w3schools metodo event javascript functional-programming promise partial-application

metodo - prototype javascript



¿Usar Function.prototype.bind con una matriz de argumentos? (10)

¿Por qué no simplemente enlazar a la matriz de argumentos según su ejemplo y hacer que la función bound() trate así como una matriz ?

Según el aspecto de su uso, está pasando una función como argumento final a bound() , lo que significa que al pasar la matriz de argumentos real, evita tener que separar los argumentos de las devoluciones dentro de bound() , lo que hace que sea más fácil jugar con.

¿Cómo puedo llamar a Function.prototype.bind con una matriz de argumentos, a diferencia de los argumentos codificados? (No usa ECMA6, por lo que no hay operador de propagación).

Estoy tratando de poner un envoltorio de promesas alrededor de un módulo que usa devoluciones de llamada y quiero vincular todos los argumentos pasados ​​a mi método de envoltura y vincularlos. Luego deseo llamar a la función enlazada parcialmente aplicada con mi propia devolución de llamada, que resolverá o rechazará una promesa.

var find = function() { var deferred, bound; deferred = Q.defer(); bound = db.find.bind(null, arguments); bound(function(err, docs) { if(err) { deferred.fail(err); } else { deferred.resolve(docs); } }); return deferred.promise; }

Pero, obviamente, esto no funciona porque bind espera argumentos en lugar de una matriz de argumentos. Sé que podría hacer esto insertando mi devolución de llamada al final de la matriz de argumentos y usando apply:

arguments[arguments.length] = function(err, docs) { ... } db.find.apply(null, arguments);

O al iterar sobre la matriz de argumentos y volver a vincular la función para cada argumento:

var bound, context; for(var i = 0; i < arguments.length; i++) { context = bound ? bound : db.find; bound = context.bind(null, arguments[i]); } bound(function(err, docs) { ... })

Pero ambos métodos se sienten sucios. ¿Algunas ideas?


Acabo de tener una idea alternativa, aplicar parcialmente el valor null para el contexto y luego usar apply para llamar a la función parcialmente aplicada.

bound = db.find.bind.bind(null).apply(null, arguments);

Esto elimina la necesidad del aspecto ligeramente [null].concat() en la respuesta de [null].concat() .


El siguiente es un fragmento común de código que uso en todos mis proyectos:

var bind = Function.bind; var call = Function.call; var bindable = bind.bind(bind); var callable = bindable(call);

La función bindable ahora se puede usar para pasar una matriz para bind siguiente manera:

var bound = bindable(db.find, db).apply(null, arguments);

De hecho, puede almacenar en caché bindable(db.find, db) para acelerar el enlace de la siguiente manera:

var findable = bindable(db.find, db); var bound = findable.apply(null, arguments);

Puede usar la función que se puede findable con o sin una matriz de argumentos:

var bound = findable(1, 2, 3);

Espero que esto ayude.


Genéricamente, este esquema es suficiente:

//obj = db //fnName = ''find'' var args = [this||null].concat(Array.prototype.slice.apply(arguments); obj[fnName].bind.apply(obj[fnName], args);


La respuesta de Felix no funcionó para mí porque el objeto arguments no es realmente una matriz (como señaló Otts). La solución para mí era simplemente cambiar bind y apply :

bound = db.find.apply.bind(db.find, null, arguments);


Me parece siguiente más limpio que las respuestas aceptadas

Function.bind.apply(db.find, [null].concat(arguments));


Para aquellos que usan ES6, Babel compila:

db.find.bind(this, ...arguments)

a:

db.find.bind.apply(db.find, [this].concat(Array.prototype.slice.call(arguments)));

Creo que es justo decir que Babel es bastante definitivo. Sin embargo, crédito a @ lorenz-lo-sauer, es casi idéntico.


Si alguien está buscando una muestra abstracta:

var binded = hello.apply.bind(hello,null,[''hello'',''world'']); binded(); function hello(a,b){ console.log(this); //null console.log(a); //hello console.log(b); //world }


Una respuesta definitiva y simple podría ser

Function.apply.bind(this.method, this, arguments);

Un poco "difícil" de entender, pero ordenado.


.bind es una función normal, por lo que puede invocar .apply .
Todo lo que tiene que hacer es pasar la función original como primer param y la deseada THIS variable como primer elemento de la matriz de argumentos:

bound = db.find.bind.apply(db.find, [null].concat(arguments)); // ^-----^ ^-----^ THIS

Si eso se puede considerar más limpio o no se deja al lector.