Javascript this
Einfacher Funktionsaufruf
Betrachten Sie die folgende Funktion:
function foo() {
console.log("bar");
console.log(this);
}
foo(); // calling the function
Beachten Sie, dass wir dies im normalen Modus ausführen, dh der strikte Modus wird nicht verwendet.
Wenn Sie in einem Browser ausgeführt werden, wird der Wert von this
als protokolliert window
. Das ist weilwindow
es sich um die globale Variable im Bereich eines Webbrowsers handelt.
Wenn Sie denselben Code in einer Umgebung wie node.js ausführen, this
auf die globale Variable in Ihrer App verwiesen.
Wenn wir dies nun im strengen Modus ausführen, indem wir die Anweisung "use strict";
am Anfang der Funktionsdeklaration hinzufügen , this
wird in keiner der Umgebungen mehr auf die globale Variable verwiesen. Dies geschieht, um Verwirrungen im strengen Modus zu vermeiden. this
würde in diesem Fall einfach protokollierenundefined
, da dies nicht definiert ist.
In den folgenden Fällen würden wir sehen, wie der Wert von manipuliert wird this
.
Aufruf einer Funktion für ein Objekt
Es gibt verschiedene Möglichkeiten, dies zu tun. Wenn Sie native Methoden in Javascript wie forEach
und aufgerufen haben slice
, sollten Sie bereits wissen, dass sich die this
Variable in diesem Fall auf die bezieht, Object
auf die Sie diese Funktion aufgerufen haben (Beachten Sie, dass in Javascript fast alles ein ist Object
, einschließlich Array
s und Function
s). Nehmen Sie zum Beispiel den folgenden Code.
var myObj = {key: "Obj"};
myObj.logThis = function () {
// I am a method
console.log(this);
}
myObj.logThis(); // myObj is logged
Wenn a Object
eine Eigenschaft enthält, die a enthält Function
, wird die Eigenschaft als Methode bezeichnet. Wenn diese Methode aufgerufen wird, wird ihre this
Variable immer auf die Variable gesetzt, der Object
sie zugeordnet ist. Dies gilt sowohl für strenge als auch für nicht strenge Modi.
Beachten Sie, dass der Verweis auf this
in der neuen Variablen nicht mehr beibehalten wird , wenn eine Methode in einer anderen Variablen gespeichert (oder vielmehr kopiert) wird. Zum Beispiel:
// continuing with the previous code snippet
var myVar = myObj.logThis;
myVar();
// logs either of window/global/undefined based on mode of operation
Betrachtet man ein allgemeineres praktisches Szenario:
var el = document.getElementById('idOfEl');
el.addEventListener('click', function() { console.log(this) });
// the function called by addEventListener contains this as the reference to the element
// so clicking on our element would log that element itself
Das new
Schlüsselwort
Betrachten Sie eine Konstruktorfunktion in Javascript:
function Person (name) {
this.name = name;
this.sayHello = function () {
console.log ("Hello", this);
}
}
var awal = new Person("Awal");
awal.sayHello();
// In `awal.sayHello`, `this` contains the reference to the variable `awal`
Wie funktioniert das? Mal sehen, was passiert, wenn wir das new
Schlüsselwort verwenden.
- Das Aufrufen der Funktion mit dem
new
Schlüsselwort würde sofort einen Object
Typ initialisieren Person
.
- Für den Konstruktor
Object
ist der Konstruktor festgelegt Person
. Beachten Sie auch, dass typeof awal
zurückkehren würde Object
nur.
- Diesem neuen
Object
würde der Prototyp von zugewiesen Person.prototype
. Dies bedeutet, dass jede Methode oder Eigenschaft im Person
Prototyp für alle Instanzen von verfügbar ist Person
, einschließlich awal
.
- Die Funktion
Person
selbst wird jetzt aufgerufen. this
eine Referenz auf das neu konstruierte Objekt sein awal
.
Ziemlich einfach, oder?
Beachten Sie, dass die offizielle ECMAScript-Spezifikation nirgends besagt, dass solche Arten von Funktionen tatsächliche constructor
Funktionen sind. Sie sind nur normale Funktionen und new
können für jede Funktion verwendet werden. Es ist nur so, dass wir sie als solche verwenden und sie daher nur als solche bezeichnen.
Funktionen für Funktionen aufrufen: call
undapply
Also ja, da function
sind es auchObjects
(und tatsächlich erstklassige Variablen in Javascript) sind, haben sogar Funktionen Methoden, die ... nun, Funktionen selbst sind.
Alle Funktionen erben vom Globalen Function
, und zwei seiner vielen Methoden sind call
und apply
, und beide können verwendet werden, um den Wert von this
in der Funktion zu manipulieren, für die sie aufgerufen werden.
function foo () { console.log (this, arguments); }
var thisArg = {myObj: "is cool"};
foo.call(thisArg, 1, 2, 3);
Dies ist ein typisches Beispiel für die Verwendung call
. Es nimmt grundsätzlich den ersten Parameter und setzt this
in der Funktion foo
als Referenz auf thisArg
. Alle anderen übergebenen Parameter call
werden foo
als Argumente an die Funktion übergeben .
Der obige Code meldet sich also {myObj: "is cool"}, [1, 2, 3]
in der Konsole an. Ziemlich schöne Möglichkeit, den Wert von zu ändernthis
einer Funktion .
apply
ist fast dasselbe wie zu call
akzeptieren, dass nur zwei Parameter benötigt werden: thisArg
und ein Array, das die Argumente enthält, die an die Funktion übergeben werden sollen. Der obige call
Aufruf kann also folgendermaßen übersetzt werden apply
:
foo.apply(thisArg, [1,2,3])
Beachten Sie, dass call
und apply
den Wert von überschreiben kannthis
Aufrufs der durch die Punktmethode festgelegten Menge wir im zweiten Aufzählungszeichen erörtert haben. Einfach genug :)
Präsentieren .... bind
!
bind
ist ein Bruder von call
und apply
. Es ist auch eine Methode, die von allen Funktionen des globalen Function
Konstruktors in Javascript geerbt wird . Der Unterschied zwischen bind
und call
/ apply
besteht darin, dass beide call
und apply
die Funktion tatsächlich aufrufen. bind
Gibt andererseits eine neue Funktion mit der Voreinstellung thisArg
und zurück arguments
. Nehmen wir ein Beispiel, um dies besser zu verstehen:
function foo (a, b) {
console.log (this, arguments);
}
var thisArg = {myObj: "even more cool now"};
var bound = foo.bind(thisArg, 1, 2);
console.log (typeof bound); // logs `function`
console.log (bound);
/* logs `function () { native code }` */
bound(); // calling the function returned by `.bind`
// logs `{myObj: "even more cool now"}, [1, 2]`
Sehen Sie den Unterschied zwischen den drei? Es ist subtil, aber sie werden unterschiedlich verwendet. Wie call
und apply
, bind
auch over-ride den Wertthis
Satz von Punkt-Methodenaufruf.
Beachten Sie auch, dass keine dieser drei Funktionen Änderungen an der ursprünglichen Funktion vornimmt. call
und apply
würde den Wert von frisch konstruierten Funktionen während zurückgebenbind
die frisch konstruierte Funktion selbst zurückgegeben wird, die zum Aufrufen bereit ist.
Zusätzliches Zeug, kopiere das
Manchmal gefällt Ihnen die Tatsache nicht, dass sich this
Änderungen mit dem Bereich ändern, insbesondere der verschachtelte Bereich. Schauen Sie sich das folgende Beispiel an.
var myObj = {
hello: function () {
return "world"
},
myMethod: function () {
// copy this, variable names are case-sensitive
var that = this;
// callbacks ftw \o/
foo.bar("args", function () {
// I want to call `hello` here
this.hello(); // error
// but `this` references to `foo` damn!
// oh wait we have a backup \o/
that.hello(); // "world"
});
}
};
Im obigen Code sehen wir, dass sich der Wert von this
mit dem verschachtelten Bereich geändert hat, aber wir wollten den Wert von this
vom ursprünglichen Bereich. Also wir ‚kopiert‘ this
auf that
und verwendet kopieren die statt this
. Clever, was?
Index:
- Was ist
this
standardmäßig enthalten?
- Was ist, wenn wir die Funktion als Methode mit Objekt-Punkt-Notation aufrufen?
- Was ist, wenn wir die verwenden
new
Schlüsselwort verwenden?
- Wie manipulieren wir
this
mit call
und apply
?
- Verwenden von
bind
.
- Kopieren,
this
um Probleme mit verschachtelten Bereichen zu lösen.