w3schools tipos otro llamar funciones funcion desde anidadas javascript function

tipos - llamar funcion javascript desde otro javascript



Determine si una función de JavaScript es una función vinculada (6)

¿Hay una manera de determinar si una función de JavaScript es una función vinculada ?

Ejemplo:

var obj = { x:1 }; function printX() { document.write(this.x); } function takesACallback(cb) { // how can one determine if this is a bounded function // not just a function? if (typeof cb === ''function'') { cb(); } } takesACallback(printX.bind(obj)); // 1 takesACallback(printX); // undefined

Quizás este sea un punto importante. No estoy preguntando por qué la segunda llamada se imprime indefinida.


Basándome en respuestas anteriores, creo una función para determinar:

function isBoundFunction(func) { if(typeof func.prototype === ''object'') return false try { new func() } catch(e) { return false } return true }

Esta función determina tres tipos de funciones: 1. función original, cuyo prototipo es objeto, 2. función de flecha, que no se puede utilizar como constructor, 3. función de límite.


En entornos compatibles con ES6, puede verificar si el nombre de la función comienza con "bound " (la palabra "enlazado" seguido de un espacio).

De la especificación:

19.2.3.2 Function.prototype.bind (thisArg, ... args)

[...]

15. Ejecute SetFunctionName ( F , targetName , "bound").

Por supuesto, esto podría dar como resultado falsos positivos si el nombre de la función se cambiara manualmente.


Necesitarías escribir tu propia función de bind en el prototipo. Esa función construiría un índice de lo que se ha vinculado.

Luego podría tener otra función para realizar una búsqueda en el objeto donde se almacena ese índice.


Soy nuevo aquí y no tengo suficiente reputación para publicar comentarios, solo respuestas. Lo siento, pero esto no responde al OP, porque no tengo idea de cómo hacerlo. Desearía haber.

Sin embargo, las respuestas muy comunes basadas en una propiedad de prototype faltante no funcionarán. Los métodos de clase, las definiciones de métodos en objetos y las funciones async tampoco tienen propiedades de prototype , pero no están naturalmente vinculadas.

Además, tenga en cuenta que todavía es posible vincular manualmente una función por cierre, lo que desafiaría cualquier intento de detectar su estado enlazado:

const bind=(fn,obj)=>{ return (...args)=>{ return fn.apply(obj,args) } }


Tanto las funciones enlazadas como las funciones de flecha no tienen una propiedad de prototype :

typeof (function() {}).prototype // ''object'' as usual typeof (function() {}).bind(null).prototype // ''undefined''! typeof (() => {}).prototype // ''undefined''!

Esto no es 100% seguro ya que aún podría asignar esta propiedad manualmente (aunque sería extraño).
Como tal, una forma simple de verificar la capacidad de enlace sería la siguiente:

// ES5 function isBindable(func) { return func.hasOwnProperty(''prototype''); } // ES6 const isBindable = func => func.hasOwnProperty(''prototype'');

Uso:

isBindable(function () {}); // true isBindable(() => {}); // false isBindable( (function () {}).bind(null) ); // false

De esta manera, puede asegurarse de que la función que se ha pasado pueda tratar this dinámica.

Aquí hay un ejemplo de uso para el que falla lo anterior:

const arrowFunc = () => {}; arrowFunc.prototype = 42; isBindable(arrowFunc); // true :(

Curiosamente, si bien las funciones enlazadas no tienen una propiedad de prototype , todavía pueden usarse como constructores (con new ):

var Animal = function(name) { this.name = name; }; Animal.prototype.getName = function() { return this.name; }; var squirrel = new Animal(''squirrel''); console.log(squirrel.getName()); // prints "squirrel" var MutatedAnimal = Animal.bind({}); // Radiation :) console.log(MutatedAnimal.hasOwnProperty(''prototype'')); // prints "false" var mutatedSquirrel = new MutatedAnimal(''squirrel with two heads''); console.log(mutatedSquirrel.getName()); // prints "squirrel with two heads"

En ese caso, se utiliza en su lugar el prototype función original ( Animal ).
Ver JS Bin , código y enlace cortesía de Dmitri Pavlutin .

Por supuesto, esto no funcionará con las funciones de flecha ya que no se pueden usar como constructores.

Desafortunadamente, no sé si hay una manera de distinguir una función enlazada (que se puede usar como constructor) de una función de flecha (que no se puede usar como constructor) sin try con una new y verificar si se lanza ( new (() => {}) lanza un error "no es un constructor" ).


Uno podría anular el prototipo existente vinculando, etiquetando funciones que han sido vinculadas.

Una solución simple. Sin embargo, esto probablemente eliminará ciertas optimizaciones en V8 (y posiblemente otros tiempos de ejecución) debido a clases ocultas.

(function (bind) { Object.defineProperties(Function.prototype, { ''bind'': { value: function (context) { var newf = bind.apply(this, arguments); newf.context = context; return newf; } }, ''isBound'': { value: function () { return this.hasOwnProperty(''context''); } } }); }(Function.prototype.bind));

En movimiento:

(function (bind) { Object.defineProperties(Function.prototype, { ''bind'': { value: function (context) { var newf = bind.apply(this, arguments); newf.context = context; return newf; } }, ''isBound'': { value: function () { return this.hasOwnProperty(''context''); } } }); }(Function.prototype.bind)); var a = function () { console.log(this); }; var b = { b: true }; var c = a.bind(b); console.log(a.isBound()) console.log(c.isBound()) console.log(c.context === b); a(); c();