Erklärung über prototype.js funktionieren Bindungscode
-
30-09-2019 - |
Frage
Von: http://ejohn.org/apps/learn/#2
Function.prototype.bind = function(){
var fn = this, args = Array.prototype.slice.call(arguments), object = args.shift();
return function(){
return fn.apply(object,
args.concat(Array.prototype.slice.call(arguments)));
};
};
Kann mir jemand sagen, warum die zweite Rückkehr notwendig ist (vor fn.apply)?
Auch kann jemand erklären, warum args.concat notwendig ist? Warum sollte es nicht neu geschrieben werden als:
fn.apply(object, args)
statt
return fn.apply(object,
args.concat(Array.prototype.slice.call(arguments)));
Lösung
Die zweite Rückkehr ist notwendig, weil sonst werden wir alle Rückgabewert von der gebundenen Funktion verlieren.
Sie können bereits wissen, aber nicht zu erwähnen verletzt. Wenn wir in einer anderen Funktion nicht fn.apply
wickeln, dann sind wir direkt die Funktion fn
Aufruf, die suboptimale ist, als bind
nur den Ausführungskontext festlegen soll (was soll innerhalb der Funktion beziehen sich auf this
) und nicht invoke es .
Javascript Methoden können durch den Aufruf der call
oder apply
Methode auf sie aufgerufen werden. Hier ist ein kleines Beispiel:
function example() {
alert("useless example");
}
example.apply() // or example.call(), alerts "useless example";
Die äußere Funktion in Prototype bind () soll an die Arbeit wie eine unsichtbare Wrapper um die gebundene Funktion. Damit alle Argumente, die an den Wrapper übergeben werden sollen auch an die gebundenen Funktion übergeben werden, und es muss einen Wert zurückgeben, dass die gebundene Funktion zurückkehrt, weshalb die return-Anweisung gibt.
Der Grund dafür args.concat innen fn.apply anders ist und es ist nicht optional. bind
in Prototype können Sie Argumente an die gebundenen Funktion vorangestellt wird.
args
stellt die Argumente, die übergeben wurden, als wir bind
auf die Funktion aufgerufen. arguments
stellt die Argumente, die übergeben wurden, als wir die gebundene Funktion aufgerufen. Wir sind im Grunde verketten zwei Arrays gibt.
Aus dem obigen Beispiel:
var obj = { x: 'prop x' };
var boundExample = example.bind(obj, 12, 23); // args => 12, 23
boundExample(36, 49); // arguments => 36, 49
// arguments that our example() function receives => 12, 23, 36, 49
Andere Tipps
Alte Post, aber ein neuerer Ansatz;)
Function.prototype.bind = function(){
var fn = this,
context = arguments[0],
args = Array.prototype.slice.call(arguments, 1);
return function(){
return fn.apply(context, args.concat([].slice.call(arguments)));
}
}
obj = {'abc':'x'};
var func = function() {
console.log(arguments);
alert(this.abc);
}
var x = func.bind(obj);
console.log(x(1,2,3));
Dies ist ein sehr gutes Beispiel zu erklären. Führen Sie es und überprüfen Sie das Konsolenprotokoll. Dann ändern Sie den Code auszulassen
[].slice.call(arguments)
Sie werden sehen, dass die console.log der Ausführung von x (1,2,3) ist mehr die Argumente nicht angezeigt. Das ist, weil die Argumente Objekte ist eine lokale Variable in allen Funktionen. Das mag ein wenig verwirrend klingen, aber was es bedeutet, ist im Grunde:
var x = func.bind(obj,1,2,3);
Gibt diese Funktion intern:
function() {
return fn.apply(obj, [1,2,3].concat([].slice.call(arguments)));
}
So ist es eher eine Vorlage für die Funktion ist.
Wenn Sie laufen jetzt ist es wie:
x(4,5,6)
Dies wird RAN:
fn.apply(obj, [1,2,3].concat([].slice.call(arguments)))
mit einem speziellen Argumente Object = {0: 4,1: 5,2: 6}, die in eine Anordnung überführt werden kann unter Verwendung von [] .slice.call wo Argumente ist ein lokales Objekt, das automatisch während der Invokation der Funktion zugeordnet ist beeing.