In JavaScript ist dies nicht unbedingt nur im Kontext von Objektmethoden zu finden. Es gibt diesen Verweis auch in globalen Funktionsaufrufen und mehreren anderen unterschiedlichen Kontexten.
Es kann das globale Objekt, das aktuelle Objekt oder ein beliebiges Objekt sein, es hängt alles davon ab, wie die Funktion aufgerufen wird. Es gibt mehrere Möglichkeiten, Funktionen in JavaScript aufzurufen: als Objektmethode, als Funktion, als Konstruktor und mit apply oder call.
1. Aufruf als Objektmethode
In JavaScript sind Funktionen auch Objekte, daher können Funktionen als Attribute eines Objekts verwendet werden. Zu diesem Zeitpunkt wird die Funktion als Methode des Objekts bezeichnet. Bei Verwendung dieser aufrufenden Methode ist diese natürlich an das Objekt gebunden.
var point = {
x : 0,
y: 0,
moveTo : function(x, y) {
This.x = this.x x;
This.y = this.y y;
}
};
point.moveTo(1, 1)//dies ist an das aktuelle Objekt gebunden, d. h. Punktobjekt
2. Aufruf als Funktion
Die Funktion kann auch direkt aufgerufen werden, dann ist diese an das globale Objekt gebunden. Im Browser ist window das globale Objekt. Zum Beispiel im folgenden Beispiel: Wenn die Funktion aufgerufen wird, wird diese an das globale Objekt gebunden und dann die Zuweisungsanweisung ausgeführt. Dies entspricht der impliziten Deklaration einer globalen Variablen, was offensichtlich nicht das ist, was der Aufrufer möchte.
Funktion makeNoSense(x) {
this.x = x;
}
makeNoSense(5);
x;// x ist zu einer globalen Variablen mit dem Wert 5
geworden
Bei internen Funktionen, also Funktionen, die in einem anderen Funktionskörper deklariert sind, führt diese Methode der Bindung an das globale Objekt zu einem weiteren Problem. Wir nehmen immer noch das zuvor erwähnte Punktobjekt als Beispiel. Dieses Mal hoffen wir, zwei Funktionen in der moveTo-Methode zu definieren, um die x- bzw. y-Koordinaten zu übersetzen. Das Ergebnis kann unerwartet sein. Nicht nur bewegt sich das Punktobjekt nicht, es gibt auch zwei weitere globale Variablen x und y.
var point = {
x : 0,
y: 0,
moveTo : function(x, y) {
// Interne Funktion
var moveX = function(x) {
This.x = x;//Wohin ist das gebunden?
};
// Interne Funktion
var moveY = function(y) {
This.y = y;//Wohin ist das gebunden?
};
moveX(x);
moveY(y);
}
};
point.moveTo(1, 1);
point.x; //==>0
point.y; //==>0
x; //==>1
y; //==>1
Dies ist ein Designfehler in JavaScript. Die richtige Designmethode besteht darin, dass diese der internen Funktion an das Objekt gebunden werden sollte, das ihrer äußeren Funktion entspricht. Um diesen Designfehler zu vermeiden, haben intelligente JavaScript-Programmierer eine Variablensubstitution entwickelt . Methode, laut Konvention wird die Variable im Allgemeinen so benannt.
var point = {
x : 0,
y: 0,
moveTo : function(x, y) {
var that = this;
// Interne Funktion
var moveX = function(x) {
That.x = x;
};
// Interne Funktion
var moveY = function(y) {
That.y = y;
}
MoveX(x);
MoveY(y);
}
};
point.moveTo(1, 1);
point.x; //==>1
point.y; //==>1
Aufruf als Konstruktor
JavaScript unterstützt objektorientierte Programmierung. Im Gegensatz zu gängigen objektorientierten Programmiersprachen verfügt JavaScript nicht über das Konzept von Klassen, sondern verwendet eine Vererbung basierend auf Prototypen. Dementsprechend ist auch der Konstruktor in JavaScript etwas ganz Besonderes. Wenn er nicht mit new aufgerufen wird, ist er dasselbe wie eine gewöhnliche Funktion. Als weitere Konvention beginnen Konstrukteure mit einem Großbuchstaben, um Aufrufer daran zu erinnern, sie auf die richtige Weise aufzurufen. Bei korrektem Aufruf wird dieser an das neu erstellte Objekt gebunden.
Funktion Point(x, y){
This.x = x;
This.y = y;
}
Verwenden Sie Apply oder Call-to-Call
Lassen Sie uns noch einmal betonen, dass Funktionen in JavaScript auch Objekte sind und die Methoden „Apply“ und „Call“ von Objekten Methoden von Funktionsobjekten sind. Diese beiden Methoden sind äußerst leistungsfähig. Sie ermöglichen das Wechseln des Kontexts, in dem die Funktion ausgeführt wird, also des Objekts, an das sie gebunden ist. Viele Techniken und Bibliotheken in JavaScript nutzen diese Methode. Schauen wir uns ein konkretes Beispiel an:
Funktion Point(x, y){
This.x = x;
This.y = y;
This.moveTo = function(x, y){
This.x = x;
This.y = y;
}
}
var p1 = neuer Punkt(0, 0);
var p2 = {x: 0, y: 0};
p1.moveTo(1, 1);
p1.moveTo.apply(p2, [10, 10]);
Im obigen Beispiel verwenden wir den Konstruktor, um ein Objekt p1 zu generieren, das auch über eine moveTo-Methode verfügt. Wir verwenden Objektliterale, um ein weiteres Objekt p2 zu erstellen, und wir sehen, dass mit apply die Methode von p1 auf p2 angewendet werden kann , dieses Mal ist dies auch an Objekt p2 gebunden. Ein weiterer Methodenaufruf hat ebenfalls die gleiche Funktion, der Unterschied besteht jedoch darin, dass der letzte Parameter nicht einheitlich als Array, sondern separat übergeben wird.
Funktion Foo(){
//1.Der Konstruktor, auf den hiermit verwiesen wird, ist das Objekt, auf das argument.callee
verweist
//Die Beschreibung ist der Konstruktor, der durch den neuen Operator ausgeführt wird
if(this.constructor==arguments.callee){
Alert('Objekt erstellt');
}
//2.Dies ist ein Fenster, dann ist es ein globaler Aufruf
if(this==window){
alarm('normaler Anruf');
}
else{//3. Andernfalls wird es als Methode anderer Objekte aufgerufen
alarm('called by ' this.constructor);
}
}
Foo();//Globaler Funktionsaufruf
Foo.call(new Object());//Aufruf als Mitgliedsmethode eines Objektobjekts
new Foo();//Wird vom neuen Operator aufgerufen, um die Objektkonstruktion durchzuführen