Wie funktioniert das Schlüsselwort "this"?
Ich habe festgestellt, dass es anscheinend keine klare Erklärung dafür gibt, was das this
Schlüsselwort ist und wie es in JavaScript auf der Stack Overflow-Site korrekt (und falsch) verwendet wird.
Ich habe ein sehr seltsames Verhalten damit gesehen und nicht verstanden, warum es aufgetreten ist.
Wie funktioniert this
und wann sollte es verwendet werden?
Antworten
Ich empfehle , zuerst den Artikel Scope von Mike West in JavaScript ( Spiegel ) zu lesen . Es ist eine hervorragende, freundliche Einführung in die Konzepte this
und Umfangsketten von JavaScript.
Sobald Sie sich daran gewöhnt haben, this
sind die Regeln eigentlich ziemlich einfach. Der ECMAScript 5.1 Standard definiert this
:
§11.1.1 Das
this
SchlüsselwortDas
this
Schlüsselwort ergibt den Wert von ThisBinding des aktuellen Ausführungskontexts
Diese Bindung wird vom JavaScript-Interpreter beibehalten, wenn er JavaScript-Code auswertet, wie z. B. ein spezielles CPU-Register, das einen Verweis auf ein Objekt enthält. Der Interpreter aktualisiert ThisBinding immer dann, wenn in einem von nur drei verschiedenen Fällen ein Ausführungskontext eingerichtet wird:
1. Anfänglicher globaler Ausführungskontext
Dies ist der Fall bei JavaScript-Code, der auf oberster Ebene ausgewertet wird, z. B. direkt in einem <script>
:
<script>
alert("I'm evaluated in the initial global execution context!");
setTimeout(function () {
alert("I'm NOT evaluated in the initial global execution context.");
}, 1);
</script>
Bei der Auswertung von Code im anfänglichen globalen Ausführungskontext wird ThisBinding auf das globale Objekt festgelegt window
( §10.4.1.1 ).
2. Eval-Code eingeben
…
eval()
Wird durch einen direkten Aufruf von ThisBinding unverändert gelassen; Es ist der gleiche Wert wie ThisBinding des aufrufenden Ausführungskontexts ( §10.4.2 (2) (a)).… Wenn nicht durch einen direkten Aufruf von
eval()
ThisBinding, wird das globale Objekt so eingestellt, als würde es im anfänglichen globalen Ausführungskontext ausgeführt ( §10.4.2 (1)).
§15.1.2.1.1 definiert, was ein direkter Anruf eval()
ist. Grundsätzlich eval(...)
handelt es sich um einen direkten Anruf, während so etwas wie (0, eval)(...)
oder var indirectEval = eval; indirectEval(...);
ein indirekter Anruf ist eval()
. Siehe Chuckjs Antwort auf (1, eval) ('this') vs eval ('this') in JavaScript? und Dmitry Soshnikovs ECMA-262-5 im Detail. Kapitel 2. Strenger Modus. für den Fall, dass Sie einen indirekten eval()
Anruf verwenden könnten .
3. Funktionscode eingeben
Dies tritt beim Aufrufen einer Funktion auf. Wenn eine Funktion für ein Objekt aufgerufen wird, z. B. in obj.myMethod()
oder ein gleichwertiges Objekt, wird obj["myMethod"]()
ThisBinding auf das Objekt festgelegt ( obj
im Beispiel; §13.2.1 ). In den meisten anderen Fällen wird ThisBinding auf das globale Objekt festgelegt ( §10.4.3 ).
Der Grund für das Schreiben "in den meisten anderen Fällen" liegt darin, dass acht integrierte ECMAScript 5-Funktionen vorhanden sind, mit denen ThisBinding in der Argumentliste angegeben werden kann. Diese Sonderfunktionen haben eine sogenannte Funktion, thisArg
die beim Aufruf der Funktion zur ThisBinding wird ( §10.4.3 ).
Diese speziellen integrierten Funktionen sind:
Function.prototype.apply( thisArg, argArray )
Function.prototype.call( thisArg [ , arg1 [ , arg2, ... ] ] )
Function.prototype.bind( thisArg [ , arg1 [ , arg2, ... ] ] )
Array.prototype.every( callbackfn [ , thisArg ] )
Array.prototype.some( callbackfn [ , thisArg ] )
Array.prototype.forEach( callbackfn [ , thisArg ] )
Array.prototype.map( callbackfn [ , thisArg ] )
Array.prototype.filter( callbackfn [ , thisArg ] )
Bei den Function.prototype
Funktionen werden sie für ein Funktionsobjekt aufgerufen, aber anstatt ThisBinding auf das Funktionsobjekt zu setzen, wird ThisBinding auf das gesetzt thisArg
.
Bei den Array.prototype
Funktionen wird das callbackfn
Angegebene in einem Ausführungskontext aufgerufen, in dem ThisBinding auf gesetzt ist, thisArg
falls angegeben. Andernfalls zum globalen Objekt.
Dies sind die Regeln für einfaches JavaScript. Wenn Sie anfangen, JavaScript-Bibliotheken (z. B. jQuery) zu verwenden, stellen Sie möglicherweise fest, dass bestimmte Bibliotheksfunktionen den Wert von manipulieren this
. Die Entwickler dieser JavaScript-Bibliotheken tun dies, weil sie in der Regel die häufigsten Anwendungsfälle unterstützen und Benutzer der Bibliothek dieses Verhalten normalerweise als bequemer empfinden. Wenn Sie Rückruffunktionen übergeben, die this
auf Bibliotheksfunktionen verweisen, sollten Sie in der Dokumentation nach Garantien suchen, welchen Wert der Wert this
beim Aufruf der Funktion hat.
Wenn Sie sich fragen, wie eine JavaScript-Bibliothek den Wert von manipuliert this
, verwendet die Bibliothek einfach eine der integrierten JavaScript-Funktionen, die a akzeptieren thisArg
. Sie können auch Ihre eigene Funktion schreiben, indem Sie eine Rückruffunktion verwenden und thisArg
:
function doWork(callbackfn, thisArg) {
//...
if (callbackfn != null) callbackfn.call(thisArg);
}
Es gibt einen Sonderfall, den ich noch nicht erwähnt habe. Beim Erstellen eines neuen Objekts über den new
Operator erstellt der JavaScript-Interpreter ein neues, leeres Objekt, legt einige interne Eigenschaften fest und ruft dann die Konstruktorfunktion für das neue Objekt auf. Wenn also eine Funktion in einem Konstruktorkontext aufgerufen wird, ist der Wert von this
das neue Objekt, das der Interpreter erstellt hat:
function MyType() {
this.someData = "a string";
}
var instance = new MyType();
// Kind of like the following, but there are more steps involved:
// var instance = {};
// MyType.call(instance);
Pfeilfunktionen
Pfeil Funktionen (eingeführt in ECMA6) verändern den Umfang this
. Siehe die vorhandene kanonische Frage, Pfeilfunktion vs. Funktionsdeklaration / Ausdrücke: Sind sie äquivalent / austauschbar? für mehr Informationen. Aber kurz gesagt:
Pfeilfunktionen haben keine eigene
this
.... Bindung. Stattdessen werden diese Bezeichner wie jede andere Variable im lexikalischen Bereich aufgelöst. Das bedeutet, dass sich innerhalb einer Pfeilfunktionthis
... auf die Wertethis
in der Umgebung beziehen, in der die Pfeilfunktion definiert ist.
Testen Sie Ihr Verständnis nur zum Spaß anhand einiger Beispiele
Um die Antworten anzuzeigen, fahren Sie mit der Maus über die hellgrauen Kästchen.
- Was ist der Wert
this
an der markierten Linie? Warum?
window
- Die markierte Zeile wird im anfänglichen globalen Ausführungskontext ausgewertet.
if (true) {
// What is `this` here?
}
- Was ist der Wert
this
in der markierten Zeile, wennobj.staticFunction()
ausgeführt wird? Warum?
obj
- Beim Aufrufen einer Funktion für ein Objekt wird ThisBinding auf das Objekt gesetzt.
var obj = {
someData: "a string"
};
function myFun() {
return this // What is `this` here?
}
obj.staticFunction = myFun;
console.log("this is window:", obj.staticFunction() == window);
console.log("this is obj:", obj.staticFunction() == obj);
- Was ist der Wert
this
an der markierten Linie? Warum?
window
In diesem Beispiel gibt der JavaScript-Interpreter Funktionscode ein. Da
myFun
/obj.myMethod
jedoch für ein Objekt nicht aufgerufen wird, wird ThisBinding auf gesetztwindow
.Dies unterscheidet sich von Python, bei dem beim Zugriff auf eine Methode (
obj.myMethod
) ein gebundenes Methodenobjekt erstellt wird .
var obj = {
myMethod: function () {
return this; // What is `this` here?
}
};
var myFun = obj.myMethod;
console.log("this is window:", myFun() == window);
console.log("this is obj:", myFun() == obj);
- Was ist der Wert
this
an der markierten Linie? Warum?
window
Dieser war schwierig. Bei der Auswertung des Eval-Codes
this
istobj
. Im Eval-Code wirdmyFun
jedoch kein Objekt aufgerufen, sodass ThisBindingwindow
für den Aufruf festgelegt ist.
<!-- no snippet because, seemingly, eval doesn’t work in snippets -->
function myFun() {
return this; // What is `this` here?
}
var obj = {
myMethod: function () {
eval("myFun()");
}
};
- Was ist der Wert
this
an der markierten Linie? Warum?
obj
Die Zeile
myFun.call(obj);
ruft die spezielle integrierte Funktion aufFunction.prototype.call()
, diethisArg
als erstes Argument akzeptiert wird .
function myFun() {
return this; // What is `this` here?
}
var obj = {
someData: "a string"
};
console.log("this is window:", myFun.call(obj) == window);
console.log("this is obj:", myFun.call(obj) == obj);
Das this
Schlüsselwort verhält sich in JavaScript anders als in anderen Sprachen. In objektorientierten Sprachen this
bezieht sich das Schlüsselwort auf die aktuelle Instanz der Klasse. In JavaScript wird der Wert von this
durch den Aufrufkontext von function ( context.function()
) bestimmt und wo er aufgerufen wird.
1. Bei Verwendung im globalen Kontext
Wenn Sie this
im globalen Kontext verwenden, ist es an ein globales Objekt gebunden ( window
im Browser).
document.write(this); //[object Window]
Wenn Sie this
innerhalb einer im globalen Kontext definierten Funktion verwenden, this
ist diese weiterhin an ein globales Objekt gebunden, da die Funktion tatsächlich zu einer Methode des globalen Kontexts gemacht wird.
function f1()
{
return this;
}
document.write(f1()); //[object Window]
Oben f1
ist eine Methode des globalen Objekts gemacht. Daher können wir es auf window
Objekt auch wie folgt aufrufen :
function f()
{
return this;
}
document.write(window.f()); //[object Window]
2. Bei Verwendung innerhalb der Objektmethode
Wenn Sie ein this
Schlüsselwort in einer Objektmethode verwenden, this
wird es an das "unmittelbare" umschließende Objekt gebunden.
var obj = {
name: "obj",
f: function () {
return this + ":" + this.name;
}
};
document.write(obj.f()); //[object Object]:obj
Oben habe ich das Wort sofort in doppelte Anführungszeichen gesetzt. Es ist darauf hinzuweisen, dass, wenn Sie das Objekt in einem anderen Objekt verschachteln, this
es an das unmittelbare übergeordnete Objekt gebunden ist.
var obj = {
name: "obj1",
nestedobj: {
name:"nestedobj",
f: function () {
return this + ":" + this.name;
}
}
}
document.write(obj.nestedobj.f()); //[object Object]:nestedobj
Selbst wenn Sie dem Objekt eine Funktion explizit als Methode hinzufügen, folgt sie den obigen Regeln, this
dh sie verweist immer noch auf das unmittelbare übergeordnete Objekt.
var obj1 = {
name: "obj1",
}
function returnName() {
return this + ":" + this.name;
}
obj1.f = returnName; //add method to object
document.write(obj1.f()); //[object Object]:obj1
3. Beim Aufrufen der kontextlosen Funktion
Wenn Sie eine this
Inside-Funktion verwenden, die ohne Kontext aufgerufen wird (dh nicht für ein Objekt), ist sie an das globale Objekt ( window
im Browser) gebunden (auch wenn die Funktion innerhalb des Objekts definiert ist).
var context = "global";
var obj = {
context: "object",
method: function () {
function f() {
var context = "function";
return this + ":" +this.context;
};
return f(); //invoked without context
}
};
document.write(obj.method()); //[object Window]:global
Ich versuche alles mit Funktionen
Wir können die obigen Punkte auch mit Funktionen ausprobieren. Es gibt jedoch einige Unterschiede.
- Oben haben wir Objekte mit Objektliteralnotation zu Objekten hinzugefügt. Wir können Mitglieder zu Funktionen hinzufügen, indem wir verwenden
this
. um sie zu spezifizieren. - Die Objektliteralnotation erstellt eine Objektinstanz, die wir sofort verwenden können. Mit function müssen wir möglicherweise zuerst die Instanz mit dem
new
Operator erstellen . - Auch in einem Objektliteralansatz können wir bereits definierten Objekten mithilfe des Punktoperators explizit Elemente hinzufügen. Dies wird nur der spezifischen Instanz hinzugefügt. Ich habe dem Funktionsprototyp jedoch eine Variable hinzugefügt, damit sie in allen Instanzen der Funktion wiedergegeben wird.
Unten habe ich alle Dinge ausprobiert, die wir mit Object und this
höher gemacht haben, aber indem ich zuerst eine Funktion erstellt habe, anstatt ein Objekt direkt zu schreiben.
/*********************************************************************
1. When you add variable to the function using this keyword, it
gets added to the function prototype, thus allowing all function
instances to have their own copy of the variables added.
*********************************************************************/
function functionDef()
{
this.name = "ObjDefinition";
this.getName = function(){
return this+":"+this.name;
}
}
obj1 = new functionDef();
document.write(obj1.getName() + "<br />"); //[object Object]:ObjDefinition
/*********************************************************************
2. Members explicitly added to the function protorype also behave
as above: all function instances have their own copy of the
variable added.
*********************************************************************/
functionDef.prototype.version = 1;
functionDef.prototype.getVersion = function(){
return "v"+this.version; //see how this.version refers to the
//version variable added through
//prototype
}
document.write(obj1.getVersion() + "<br />"); //v1
/*********************************************************************
3. Illustrating that the function variables added by both above
ways have their own copies across function instances
*********************************************************************/
functionDef.prototype.incrementVersion = function(){
this.version = this.version + 1;
}
var obj2 = new functionDef();
document.write(obj2.getVersion() + "<br />"); //v1
obj2.incrementVersion(); //incrementing version in obj2
//does not affect obj1 version
document.write(obj2.getVersion() + "<br />"); //v2
document.write(obj1.getVersion() + "<br />"); //v1
/*********************************************************************
4. `this` keyword refers to the immediate parent object. If you
nest the object through function prototype, then `this` inside
object refers to the nested object not the function instance
*********************************************************************/
functionDef.prototype.nestedObj = { name: 'nestedObj',
getName1 : function(){
return this+":"+this.name;
}
};
document.write(obj2.nestedObj.getName1() + "<br />"); //[object Object]:nestedObj
/*********************************************************************
5. If the method is on an object's prototype chain, `this` refers
to the object the method was called on, as if the method was on
the object.
*********************************************************************/
var ProtoObj = { fun: function () { return this.a } };
var obj3 = Object.create(ProtoObj); //creating an object setting ProtoObj
//as its prototype
obj3.a = 999; //adding instance member to obj3
document.write(obj3.fun()+"<br />");//999
//calling obj3.fun() makes
//ProtoObj.fun() to access obj3.a as
//if fun() is defined on obj3
4. Bei Verwendung innerhalb der Konstruktorfunktion .
Wenn die Funktion als Konstruktor verwendet wird (dh wenn sie mit einem new
Schlüsselwort aufgerufen wird ), zeigt der this
Funktionskörper innerhalb des Funktionskörpers auf das neu erstellte Objekt.
var myname = "global context";
function SimpleFun()
{
this.myname = "simple function";
}
var obj1 = new SimpleFun(); //adds myname to obj1
//1. `new` causes `this` inside the SimpleFun() to point to the
// object being constructed thus adding any member
// created inside SimipleFun() using this.membername to the
// object being constructed
//2. And by default `new` makes function to return newly
// constructed object if no explicit return value is specified
document.write(obj1.myname); //simple function
5. Bei Verwendung innerhalb der in der Prototypenkette definierten Funktion
Befindet sich die Methode in der Prototypenkette eines Objekts, this
bezieht sich diese Methode auf das Objekt, für das die Methode aufgerufen wurde, als ob die Methode für das Objekt definiert wäre.
var ProtoObj = {
fun: function () {
return this.a;
}
};
//Object.create() creates object with ProtoObj as its
//prototype and assigns it to obj3, thus making fun()
//to be the method on its prototype chain
var obj3 = Object.create(ProtoObj);
obj3.a = 999;
document.write(obj3.fun()); //999
//Notice that fun() is defined on obj3's prototype but
//`this.a` inside fun() retrieves obj3.a
6. Wenden Sie in call () die Funktionen apply () und bind () an
- Alle diese Methoden sind am definiert
Function.prototype
. - Mit diesen Methoden können Sie eine Funktion einmal schreiben und in einem anderen Kontext aufrufen. Mit anderen Worten, sie ermöglichen es, den Wert anzugeben, der
this
verwendet wird, während die Funktion ausgeführt wird. Sie übernehmen auch alle Parameter, die beim Aufrufen an die ursprüngliche Funktion übergeben werden. fun.apply(obj1 [, argsArray])
Legtobj1
den Wert vonthis
inside festfun()
und ruftfun()
übergebende Elemente vonargsArray
als Argumente auf.fun.call(obj1 [, arg1 [, arg2 [,arg3 [, ...]]]])
- Setsobj1
als der Wert vonthis
innenfun()
und Anrufenfun()
vorbeiarg1, arg2, arg3, ...
als Argumente.fun.bind(obj1 [, arg1 [, arg2 [,arg3 [, ...]]]])
- Gibt den Verweis auf die Funktion zurück,fun
wobei derthis
innere Spaß anobj1
und die Parameterfun
an die angegebenen Parameter gebunden sindarg1, arg2, arg3,...
.- Inzwischen ist der Unterschied zwischen
apply
,call
undbind
müssen offensichtlich geworden sind.apply
Ermöglicht die Angabe der Argumente, die als Array-ähnliches Objekt fungieren sollen, dh ein Objekt mit einer numerischenlength
Eigenschaft und entsprechenden nicht negativen ganzzahligen Eigenschaften. Währendcall
ermöglicht direkt die Argumente der Funktion zu spezifizieren. Beideapply
undcall
rufen sofort die Funktion im angegebenen Kontext und mit den angegebenen Argumenten auf. Gibt andererseitsbind
einfach die an den angegebenenthis
Wert und die Argumente gebundene Funktion zurück . Wir können den Verweis auf diese zurückgegebene Funktion erfassen, indem wir ihn einer Variablen zuweisen, und später können wir ihn jederzeit aufrufen.
function add(inc1, inc2)
{
return this.a + inc1 + inc2;
}
var o = { a : 4 };
document.write(add.call(o, 5, 6)+"<br />"); //15
//above add.call(o,5,6) sets `this` inside
//add() to `o` and calls add() resulting:
// this.a + inc1 + inc2 =
// `o.a` i.e. 4 + 5 + 6 = 15
document.write(add.apply(o, [5, 6]) + "<br />"); //15
// `o.a` i.e. 4 + 5 + 6 = 15
var g = add.bind(o, 5, 6); //g: `o.a` i.e. 4 + 5 + 6
document.write(g()+"<br />"); //15
var h = add.bind(o, 5); //h: `o.a` i.e. 4 + 5 + ?
document.write(h(6) + "<br />"); //15
// 4 + 5 + 6 = 15
document.write(h() + "<br />"); //NaN
//no parameter is passed to h()
//thus inc2 inside add() is `undefined`
//4 + 5 + undefined = NaN</code>
7. this
Inside Event Handler
- Wenn Sie den Ereignishandlern eines Elements eine Funktion direkt zuweisen,
this
bezieht sich die Verwendung der Funktion zur direkten Behandlung innerhalb des Ereignisses auf das entsprechende Element. Eine solche direkte Funktionszuweisung kann unter Verwendung eineraddeventListener
Methode oder durch herkömmliche Ereignisregistrierungsmethoden wie erfolgenonclick
. - Wenn Sie
this
direkt innerhalb der Ereigniseigenschaft (wie<button onclick="...this..." >
) des Elements verwenden, bezieht sich dies auf das Element. - Die Verwendung von
this
indirekt über die andere Funktion, die innerhalb der Ereignisbehandlungsfunktion oder der Ereigniseigenschaft aufgerufen wird, wird jedoch in das globale Objekt aufgelöstwindow
. - Das gleiche obige Verhalten wird erreicht, wenn wir die Funktion mithilfe der Microsoft-Modellmethode für die Ereignisregistrierung an den Ereignishandler anhängen
attachEvent
. Anstatt die Funktion dem Ereignishandler zuzuweisen (und damit die Funktionsmethode des Elements zu erstellen), ruft sie die Funktion für das Ereignis auf (ruft sie effektiv im globalen Kontext auf).
Ich empfehle, dies besser in JSFiddle zu versuchen .
<script>
function clickedMe() {
alert(this + " : " + this.tagName + " : " + this.id);
}
document.getElementById("button1").addEventListener("click", clickedMe, false);
document.getElementById("button2").onclick = clickedMe;
document.getElementById("button5").attachEvent('onclick', clickedMe);
</script>
<h3>Using `this` "directly" inside event handler or event property</h3>
<button id="button1">click() "assigned" using addEventListner() </button><br />
<button id="button2">click() "assigned" using click() </button><br />
<button id="button3" onclick="alert(this+ ' : ' + this.tagName + ' : ' + this.id);">used `this` directly in click event property</button>
<h3>Using `this` "indirectly" inside event handler or event property</h3>
<button onclick="alert((function(){return this + ' : ' + this.tagName + ' : ' + this.id;})());">`this` used indirectly, inside function <br /> defined & called inside event property</button><br />
<button id="button4" onclick="clickedMe()">`this` used indirectly, inside function <br /> called inside event property</button> <br />
IE only: <button id="button5">click() "attached" using attachEvent() </button>
8. this
in der ES6-Pfeilfunktion
In einer Pfeilfunktion this
verhält es sich wie allgemeine Variablen: Es wird von seinem lexikalischen Bereich geerbt. Die Funktion this
, in der die Pfeilfunktion definiert ist, ist die Pfeilfunktion this
.
Das ist also das gleiche Verhalten wie:
(function(){}).bind(this)
Siehe folgenden Code:
const globalArrowFunction = () => {
return this;
};
console.log(globalArrowFunction()); //window
const contextObject = {
method1: () => {return this},
method2: function(){
return () => {return this};
}
};
console.log(contextObject.method1()); //window
const contextLessFunction = contextObject.method1;
console.log(contextLessFunction()); //window
console.log(contextObject.method2()()) //contextObject
const innerArrowFunction = contextObject.method2();
console.log(innerArrowFunction()); //contextObject
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
. Dies liegt daran, dass window
es sich um die globale Variable im Bereich eines Webbrowsers handelt.
Wenn Sie denselben Code in einer Umgebung wie node.js ausführen, wird 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 nur protokollieren undefined
, 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, wenn eine Methode in einer anderen Variablen gespeichert (oder vielmehr kopiert) wird, der Verweis auf this
in der neuen Variablen nicht mehr beibehalten 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 einenObject
Typ initialisierenPerson
. - Der Konstruktor hierfür
Object
hat seinen Konstruktor auf gesetztPerson
. Beachten Sie auch, dasstypeof awal
zurückkehren würdeObject
nur. - Diesem neuen
Object
würde der Prototyp von zugewiesenPerson.prototype
. Dies bedeutet, dass jede Methode oder Eigenschaft imPerson
Prototyp für alle Instanzen von verfügbar istPerson
, einschließlichawal
. - Die Funktion
Person
selbst wird jetzt aufgerufen.this
ein Verweis auf das neu konstruierte Objekt seinawal
.
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
s auch Objects
(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 gute Möglichkeit, den Wert von this
in einer beliebigen Funktion zu ändern .
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 des Aufrufs von this
set by dot method überschreiben kann, den wir im zweiten Aufzählungszeichen besprochen 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
wird auch den Wert der Überfahrt this
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 zurückgeben, während bind
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 das
new
Schlüsselwort verwenden? - Wie manipulieren wir
this
mitcall
undapply
? - Verwenden von
bind
. - Kopieren,
this
um Probleme mit verschachtelten Bereichen zu lösen.
"das" dreht sich alles um Umfang. Jede Funktion hat ihren eigenen Bereich, und da alles in JS ein Objekt ist, kann sogar eine Funktion mit "this" einige Werte in sich speichern. OOP 101 lehrt, dass "dies" nur für Instanzen eines Objekts gilt. Daher hat jedes Mal, wenn eine Funktion ausgeführt wird, eine neue "Instanz" dieser Funktion eine neue Bedeutung von "dies".
Die meisten Menschen sind verwirrt, wenn sie versuchen, "dies" in anonymen Schließfunktionen wie:
(Funktion (Wert) { this.value = value; $ ('. some-elements'). each (function (elt) { elt.innerHTML = this.value; // uh oh !! möglicherweise undefiniert }); }) (2);
Hier in jedem () enthält "this" also nicht den "Wert", den Sie erwarten (von
this.value = value;über). Um dieses Problem zu lösen (kein Wortspiel beabsichtigt), könnte ein Entwickler:
(Funktion (Wert) { var self = this; // kleine Veränderung self.value = value; $ ('. some-elements'). each (function (elt) { elt.innerHTML = self.value; // Puh !! == 2 }); }) (2);
Versuch es; Sie werden anfangen, dieses Programmiermuster zu mögen
Da dieser Thread aufgetaucht ist, habe ich einige Punkte für Leser zusammengestellt, die neu im this
Thema sind.
Wie wird der Wert von this
bestimmt?
Wir verwenden dies ähnlich wie wir Pronomen in natürlichen Sprachen wie Englisch verwenden: „John rennt schnell, weil er versucht, den Zug zu erreichen.“ Stattdessen hätten wir schreiben können: „… John versucht, den Zug zu erreichen“.
var person = {
firstName: "Penelope",
lastName: "Barrymore",
fullName: function () {
// We use "this" just as in the sentence above:
console.log(this.firstName + " " + this.lastName);
// We could have also written:
console.log(person.firstName + " " + person.lastName);
}
}
this
wird erst dann ein Wert zugewiesen, wenn ein Objekt die Funktion aufruft, in der es definiert ist. Im globalen Bereich werden alle globalen Variablen und Funktionen für das window
Objekt definiert . Daher this
bezieht sich eine globale Funktion auf das globale window
Objekt (und hat dessen Wert) .
Wenn use strict
, this
die gebunden sind , nicht auf jedes Objekt in der globalen und in anonymen Funktionen enthält einen Wert von undefined
.
Das this
Schlüsselwort wird am meisten missverstanden, wenn: 1) wir eine verwendete Methode ausleihen this
, 2) this
einer Variablen eine verwendete Methode zuweisen , 3) eine verwendete Funktion this
als Rückruffunktion übergeben wird und 4) this
innerhalb eines Abschlusses verwendet wird - eine innere Funktion. (2)
Was hält die Zukunft
In ECMA Script 6 definiert , übernehmen Pfeilfunktionen die this
Bindung aus dem umschließenden (funktionalen oder globalen) Bereich.
function foo() {
// return an arrow function
return (a) => {
// `this` here is lexically inherited from `foo()`
console.log(this.a);
};
}
var obj1 = { a: 2 };
var obj2 = { a: 3 };
var bar = foo.call(obj1);
bar.call( obj2 ); // 2, not 3!
Während Pfeilfunktionen eine Alternative zur Verwendung darstellen bind()
, ist es wichtig zu beachten, dass sie im Wesentlichen den traditionellen this
Mechanismus zugunsten eines allgemeineren lexikalischen Geltungsbereichs deaktivieren . (1)
Verweise:
- this & Object Prototypes von Kyle Simpson. © 2014 Getify Solutions.
- javascriptissexy.com - http://goo.gl/pvl0GX
- Angus Croll - http://goo.gl/Z2RacU
this
bezieht sich in JavaScript immer auf den 'Eigentümer' der Funktion, die ausgeführt wird .
Wenn kein expliziter Eigentümer definiert ist, wird auf den obersten Eigentümer, das Fensterobjekt, verwiesen.
Also wenn ich es täte
function someKindOfFunction() {
this.style = 'foo';
}
element.onclick = someKindOfFunction;
this
würde sich auf das Elementobjekt beziehen. Aber seien Sie vorsichtig, viele Leute machen diesen Fehler.
<element onclick="someKindOfFunction()">
Im letzteren Fall verweisen Sie lediglich auf die Funktion und übergeben sie nicht an das Element. Daher this
wird auf das Fensterobjekt verwiesen.
Jeder Ausführungskontext in Javascript hat diesen Parameter, der festgelegt wird durch:
- Wie die Funktion aufgerufen wird (einschließlich als Objektmethode, Verwendung von Aufruf und Anwendung , Verwendung von Neu )
- Verwendung von binden
- Lexikalisch für Pfeilfunktionen (sie übernehmen das Dies ihres äußeren Ausführungskontexts)
- Gibt an, ob sich der Code im strengen oder im nicht strengen Modus befindet
- Ob der Code mit aufgerufen wurde eval
Sie können den Wert festgelegt dies mit func.call
, func.apply
oder func.bind
.
Standardmäßig und was die meisten Anfänger verwirrt, ist dieser Wert der Funktion das DOM-Element , wenn ein Listener aufgerufen wird, nachdem ein Ereignis für ein DOM-Element ausgelöst wurde.
Mit jQuery ist es trivial, dies mit jQuery.proxy zu ändern.
Daniel, tolle Erklärung! Ein paar Worte dazu und eine gute Liste von this
Ausführungskontextzeigern bei Ereignishandlern.
Mit zwei Worten, this
in JavaScript zeigt das Objekt, von dem (oder von dessen Ausführungskontext) die aktuelle Funktion ausgeführt wurde, und es ist immer schreibgeschützt. Sie können es trotzdem nicht festlegen (ein solcher Versuch führt zu 'Ungültige linke Hand') Seite in Zuweisung 'Nachricht.
Für Ereignishandler: Inline-Ereignishandler, z. B. <element onclick="foo">
überschreiben Sie alle anderen Handler, die zuvor und zuvor angehängt wurden. Seien Sie also vorsichtig und halten Sie sich besser von der Inline-Ereignisdelegierung fern. Und danke an Zara Alaverdyan, die mich durch eine abweichende Debatte zu dieser Liste von Beispielen inspiriert hat :)
el.onclick = foo; // in the foo - obj
el.onclick = function () {this.style.color = '#fff';} // obj
el.onclick = function() {doSomething();} // In the doSomething - Window
el.addEventListener('click',foo,false) // in the foo - obj
el.attachEvent('onclick, function () { // this }') // window, all the compliance to IE :)
<button onclick="this.style.color = '#fff';"> // obj
<button onclick="foo"> // In the foo - window, but you can <button onclick="foo(this)">
Hier ist eine gute Quelle von this
in JavaScript
.
Hier ist die Zusammenfassung:
global dies
In einem Browser ist im globalen Bereich
this
daswindow
Objekt<script type="text/javascript"> console.log(this === window); // true var foo = "bar"; console.log(this.foo); // "bar" console.log(window.foo); // "bar"
Bei der
node
Verwendung der Antwortthis
ist dies der oberste Namespace. Sie können es als bezeichnenglobal
.>this { ArrayBuffer: [Function: ArrayBuffer], Int8Array: { [Function: Int8Array] BYTES_PER_ELEMENT: 1 }, Uint8Array: { [Function: Uint8Array] BYTES_PER_ELEMENT: 1 }, ... >global === this true
Bei der
node
Ausführung von einem Skript austhis
beginnt der globale Bereich als leeres Objekt. Es ist nicht dasselbe wieglobal
\\test.js console.log(this); \\ {} console.log(this === global); \\ fasle
Funktion dies
Außer im Fall von DOM-Ereignishandlern oder wenn a thisArg
bereitgestellt wird (siehe weiter unten), verwenden sowohl im Knoten als auch in einem Browser this
in einer Funktion, die nicht mit new
Verweisen aufgerufen wird, den globalen Bereich…
<script type="text/javascript">
foo = "bar";
function testThis() {
this.foo = "foo";
}
console.log(this.foo); //logs "bar"
testThis();
console.log(this.foo); //logs "foo"
</script>
Wenn Sie verwenden use strict;
, wird in diesem Fall this
seinundefined
<script type="text/javascript">
foo = "bar";
function testThis() {
"use strict";
this.foo = "foo";
}
console.log(this.foo); //logs "bar"
testThis(); //Uncaught TypeError: Cannot set property 'foo' of undefined
</script>
Wenn Sie eine Funktion aufrufen, bei new
der this
es sich um einen neuen Kontext handelt, verweist sie nicht auf den globalen Kontext this
.
<script type="text/javascript">
foo = "bar";
function testThis() {
this.foo = "foo";
}
console.log(this.foo); //logs "bar"
new testThis();
console.log(this.foo); //logs "bar"
console.log(new testThis().foo); //logs "foo"
</script>
- Prototyp dieses
Von Ihnen erstellte Funktionen werden zu Funktionsobjekten. Sie erhalten automatisch eine spezielle prototype
Eigenschaft, der Sie Werte zuweisen können. Wenn Sie eine Instanz erstellen, indem Sie Ihre Funktion mit aufrufen, erhalten new
Sie Zugriff auf die Werte, die Sie der prototype
Eigenschaft zugewiesen haben . Sie greifen mit auf diese Werte zu this
.
function Thing() {
console.log(this.foo);
}
Thing.prototype.foo = "bar";
var thing = new Thing(); //logs "bar"
console.log(thing.foo); //logs "bar"
Es ist normalerweise ein Fehler, Arrays oder Objekte auf dem zuzuweisen prototype
. Wenn Sie möchten, dass Instanzen jeweils ihre eigenen Arrays haben, erstellen Sie sie in der Funktion und nicht im Prototyp.
function Thing() {
this.things = [];
}
var thing1 = new Thing();
var thing2 = new Thing();
thing1.things.push("foo");
console.log(thing1.things); //logs ["foo"]
console.log(thing2.things); //logs []
- Einwände dagegen
Sie können this
in jeder Funktion eines Objekts auf andere Eigenschaften dieses Objekts verweisen. Dies ist nicht dasselbe wie eine Instanz, die mit erstellt wurde new
.
var obj = {
foo: "bar",
logFoo: function () {
console.log(this.foo);
}
};
obj.logFoo(); //logs "bar"
- DOM Event dies
In einem HTML-DOM-Ereignishandler this
wird immer auf das DOM-Element verwiesen, an das das Ereignis angehängt wurde
function Listener() {
document.getElementById("foo").addEventListener("click",
this.handleClick);
}
Listener.prototype.handleClick = function (event) {
console.log(this); //logs "<div id="foo"></div>"
}
var listener = new Listener();
document.getElementById("foo").click();
Es sei denn, Sie bind
den Kontext
function Listener() {
document.getElementById("foo").addEventListener("click",
this.handleClick.bind(this));
}
Listener.prototype.handleClick = function (event) {
console.log(this); //logs Listener {handleClick: function}
}
var listener = new Listener();
document.getElementById("foo").click();
- HTML dies
Innerhalb von HTML-Attributen, in die Sie JavaScript einfügen können, this
befindet sich ein Verweis auf das Element.
<div id="foo" onclick="console.log(this);"></div>
<script type="text/javascript">
document.getElementById("foo").click(); //logs <div id="foo"...
</script>
- bewerte dies
Sie können verwenden, eval
um darauf zuzugreifen this
.
function Thing () {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () {
eval("console.log(this.foo)"); //logs "bar"
}
var thing = new Thing();
thing.logFoo();
- mit diesem
Sie können den aktuellen Bereich zum Lesen und Schreiben von Werten with
hinzufügen this
, this
ohne this
explizit darauf zu verweisen .
function Thing () {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () {
with (this) {
console.log(foo);
foo = "foo";
}
}
var thing = new Thing();
thing.logFoo(); // logs "bar"
console.log(thing.foo); // logs "foo"
- jQuery this
Die jQuery wird an vielen Stellen this
auf ein DOM-Element verweisen.
<div class="foo bar1"></div>
<div class="foo bar2"></div>
<script type="text/javascript">
$(".foo").each(function () { console.log(this); //logs <div class="foo... }); $(".foo").on("click", function () {
console.log(this); //logs <div class="foo...
});
$(".foo").each(function () {
this.click();
});
</script>
Es gibt viel Verwirrung darüber, wie "dieses" Schlüsselwort in JavaScript interpretiert wird. Hoffentlich legt dieser Artikel all diejenigen ein, die sich ein für alle Mal ausruhen. Und vieles mehr. Bitte lesen Sie den gesamten Artikel sorgfältig durch. Seien Sie gewarnt, dass dieser Artikel lang ist.
Unabhängig vom Kontext, in dem es verwendet wird, verweist "this" immer auf das "aktuelle Objekt" in Javascript. Was das "aktuelle Objekt" ist, unterscheidet sich jedoch je nach Kontext . Der Kontext kann genau 1 der 6 folgenden sein:
- Global (dh außerhalb aller Funktionen)
- Inside Direct-Aufruf "Non Bound Function" (dh eine Funktion, die nicht durch Aufrufen von functionName.bind gebunden wurde )
- Inside Indirect "Non Bound Function" Aufruf über functionName.call und functionName.apply
- Innerhalb des Aufrufs "Gebundene Funktion" (dh eine Funktion, die durch Aufrufen von functionName.bind gebunden wurde )
- Während der Objekterstellung durch "neu"
- Inside Inline DOM-Ereignishandler
Im Folgenden wird jeder dieser Kontexte einzeln beschrieben:
Globaler Kontext (dh außerhalb aller Funktionen):
Außerhalb aller Funktionen (dh im globalen Kontext) ist das "aktuelle Objekt" (und damit der Wert von "this" ) immer das "Fenster" -Objekt für Browser.
Inside Direct-Aufruf "Non Bound Function" :
Innerhalb eines direkten Aufrufs "Nicht gebundene Funktion" wird das Objekt, das den Funktionsaufruf aufgerufen hat, zum "aktuellen Objekt" (und damit zum Wert von "this" ). Wenn eine Funktion ohne explizites aktuelles Objekt aufgerufen wird , ist das aktuelle Objekt entweder das "Fenster" -Objekt (für den nicht strengen Modus) oder undefiniert (für den strengen Modus). Jede im globalen Kontext definierte Funktion (oder Variable) wird automatisch zu einer Eigenschaft des "Fenster" -Objekts. Zum Beispiel wird angenommen, dass die Funktion im globalen Kontext als definiert ist
function UserDefinedFunction(){ alert(this) }
Es wird zur Eigenschaft des Fensterobjekts, als hätten Sie es als definiert
window.UserDefinedFunction=function(){ alert(this) }
Wenn Sie diese Funktion im "nicht strengen Modus" direkt über "UserDefinedFunction ()" aufrufen / aufrufen, wird sie automatisch als "window.UserDefinedFunction ()" aufgerufen / aufgerufen und "window" zum "aktuellen Objekt" (und damit zum Wert von "). this " ) innerhalb von " UserDefinedFunction ". Wenn Sie diese Funktion im" Non Strict Mode "aufrufen, wird Folgendes ausgeführt
UserDefinedFunction() // displays [object Window] as it automatically gets invoked as window.UserDefinedFunction()
Wenn Sie im "Strict Mode" die Funktion direkt über "UserDefinedFunction ()" aufrufen / aufrufen, wird sie "NOT" automatisch als "window.UserDefinedFunction ()" aufrufen / aufrufen. Daher das "aktuelle Objekt" (und der Wert von "this"). ) innerhalb von "UserDefinedFunction" muss undefiniert sein . Das Aufrufen dieser Funktion im "Strict Mode" führt zu Folgendem
UserDefinedFunction() // displays undefined
Das explizite Aufrufen mit einem Fensterobjekt führt jedoch zu Folgendem
window.UserDefinedFunction() // "always displays [object Window] irrespective of mode."
Schauen wir uns ein anderes Beispiel an. Bitte schauen Sie sich den folgenden Code an
function UserDefinedFunction() { alert(this.a + "," + this.b + "," + this.c + "," + this.d) } var o1={ a:1, b:2, f:UserDefinedFunction } var o2={ c:3, d:4, f:UserDefinedFunction } o1.f() // Shall display 1,2,undefined,undefined o2.f() // Shall display undefined,undefined,3,4
Im obigen Beispiel sehen wir, dass, wenn "UserDefinedFunction" über o1 aufgerufen wurde , "this" den Wert o1 annimmt und der Wert seiner Eigenschaften "a" und "b" angezeigt wird. Der Wert von "c" und "d" wurde als undefiniert angezeigt, da o1 diese Eigenschaften nicht definiert
In ähnlicher Weise, wenn "UserDefinedFunction" über o2 aufgerufen wurde , nimmt "this" den Wert von o2 an und der Wert seiner Eigenschaften "c" und "d" wird angezeigt. Der Wert von "a" und "b" wurde als undefiniert angezeigt, wie dies bei o2 der Fall ist diese Eigenschaften nicht definieren.
Inside Indirect "Non Bound Function" Aufruf über functionName.call und functionName.apply :
Wenn eine "nicht gebundene Funktion" über functionName.call oder functionName.apply aufgerufen wird , wird das "aktuelle Objekt" (und damit der Wert von "this" ) auf den Wert des Parameters "this" (erster Parameter) gesetzt, der an den Aufruf übergeben wird Ich bewerbe mich . Der folgende Code zeigt dasselbe.
function UserDefinedFunction() { alert(this.a + "," + this.b + "," + this.c + "," + this.d) } var o1={ a:1, b:2, f:UserDefinedFunction } var o2={ c:3, d:4, f:UserDefinedFunction } UserDefinedFunction.call(o1) // Shall display 1,2,undefined,undefined UserDefinedFunction.apply(o1) // Shall display 1,2,undefined,undefined UserDefinedFunction.call(o2) // Shall display undefined,undefined,3,4 UserDefinedFunction.apply(o2) // Shall display undefined,undefined,3,4 o1.f.call(o2) // Shall display undefined,undefined,3,4 o1.f.apply(o2) // Shall display undefined,undefined,3,4 o2.f.call(o1) // Shall display 1,2,undefined,undefined o2.f.apply(o1) // Shall display 1,2,undefined,undefined
Der obige Code zeigt deutlich, dass der Wert "this" für jede "NON Bound Function" durch Aufruf / Anwenden geändert werden kann . Wenn der Parameter "this" nicht explizit an call / apply übergeben wird , wird "current object" (und damit der Wert von "this") im nicht strengen Modus auf "window" und im strengen Modus auf "undefined" gesetzt .
Innerhalb des Aufrufs "Gebundene Funktion" (dh einer Funktion, die durch Aufrufen von functionName.bind gebunden wurde ):
Eine gebundene Funktion ist eine Funktion, deren "dieser" Wert festgelegt wurde. Der folgende Code demonstrierte, wie "dies" im Fall einer gebundenen Funktion funktioniert
function UserDefinedFunction() { alert(this.a + "," + this.b + "," + this.c + "," + this.d) } var o1={ a:1, b:2, f:UserDefinedFunction, bf:null } var o2={ c:3, d:4, f:UserDefinedFunction, bf:null } var bound1=UserDefinedFunction.bind(o1); // permanantly fixes "this" value of function "bound1" to Object o1 bound1() // Shall display 1,2,undefined,undefined var bound2=UserDefinedFunction.bind(o2); // permanantly fixes "this" value of function "bound2" to Object o2 bound2() // Shall display undefined,undefined,3,4 var bound3=o1.f.bind(o2); // permanantly fixes "this" value of function "bound3" to Object o2 bound3() // Shall display undefined,undefined,3,4 var bound4=o2.f.bind(o1); // permanantly fixes "this" value of function "bound4" to Object o1 bound4() // Shall display 1,2,undefined,undefined o1.bf=UserDefinedFunction.bind(o2) // permanantly fixes "this" value of function "o1.bf" to Object o2 o1.bf() // Shall display undefined,undefined,3,4 o2.bf=UserDefinedFunction.bind(o1) // permanantly fixes "this" value of function "o2.bf" to Object o1 o2.bf() // Shall display 1,2,undefined,undefined bound1.call(o2) // Shall still display 1,2,undefined,undefined. "call" cannot alter the value of "this" for bound function bound1.apply(o2) // Shall still display 1,2,undefined,undefined. "apply" cannot alter the value of "this" for bound function o2.bf.call(o2) // Shall still display 1,2,undefined,undefined. "call" cannot alter the value of "this" for bound function o2.bf.apply(o2) // Shall still display 1,2,undefined,undefined."apply" cannot alter the value of "this" for bound function
Wie im obigen Code angegeben, kann "dieser" Wert für eine "gebundene Funktion" NICHT durch Aufrufen / Anwenden geändert werden . Wenn der Parameter "this" nicht explizit an bind übergeben wird, wird "current object" (und damit der Wert von "this" ) im nicht strengen Modus auf "window" und im strengen Modus auf "undefined" gesetzt . Eine Sache noch. Das Binden einer bereits gebundenen Funktion ändert den Wert von "this" nicht . Es bleibt als der Wert festgelegt, der durch die erste Bindungsfunktion festgelegt wurde.
Während der Objekterstellung durch "neu" :
Innerhalb einer Konstruktorfunktion verweist das "aktuelle Objekt" (und damit der Wert von "this" ) auf das Objekt, das derzeit durch "new" erstellt wird, unabhängig vom Bindungsstatus der Funktion. Wenn der Konstruktor jedoch eine gebundene Funktion ist, wird er mit vordefinierten Argumenten aufgerufen, die für die gebundene Funktion festgelegt sind.
Inside Inline DOM-Ereignishandler :
Bitte schauen Sie sich das folgende HTML-Snippet an
<button onclick='this.style.color=white'>Hello World</button> <div style='width:100px;height:100px;' onclick='OnDivClick(event,this)'>Hello World</div>
Das "dies" in den obigen Beispielen bezieht sich auf das "button" -Element bzw. das "div" -Element.
Im ersten Beispiel muss die Schriftfarbe der Schaltfläche beim Klicken auf Weiß gesetzt werden.
Im zweiten Beispiel wird beim Klicken auf das Element "div" die Funktion OnDivClick aufgerufen , wobei der zweite Parameter auf das angeklickte Element div verweist. Der Wert von "this" in OnDivClick darf jedoch NICHT auf das angeklickte div- Element verweisen . Es muss als "Fensterobjekt" oder "undefiniert" im nicht strengen bzw. strengen Modus festgelegt werden (wenn OnDivClick eine ungebundene Funktion ist ) oder auf einen vordefinierten gebundenen Wert festgelegt werden (wenn OnDivClick eine gebundene Funktion ist ).
Das Folgende fasst den gesamten Artikel zusammen
Im globalen Kontext bezieht sich "dies" immer auf das "Fenster" -Objekt
Wenn eine Funktion aufgerufen wird, wird sie im Kontext eines Objekts ( "aktuelles Objekt" ) aufgerufen . Wenn das aktuelle Objekt nicht explizit angegeben wird, ist das aktuelle Objekt standardmäßig das "Fensterobjekt" im NON Strict-Modus und "Undefined" im Strict-Modus.
Der Wert von "this" innerhalb einer nicht gebundenen Funktion ist die Referenz auf ein Objekt, in dessen Kontext die Funktion aufgerufen wird ( "aktuelles Objekt" ).
Der Wert von "this" innerhalb einer nicht gebundenen Funktion kann durch Aufrufen und Anwenden von Methoden der Funktion überschrieben werden .
Der Wert von "this" ist für eine gebundene Funktion festgelegt und kann nicht durch Aufrufen und Anwenden von Methoden der Funktion überschrieben werden .
Die bindende und bereits gebundene Funktion ändert den Wert von "this" nicht. Es bleibt als der Wert festgelegt, der durch die erste Bindungsfunktion festgelegt wurde.
Der Wert von "this" innerhalb eines Konstruktors ist das Objekt, das erstellt und initialisiert wird
Der Wert "this" in einem Inline-DOM-Ereignishandler bezieht sich auf das Element, für das der Ereignishandler angegeben ist.
Der wahrscheinlich ausführlichste und umfassendste Artikel this
ist der folgende:
Schonende Erklärung dieses Schlüsselworts in JavaScript
Die Idee dahinter this
ist zu verstehen, dass die Funktionsaufruftypen die signifikante Bedeutung für die Einstellung des this
Werts haben.
Wenn mit Schwierigkeiten zu identifizieren this
, nicht sich fragen:
Woher kommt
this
es ?
aber Sie fragen Sie sich:
Wie wird die Funktion aufgerufen ?
Für eine Pfeilfunktion (Sonderfall der Kontexttransparenz) fragen Sie sich:
Welchen Wert hat
this
wo die Pfeilfunktion definiert ist ?
Diese Einstellung ist richtig im Umgang mit this
und erspart Ihnen Kopfschmerzen.
Dies ist die beste Erklärung , die ich gesehen habe: Verstehen Sie JavaScripts diese mit Clarity
Die diese Referenz bezieht sich immer auf (und hält den Wert von) ein objekt einer singuläres objekt und es in der Regel in einer Funktion , oder ein Verfahren verwendet wird, obwohl es außerhalb einer Funktion im globalen Bereich verwendet werden kann. Beachten Sie, dass bei Verwendung des strengen Modus der Wert undefiniert in globalen Funktionen und in anonymen Funktionen enthalten ist, die an kein Objekt gebunden sind.
Es gibt vier Szenarien, in denen dies verwirrend sein kann:
- Wenn wir ein Verfahren (das verwendet passieren diese ) als Argument als Callback - Funktion verwendet werden.
- Wenn wir eine innere Funktion verwenden (einen Verschluss). Es ist wichtig zu beachten, dass Closures mit dem Schlüsselwort this nicht auf diese Variable der äußeren Funktion zugreifen können, da auf diese Variable nur die Funktion selbst zugreifen kann, nicht die inneren Funktionen.
- Wenn ein Verfahren , das auf beruht dies auf eine Variable in Kontexten zugeordnet, in welchem Fall diese Verweise eine andere Aufgabe , als ursprünglich beabsichtigt.
- Wenn Sie dies zusammen mit den Bind-, Apply- und Call-Methoden verwenden.
Er gibt Codebeispiele, Erklärungen und Lösungen, die ich für sehr hilfreich hielt.
this
ist eines der missverstandenen Konzepte in JavaScript, da es sich von Ort zu Ort kaum anders verhält. this
Bezieht sich einfach auf den "Eigentümer" der Funktion, die wir gerade ausführen .
this
hilft dabei, das aktuelle Objekt (auch als Ausführungskontext bezeichnet) abzurufen, mit dem wir arbeiten. Wenn Sie verstehen, in welchem Objekt die aktuelle Funktion ausgeführt wird, können Sie leicht verstehen, was aktuell this
ist
var val = "window.val"
var obj = {
val: "obj.val",
innerMethod: function () {
var val = "obj.val.inner",
func = function () {
var self = this;
return self.val;
};
return func;
},
outerMethod: function(){
return this.val;
}
};
//This actually gets executed inside window object
console.log(obj.innerMethod()()); //returns window.val
//Breakdown in to 2 lines explains this in detail
var _inn = obj.innerMethod();
console.log(_inn()); //returns window.val
console.log(obj.outerMethod()); //returns obj.val
Oben erstellen wir 3 Variablen mit dem gleichen Namen 'val'. Eine im globalen Kontext, eine innerhalb von obj und die andere innerhalb von innerMethod of obj. JavaScript löst Bezeichner in einem bestimmten Kontext auf, indem die Bereichskette von lokal nach global verschoben wird.
Nur wenige Orte, an denen this
unterschieden werden kann
Aufrufen einer Methode eines Objekts
var status = 1;
var helper = {
status : 2,
getStatus: function () {
return this.status;
}
};
var theStatus1 = helper.getStatus(); //line1
console.log(theStatus1); //2
var theStatus2 = helper.getStatus;
console.log(theStatus2()); //1
Wenn line1 ausgeführt wird, erstellt JavaScript einen Ausführungskontext (EC) für den Funktionsaufruf und setzt this
auf das Objekt , auf das vor dem letzten "" verwiesen wird. . In der letzten Zeile können Sie also verstehen, dass dies a()
im globalen Kontext ausgeführt wurde window
.
Mit Konstruktor
this
kann verwendet werden, um auf das zu erstellende Objekt zu verweisen
function Person(name){
this.personName = name;
this.sayHello = function(){
return "Hello " + this.personName;
}
}
var person1 = new Person('Scott');
console.log(person1.sayHello()); //Hello Scott
var person2 = new Person('Hugh');
var sayHelloP2 = person2.sayHello;
console.log(sayHelloP2()); //Hello undefined
Wenn neu Person()
ausgeführt wird, wird ein vollständig neues Objekt erstellt. Person
wird aufgerufen und this
so eingestellt, dass es auf dieses neue Objekt verweist.
Funktionsaufruf
function testFunc() {
this.name = "Name";
this.myCustomAttribute = "Custom Attribute";
return this;
}
var whatIsThis = testFunc();
console.log(whatIsThis); //window
var whatIsThis2 = new testFunc();
console.log(whatIsThis2); //testFunc() / object
console.log(window.myCustomAttribute); //Custom Attribute
Wenn wir ein new
Schlüsselwort vermissen , whatIsThis
verweist es auf den globalsten Kontext, den es finden kann ( window
)
Mit Event-Handlern
Wenn der Ereignishandler inline ist, this
bezieht er sich auf ein globales Objekt
<script type="application/javascript">
function click_handler() {
alert(this); // alerts the window object
}
</script>
<button id='thebutton' onclick='click_handler()'>Click me!</button>
this
Bezieht sich beim Hinzufügen eines Ereignishandlers über JavaScript auf das DOM-Element, das das Ereignis generiert hat.
- Sie können den Kontext auch mit
.apply()
.call()
und bearbeiten.bind()
- JQuery-Proxy ist eine weitere Möglichkeit, mit der Sie sicherstellen können, dass dies in einer Funktion der gewünschte Wert ist. (Überprüfen Sie die Verwendung von $ .proxy () , jQuery.proxy (). )
- Was var that = thisbedeutet das in JavaScript ?
In pseudoklassischen Begriffen ist die Art und Weise, wie viele Vorlesungen das Schlüsselwort 'this' lehren, ein Objekt, das von einer Klasse oder einem Objektkonstruktor instanziiert wird. Stellen Sie sich jedes Mal vor, wenn ein neues Objekt aus einer Klasse erstellt wird, dass unter der Haube eine lokale Instanz eines 'this'-Objekts erstellt und zurückgegeben wird. Ich erinnere mich, dass es so gelehrt wurde:
function Car(make, model, year) {
var this = {}; // under the hood, so to speak
this.make = make;
this.model = model;
this.year = year;
return this; // under the hood
}
var mycar = new Car('Eagle', 'Talon TSi', 1993);
// ========= under the hood
var this = {};
this.make = 'Eagle';
this.model = 'Talon TSi';
this.year = 1993;
return this;
Der Wert von "this" hängt vom "Kontext" ab, in dem die Funktion ausgeführt wird. Der Kontext kann ein beliebiges Objekt oder das globale Objekt sein, dh ein Fenster.
Die Semantik von "dies" unterscheidet sich also von den traditionellen OOP-Sprachen. Und es verursacht Probleme: 1. wenn eine Funktion an eine andere Variable übergeben wird (höchstwahrscheinlich ein Rückruf); und 2. wenn ein Abschluss von einer Mitgliedsmethode einer Klasse aufgerufen wird.
In beiden Fällen ist dies auf Fenster eingestellt.
Was würde das helfen? (Die größte Verwirrung von "dies" in Javascript ist darauf zurückzuführen, dass es im Allgemeinen nicht mit Ihrem Objekt verknüpft ist, sondern mit dem aktuellen Ausführungsbereich - das funktioniert möglicherweise nicht genau so, fühlt sich für mich aber immer so an - eine vollständige Erklärung finden Sie im Artikel.)
Ein paar Infos zu diesem Keyword
Lassen Sie uns das this
Schlüsselwort im globalen Bereich ohne weiteren Code auf der Konsole protokollieren
console.log(this)
In Client / Browser ist das this
Schlüsselwort ein globales Objektwindow
console.log(this === window) // true
und
In Server / Node / Javascript ist das Laufzeitschlüsselwort this
auch ein globales Objektmodule.exports
console.log(this === module.exports) // true
console.log(this === exports) // true
Denken Sie daran, exports
ist nur ein Hinweis aufmodule.exports
Diese Verwendung für Scope ist einfach so
<script type="text/javascript" language="javascript">
$('#tbleName tbody tr').each(function{ var txt=''; txt += $(this).find("td").eq(0).text();
\\same as above but synatx different
var txt1='';
txt1+=$('#tbleName tbody tr').eq(0).text();
alert(txt1)
});
</script>
Der Wert von txt1 und txt ist im obigen Beispiel gleich. $ (this) = $ ('# tbleName tbody tr') ist der gleiche
Ich habe eine andere Einstellung this
als die anderen Antworten, von denen ich hoffe, dass sie hilfreich sind.
Eine Möglichkeit, JavaScript zu betrachten, besteht darin, festzustellen, dass es nur eine Möglichkeit gibt, eine Funktion 1 aufzurufen . Es ist
functionObject.call(objectForThis, arg0, arg1, arg2, ...);
Es wird immer ein Wert angegeben objectForThis
.
Alles andere ist syntaktischer Zucker für functionObject.call
Alles andere kann also dadurch beschrieben werden, wie es übersetzt wird functionObject.call
.
Wenn Sie nur eine Funktion aufrufen, this
ist dies das "globale Objekt", das im Browser das Fenster ist
function foo() {
console.log(this);
}
foo(); // this is the window object
Mit anderen Worten,
foo();
wurde effektiv übersetzt in
foo.call(window);
Beachten Sie, dass, wenn Sie den strengen Modus verwenden this
, dies der Fall istundefined
'use strict';
function foo() {
console.log(this);
}
foo(); // this is the window object
was bedeutet
Mit anderen Worten,
foo();
wurde effektiv übersetzt in
foo.call(undefined);
In JavaScript gibt es Operatoren wie +
und -
und *
. Es gibt auch den Punktoperator.
Der .
Operator bedeutet, wenn er mit einer Funktion auf der rechten Seite und einem Objekt auf der linken Seite verwendet wird, effektiv "Objekt als this
Funktion übergeben".
Beispiel
const bar = {
name: 'bar',
foo() {
console.log(this);
},
};
bar.foo(); // this is bar
Mit anderen Worten bar.foo()
übersetzt inconst temp = bar.foo; temp.call(bar);
Beachten Sie, dass es keine Rolle spielt, wie die Funktion erstellt wurde (meistens ...). All dies führt zu den gleichen Ergebnissen
const bar = {
name: 'bar',
fn1() { console.log(this); },
fn2: function() { console.log(this); },
fn3: otherFunction,
};
function otherFunction() { console.log(this) };
bar.fn1(); // this is bar
bar.fn2(); // this is bar
bar.fn3(); // this is bar
Auch dies sind alles nur syntaktische Zucker für
{ const temp = bar.fn1; temp.call(bar); }
{ const temp = bar.fn2; temp.call(bar); }
{ const temp = bar.fn3; temp.call(bar); }
Eine weitere Falte ist die Prototypenkette. Wenn Sie a.b
JavaScript verwenden, wird zuerst das Objekt überprüft, auf das direkt a
für die Eigenschaft verwiesen wird b
. Wenn b
das Objekt nicht gefunden wird, sucht JavaScript im zu suchenden Prototyp des Objekts b
.
Es gibt verschiedene Möglichkeiten, den Prototyp eines Objekts zu definieren. Das häufigste im Jahr 2019 ist das class
Schlüsselwort. Für die Zwecke, this
obwohl es keine Rolle spielt. Was zählt, ist, dass, wenn es im Objekt a
nach Eigenschaften sucht, b
wenn es Eigenschaften b
auf dem Objekt findet, oder in seiner Prototypkette, wenn b
es eine Funktion ist, die gleichen Regeln wie oben gelten. Die Funktionsreferenzen b
werden mit der call
Methode aufgerufen und a
als objectForThis übergeben, wie oben in dieser Antwort gezeigt.
Jetzt. Stellen wir uns vor, wir erstellen eine Funktion, die explizit festgelegt wird, this
bevor eine andere Funktion aufgerufen wird, und rufen sie dann mit dem .
Operator (Punkt) auf
function foo() {
console.log(this);
}
function bar() {
const objectForThis = {name: 'moo'}
foo.call(objectForThis); // explicitly passing objectForThis
}
const obj = {
bar,
};
obj.bar();
Im Anschluss an die Übersetzung Gebrauch call
, obj.bar()
wird const temp = obj.bar; temp.call(obj);
. Wenn wir die bar
Funktion eingeben, die wir aufrufen, foo
aber explizit ein anderes Objekt für objectForThis übergeben haben. Wenn wir also bei foo ankommen, this
ist dies das innere Objekt.
Dies ist, was beide bind
und =>
Funktionen effektiv tun. Sie sind mehr syntaktischer Zucker. Sie erstellen effektiv eine neue unsichtbare Funktion genau wie bar
oben, die explizit festgelegt wird, this
bevor die angegebene Funktion aufgerufen wird. Im Falle von bind this
wird auf alles gesetzt, an das Sie übergeben bind
.
function foo() {
console.log(this);
}
const bar = foo.bind({name: 'moo'});
// bind created a new invisible function that calls foo with the bound object.
bar();
// the objectForThis we are passing to bar here is ignored because
// the invisible function that bind created will call foo with with
// the object we bound above
bar.call({name: 'other'});
Beachten Sie, dass functionObject.bind
wir , wenn es nicht existiert, unsere eigenen so machen könnten
function bind(fn, objectForThis) {
return function(...args) {
return fn.call(objectForthis, ...args);
};
}
und dann könnten wir es so nennen
function foo() {
console.log(this);
}
const bar = bind(foo, {name:'abc'});
Pfeilfunktionen, der =>
Operator sind syntaktischer Zucker zum Binden
const a = () => {console.log(this)};
ist das gleiche wie
const tempFn = function() {console.log(this)};
const a = tempFn.bind(this);
Ebenso bind
wird eine neue unsichtbare Funktion erstellt, die die angegebene Funktion mit einem gebundenen Wert aufruft, für den objectForThis
jedoch im Gegensatz zu bind
dem zu bindenden Objekt implizit ist. Es ist alles this
, was gerade passiert, wenn der =>
Operator verwendet wird.
Also, genau wie die obigen Regeln
const a = () => { console.log(this); } // this is the global object
'use strict';
const a = () => { console.log(this); } // this is undefined
function foo() {
return () => { console.log(this); }
}
const obj = {
foo,
};
const b = obj.foo();
b();
obj.foo()
übersetzt const temp = obj.foo; temp.call(obj);
wodurch der Pfeil Operator innerhalb foo
binden obj
an eine neue unsichtbare Funktion und dass neue unsichtbare Funktion zurück , die zugewiesen ist b
. b()
funktioniert wie immer als b.call(window)
oder b.call(undefined)
ruft die neue unsichtbare Funktion auf, die foo
erstellt wurde. Diese unsichtbare Funktion ignoriert das this
übergebene und wird obj
als objectForThis` an die Pfeilfunktion übergeben.
Der obige Code übersetzt in
function foo() {
function tempFn() {
console.log(this);
}
return tempFn.bind(this);
}
const obj = {
foo,
};
const b = obj.foo();
b.call(window or undefined if strict mode);
1apply
ist eine andere ähnliche Funktion wiecall
functionName.apply(objectForThis, arrayOfArgs);
Ab ES6 können Sie dies jedoch konzeptionell sogar in übersetzen
functionName.call(objectForThis, ...arrayOfArgs);
Zusammenfassung this
Javascript:
- Der Wert von
this
wird dadurch bestimmt, wie die Funktion nicht aufgerufen wird, wo sie erstellt wurde! - Normalerweise wird der Wert von
this
durch das Objekt bestimmt, das vom Punkt übrig bleibt. (window
im globalen Raum) - In Ereignis-Listenern
this
bezieht sich der Wert von auf das DOM-Element, für das das Ereignis aufgerufen wurde. - Wenn in function mit dem
new
Schlüsselwort aufgerufen wird,this
bezieht sich der Wert von auf das neu erstellte Objekt - Sie können den Wert der Manipulation
this
mit den Funktionen:call
,apply
,bind
Beispiel:
let object = {
prop1: function () {console.log(this);}
}
object.prop1(); // object is left of the dot, thus this is object
const myFunction = object.prop1 // We store the function in the variable myFunction
myFunction(); // Here we are in the global space
// myFunction is a property on the global object
// Therefore it logs the window object
Beispiel für Ereignis-Listener:
document.querySelector('.foo').addEventListener('click', function () {
console.log(this); // This refers to the DOM element the eventListener was invoked from
})
document.querySelector('.foo').addEventListener('click', () => {
console.log(this); // Tip, es6 arrow function don't have their own binding to the this v
}) // Therefore this will log the global object
.foo:hover {
color: red;
cursor: pointer;
}
<div class="foo">click me</div>
Beispielkonstruktor:
function Person (name) {
this.name = name;
}
const me = new Person('Willem');
// When using the new keyword the this in the constructor function will refer to the newly created object
console.log(me.name);
// Therefore, the name property was placed on the object created with new keyword.
Um "dies" richtig zu verstehen, muss man den Kontext, den Umfang und den Unterschied zwischen ihnen verstehen.
Geltungsbereich : In Javascript bezieht sich der Geltungsbereich auf die Sichtbarkeit der Variablen. Der Geltungsbereich wird durch die Verwendung der Funktion erreicht. (Lesen Sie mehr über den Umfang)
Kontext : Der Kontext bezieht sich auf Objekte. Es bezieht sich auf das Objekt, zu dem eine Funktion gehört. Wenn Sie das JavaScript-Schlüsselwort "this" verwenden, bezieht es sich auf das Objekt, zu dem die Funktion gehört. Wenn Sie beispielsweise innerhalb einer Funktion sagen: "this.accoutNumber", beziehen Sie sich auf die Eigenschaft "accoutNumber", die zu dem Objekt gehört, zu dem diese Funktion gehört.
Wenn das Objekt "myObj" eine Methode namens "getMyName" hat und das JavaScript-Schlüsselwort "this" in "getMyName" verwendet wird, verweist es auf "myObj". Wenn die Funktion "getMyName" im globalen Bereich ausgeführt wurde, bezieht sich "this" auf das Fensterobjekt (außer im strengen Modus).
Nun sehen wir uns ein Beispiel an:
<script>
console.log('What is this: '+this);
console.log(this);
</script>
Wenn Sie den Code in der Browserausgabe ausführen, wird Folgendes ausgeführt:
Entsprechend der Ausgabe, die Sie sich im Kontext des Fensterobjekts befinden, ist auch sichtbar, dass sich der Fensterprototyp auf das Objekt bezieht.
Versuchen wir es nun innerhalb einer Funktion:
<script>
function myFunc(){
console.log('What is this: '+this);
console.log(this);
}
myFunc();
</script>
Ausgabe:
Jetzt erstellen wir unser eigenes Objekt. In Javascript können Sie ein Objekt auf viele Arten erstellen.
<script>
var firstName = "Nora";
var lastName = "Zaman";
var myObj = {
firstName:"Lord",
lastName:'Baron',
printNameGetContext:function(){
console.log(firstName + " "+lastName);
console.log(this.firstName +" "+this.lastName);
return this;
}
}
var context = myObj.printNameGetContext();
console.log(context);
</script>
Ausgabe:
Aus dem obigen Beispiel haben wir herausgefunden, dass sich das Schlüsselwort 'this' auf einen neuen Kontext bezieht, der mit myObj zusammenhängt, und myObject hat auch eine Prototypkette zu Object.
Lassen Sie uns ein weiteres Beispiel werfen:
<body>
<button class="btn">Click Me</button>
<script>
function printMe(){
//Terminal2: this function declared inside window context so this function belongs to the window object.
console.log(this);
}
document.querySelector('.btn').addEventListener('click', function(){
//Terminal1: button context, this callback function belongs to DOM element
console.log(this);
printMe();
})
</script>
</body>
Ausgabe: Sinn machen, oder? (Kommentare lesen)
Wenn Sie Probleme haben, das obige Beispiel zu verstehen, versuchen wir es mit unserem eigenen Rückruf.
<script>
var myObj = {
firstName:"Lord",
lastName:'Baron',
printName:function(callback1, callback2){
//Attaching callback1 with this myObj context
this.callback1 = callback1;
this.callback1(this.firstName +" "+this.lastName)
//We did not attached callback2 with myObj so, it's reamin with window context by default
callback2();
/*
//test bellow codes
this.callback2 = callback2;
this.callback2();
*/
}
}
var callback2 = function (){
console.log(this);
}
myObj.printName(function(data){
console.log(data);
console.log(this);
}, callback2);
</script>
Ausgabe:
Lassen Sie uns nun Scope, Self, IIFE und DIESES Verhalten verstehen
var color = 'red'; // property of window
var obj = {
color:'blue', // property of window
printColor: function(){ // property of obj, attached with obj
var self = this;
console.log('In printColor -- this.color: '+this.color);
console.log('In printColor -- self.color: '+self.color);
(function(){ // decleard inside of printColor but not property of object, it will executed on window context.
console.log(this)
console.log('In IIFE -- this.color: '+this.color);
console.log('In IIFE -- self.color: '+self.color);
})();
function nestedFunc(){// decleard inside of printColor but not property of object, it will executed on window context.
console.log('nested fun -- this.color: '+this.color);
console.log('nested fun -- self.color: '+self.color);
}
nestedFunc(); // executed on window context
return nestedFunc;
}
};
obj.printColor()(); // returned function executed on window context
</script>
Die Ausgabe ist ziemlich großartig, oder?