Heim > Artikel > Web-Frontend > Ausführliche Erklärung hierzu in JavaScript
Das ist in JavaScript immer verwirrend und sollte eine der bekannten Fallstricke von js sein. Persönlich denke ich auch, dass dies in js kein gutes Design ist. Aufgrund der späten Bindungseigenschaften kann es sich um das globale Objekt, das aktuelle Objekt oder ... handeln. Einige Leute verwenden dies aufgrund der Größe sogar nicht Fallstricke.
Tatsächlich werden Sie, wenn Sie das Funktionsprinzip vollständig verstehen, natürlich nicht in diese Gruben fallen. Schauen wir uns an, worauf dies in den folgenden Situationen hinweist:
1 this in global code
1 warning(x);
// Der Wert der globalen Variablen x ist 2
Dies im globalen Bereich zeigt auf das globale Objekt, das ein Fenster im Browser ist.
2. Aufruf als einfache Funktion
function fooCoder(x) {
this.x = x;
}
fooCoder(2);
alert(x) ;
//Der Wert der globalen Variablen x ist 2
Hier zeigt dies auf das globale Objekt, also das Fenster. Im strikten Modus ist es undefiniert.
3. Rufen Sie die Methode als Objekt auf
var name = "clever coder";
var person = {
name : "foocoder",
hello : function(sth) {
console.log(this.name + " sagt " + etw);
}
}
person.hello("hello world");
Ausgabe-Foocoder sagt Hallo Welt. Dies zeigt auf das Personenobjekt, das das aktuelle Objekt ist.
4. Als Konstruktor
1 neuer FooCoder();
Dieser innerhalb der Funktion zeigt auf das neu erstellte Objekt.
5. Interne Funktion
var name = "clever coder";
var person = {
name : "foocoder",
hello : function( etw){
var sayhello = function(sth) {
console.log(this.name + " sagt " + etw);
};
sayhello(
}
person.hello("Hallo Welt");
//Clever Coder sagt Hallo Welt
In der internen Funktion ist dies nicht an die erwartete Bindung gebunden. Stattdessen , es ist an das globale Objekt gebunden. Dies wird im Allgemeinen als Entwurfsfehler in der JavaScript-Sprache angesehen, da niemand möchte, dass dies in der inneren Funktion auf das globale Objekt verweist stimmte zu, das oder ich selbst zu sein:
var name = "clever coder";
var person = {
name : "foocoder",
hello : function(sth){
var that = this;
var sayhello = function(sth) {
console.log(that.name + " said " + sth);
};
sayhello(sth);
}
}
person.hello("hello world");
//foocoder sagt hallo Welt
6. Verwenden Sie „Call“ und „Apply“, um dies festzulegen
1 person.hello.call(person, "world");
apply ähnelt call, außer dass die nachfolgenden Parameter über ein Array und nicht separat übergeben werden. Definition:
call( thisArg [, arg1, arg2, ... ] );
// Parameterliste, arg1, arg2, ...
apply(thisArg [, argArray] ) ;
// Array von Parametern, argArray
Beide werden verwendet, um eine Funktion an ein bestimmtes Objekt zu binden. Dies wird zu diesem Zeitpunkt natürlich explizit als festgelegt erster Parameter.
Eine kurze Zusammenfassung
Eine kurze Zusammenfassung der oben genannten Punkte. Wir können feststellen, dass nur der sechste Punkt verwirrend ist.
Tatsächlich kann es wie folgt zusammengefasst werden:
Wenn eine Funktion als Methode eines Objekts aufgerufen wird, zeigt dies auf das Objekt.
Wenn die Funktion als Ausblendfunktion aufgerufen wird, zeigt dies auf das globale Objekt (im strikten Modus ist es undefiniert)
Dies im Konstruktor zeigt auf das neu erstellte Objekt
Dies im verschachtelten Die Funktion erbt nicht die Funktion der oberen Ebene. Bei Bedarf kann eine Variable verwendet werden, um die Funktion der oberen Ebene zu speichern.
Um es einfach zusammenzufassen: Wenn dies in einer Funktion verwendet wird, zeigt dies nur dann auf das Objekt, wenn die Funktion direkt von einem Objekt aufgerufen wird.
obj.foocoder();
foocoder.call(obj, ...);
foocoder.apply(obj, ...);
Los weiter
Wir schreiben möglicherweise oft Code wie diesen:
1 $("#some-ele").click = obj.handler;
Wenn dies in der verwendet wird handler , wird dies an obj gebunden sein? Offensichtlich nicht. Nach der Zuweisung wird die Funktion im Callback ausgeführt und an das Element $("#some-div") gebunden. Dies erfordert ein Verständnis der Ausführungsumgebung der Funktion. In diesem Artikel wird nicht näher auf die Ausführungsumgebung der Funktion eingegangen. Weitere Informationen finden Sie in der entsprechenden Einführung zur Ausführungsumgebung und zur Bereichskette in „Javascript Advanced Programming“. Ich möchte hier darauf hinweisen, dass das Verständnis der Ausführungsumgebung von js-Funktionen Ihnen dabei helfen wird, dies besser zu verstehen.
Wie können wir also das Problem der Callback-Funktionsbindung lösen? In ES5 wurde eine neue Methode eingeführt, bind():
fun.bind(thisArg[, arg1[, arg2[, ...]]])
thisArg
Wenn die gebundene Funktion aufgerufen wird, wird dieser Parameter beim Ausführen als dieser Punkt der ursprünglichen Funktion verwendet. Wenn der neue Operator zum Aufrufen der gebundenen Funktion verwendet wird, ist dieser Parameter ungültig.
1 arg1, arg2 , ...
Wenn die gebundene Funktion aufgerufen wird, werden diese Parameter sowie die Parameter der gebundenen Funktion selbst als Parameter der ursprünglichen Funktion verwendet, wenn sie der Reihe nach ausgeführt werden.
Diese Methode erstellt eine neue Funktion, die als Bindungsfunktion bezeichnet wird, und verwendet den ersten Parameter, der beim Erstellen an die Bindungsmethode übergeben wird, und den zweiten und die folgenden Parameter, die an die Bindungsmethode übergeben werden Parameter plus die Parameter der gebundenen Funktion selbst werden beim Ausführen nacheinander als Parameter der ursprünglichen Funktion verwendet, um die ursprüngliche Funktion aufzurufen
Offensichtlich kann die Bindungsmethode das obige Problem gut lösen.
1
2 $("#some-ele").click(person.hello.bind(person));
//Wenn auf das entsprechende Element geklickt wird, sagt der Ausgabe-Foocoder „Hallo Welt“
Tatsächlich ist diese Methode auch einfach zu simulieren. Schauen wir uns den Quellcode der Bindemethode in Prototype.js an:
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.prototyp.slice.call(arguments)));
};
};