2012-05-09 7 views
16

Me estoy poniendo la cabeza envuelta en currying y otras técnicas usando Function.prototype.bind.
Parece extremadamente útil cambiar el alcance de la función (es decir, el valor this) en ciertas situaciones.¿Puedo obtener una función independiente de una función enlazada en JavaScript?

Sin embargo it looks like you can't change the scope with bind una vez que ya lo hicieron:

function f = obj.method.bind(42); 
function g = obj.method.bind('Hi'); 

function f2 = f.bind('Hi'); // “this” is still 42 

¿Es posible recuperar la función sin consolidar original a partir de una función ligada en absoluto?

+4

¿Has probado? –

+0

@Martin: estoy creando un violín en este momento. Parece una pregunta muy simple para alguien que conoce la respuesta, de ahí que haya publicado una pregunta sin investigación previa. –

+0

@Martin: Acabo de [verifiqué mis suposiciones] (http://jsfiddle.net/dXq2E/) y realmente parece que no puedo cambiar el alcance con 'bind' dos veces. Entonces, ¿es posible? ¿Hay algún tipo de 'desvinculación'? –

Respuesta

15

Lo que hace básicamente el método bind es algo similar (no exactamente, porque los argumentos son cortados para excluir el contexto):

function bind(context) { 
    var self = this; 
    return function() { 
     self.apply(context, arguments); 
    } 
} 

Así que básicamente es volver otra función que se llame a sí mismo con el contexto y argumentos dados . Si a continuación bind de nuevo, se le enlazando esta función de nueva creación, que será como si bind fue implementado como:

function bind(context) { 
    var self = this; 
    return function() { 
     self.apply(context, arguments); 
    }.bind(otherContext); 
} 

Pero debido a que la función interna devuelto por actos obligan a modo de cierre, donde el contexto original es el que está primero vinculado (self), ese será el contexto en el que su función será realmente ejecutada.

22

Pensé que sería útil ilustrar Win32's answer con una imagen.

Un contenedor generado por bind asegura su función es llamada con el contexto dado no importa lo.
Tal contenedor siempre ignorará su propio contexto.

Dada una cadena de envolturas, se pierde cualquier contexto excepto el más interno. Por lo tanto, no hay forma de cambiar el contexto una vez que se ha configurado usando bind.

Chained bind calls

+0

Buena explicación visual :) – Win32

+0

explicación genial @ Dan Abramov !! –

Cuestiones relacionadas