2012-05-09 6 views
16

Ich bekomme meinen Kopf über Curry und andere Techniken mit Function.prototype.bind gewickelt.
Es scheint äußerst nützlich, Funktionsumfang (d. H. this Wert) in bestimmten Situationen zu ändern.Kann ich eine ungebundene Funktion von einer gebundenen Funktion in JavaScript erhalten?

jedoch it looks like you can't change the scope with bind, wenn Sie bereits tat so:

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

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

Ist es möglich, auf alle ursprünglichen ungebundene Funktion aus einer gebundenen Funktion abzurufen?

+4

haben Sie versucht? –

+0

@Martin: Ich kreiere gerade eine Geige. Für jemanden, der die Antwort kennt, scheint es eine sehr einfache Frage zu sein, weshalb ich eine Frage ohne vorherige Recherche gestellt habe. –

+0

@Martin: Ich habe nur [meine Annahmen überprüft] (http://jsfiddle.net/dXq2E/) und es sieht wirklich so aus, als ob ich den Umfang nicht zweimal mit 'bind' ändern kann. Also, ist es überhaupt möglich? Gibt es eine Art "Entbinden"? –

Antwort

15

Was die bind Methode im Grunde tut, ist so etwas wie (nicht genau, weil Argumente in Scheiben geschnitten werden, um den Kontext auszuschließen):

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

Also im Grunde ist es eine andere Funktion zurückkehrt, die sich mit dem gegebenen Kontext nennen und Argumente . Wenn Sie dann wieder bind es, werden Sie diese neu geschaffene Funktion verbindlich, die als ob bind implementiert werden wie:

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

Aber weil die innere Funktion durch bind wirkt als Verschluss, wo die ursprünglichen Kontext zurück ist das erste binded (self), das wird der Kontext sein, mit dem Ihre Funktion wirklich ausgeführt wird.

22

Ich dachte, es wäre nützlich, Win32's answer mit einem Bild zu veranschaulichen.

Ein Wrapper generiert von bind stellt sicher, dass Ihre Funktion mit gegebenem Kontext aufgerufen wird egal was.
Ein solcher Wrapper wird immer seinen eigenen Kontext ignorieren.

Angesichts einer Kette von Wrappern ist jeder Kontext außer dem innersten verloren.
Daher gibt es keine Möglichkeit, den Kontext zu ändern, sobald er mit bind festgelegt wurde.

Chained bind calls

+0

Schöne visuelle Erklärung :) – Win32

+0

cool Erklärung @Dan Abramov !! –