En Javascript, ¿cómo puedo vincular argumentos a una función sin vincular el this
parámetro?
Por ejemplo:
//Example function.
var c = function(a, b, c, callback) {};
//Bind values 1, 2, and 3 to a, b, and c, leave callback unbound.
var b = c.bind(null, 1, 2, 3); //How can I do this without binding scope?
¿Cómo puedo evitar el efecto secundario de tener que vincular también el alcance de la función (por ejemplo, configuración this
= nulo)?
Editar:
Perdón por la confusion. Quiero vincular argumentos, luego poder llamar a la función vinculada más tarde y hacer que se comporte exactamente como si llamara a la función original y le pasara los argumentos vinculados:
var x = 'outside object';
var obj = {
x: 'inside object',
c: function(a, b, c, callback) {
console.log(this.x);
}
};
var b = obj.c.bind(null, 1, 2, 3);
//These should both have exact same output.
obj.c(1, 2, 3, function(){});
b(function(){});
//The following works, but I was hoping there was a better way:
var b = obj.c.bind(obj, 1, 2, 3); //Anyway to make it work without typing obj twice?
Todavía soy nuevo en esto, lo siento por la confusión.
¡Gracias!
javascript
Imbuir
fuente
fuente
this
?var b = c.bind(this, 1,2,3);
bind()
sernull
? Parece funcionar bien en FF.this
completamente desatado en JavaScript. Siempre significa algo . Por lo tanto, la vinculaciónthis
althis
de la función adjunta tiene mucho sentido.Respuestas:
Puede hacer esto, pero es mejor evitar pensar en ello como "vinculante", ya que ese es el término utilizado para establecer el valor "this". ¿Quizás pensar en ello como "envolver" los argumentos en una función?
Lo que debe hacer es crear una función que tenga los argumentos deseados integrados a través de cierres:
Espero tener la sintaxis ahí. Lo que hace es crear una función llamada withWrappedArguments () (para ser pedante, es una función anónima asignada a la variable) que puede llamar en cualquier momento y en cualquier lugar y siempre actuará con actualArg1Value y actualArg2Value, y cualquier otra cosa que desee poner ahí. También puede hacer que acepte más argumentos en el momento de la llamada si lo desea. El secreto son los paréntesis después de la llave de cierre final. Estos hacen que la función externa se ejecute inmediatamente, con los valores pasados, y genere la función interna que se puede llamar más tarde. Los valores pasados se congelan en el momento en que se genera la función.
Esto es efectivamente lo que hace bind, pero de esta manera es explícito que los argumentos envueltos son simplemente cierres en variables locales, y no hay necesidad de cambiar el comportamiento de esto.
fuente
f(x,y)
que queremosf(x)(y)
og=f(x); g(y)
. Así que cambiaríamosf=(x,y)=>x+y
af=(x)=>(y)=>x+y
".En ES6, esto se hace fácilmente usando parámetros de descanso junto con el operador de propagación .
Entonces podemos definir una función
bindArgs
que funcione comobind
, excepto que solo los argumentos están vinculados, pero no el contexto (this
).Luego, para una función
foo
y un objeto especificadosobj
, la declaraciónes equivalente a
donde solo están vinculados el primer y segundo argumento
bar
, mientras queobj
se usa el contexto especificado en la invocación y se añaden argumentos adicionales después de los argumentos vinculados. El valor de retorno simplemente se reenvía.fuente
let
yconst
aún no estaban disponibles cuando publiqué esto por primera vez. Está actualizado ahora.En el
bind
método nativo ,this
se pierde el valor de la función de resultado. Sin embargo, puede recodificar fácilmente la corrección común para no usar un argumento para el contexto:fuente
Function
pero me ahorró mucho tiempo y algunas soluciones desagradables. Graciasbind
. Puede transformarlo fácilmente en unfunction bindArgs(fn){ …, args = slice.call(arguments, 1); …}
this
serloa
. Puede usarbind
en su lugar, por supuesto. Sin embargo, al OP no le importa explícitamente elthis
valor y quería una función parcial no vinculada.this
es que la función se usathis
, pero no querían vincularla en ese momento. Además, la parte en la pregunta del OP//These should both have exact same output.
es contradictoria con otras partes.bind
no funciona en absoluto con constructores, las funciones enlazadas no tienen.prototype
. No,Function.prototype !== mymethod.prototype
Una pequeña implementación más solo por diversión:
Cómo utilizar:
fuente
fuente
const curry = (fn, ...curryArgs) => (...args) => fn(...curryArgs, args)
Es un poco difícil decir exactamente lo que quiere hacer en última instancia porque el ejemplo es un poco arbitrario, pero es posible que desee buscar en parciales (o currying): http://jsbin.com/ifoqoj/1/edit
Enlace al artículo de John Resig: http://ejohn.org/blog/partial-functions-in-javascript/
fuente
partial
necesita ser llamado conundefined
argumentos para que funcione, no lo que uno esperaría, y dividido en funciones que toman un número arbitrario de parámetros.this
objeto aún se estropea. Eche un vistazo a: jsbin.com/ifoqoj/4/editPuede que desee vincular la referencia de esto en último lugar, pero su código: -
Ya se aplicó el enlace, por ejemplo, este y más tarde no se puede cambiar. Lo que sugeriré es que use la referencia también como un parámetro como este: -
fuente
Utilice un
protagonist
!Básicamente, la función a la que desea pasar parámetros se convierte en un proxy al que puede llamar para pasar una variable y devuelve la función que realmente desea hacer.
¡Espero que esto ayude!
fuente
Un usuario anónimo publicó esta información adicional:
fuente
Bueno, para el ejemplo que diste, esto servirá
Si desea garantizar el cierre de los parámetros:
Pero si es así, debes ceñirte a tu solución:
Es la mejor forma.
fuente
¿Tan simple como eso?
Solución más general:
fuente
Usando LoDash puedes usar la
_.partial
función.fuente
¿Por qué no utilizar una envoltura alrededor de la función para guardar esto como mitos?
fuente
jQuery 1.9 trajo exactamente esa característica con la función de proxy.
Ejemplo:
fuente
Caso de uso de Jquery:
en lugar:
utilizar este:
fuente