Wie funktioniert das Schlüsselwort "this"?

Jun 27 2010

Ich habe festgestellt, dass es anscheinend keine klare Erklärung dafür gibt, was das thisSchlü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 thisund wann sollte es verwendet werden?

Antworten

1378 DanielTrebbien Jun 27 2010 at 20:15

Ich empfehle , zuerst den Artikel Scope von Mike West in JavaScript ( Spiegel ) zu lesen . Es ist eine hervorragende, freundliche Einführung in die Konzepte thisund Umfangsketten von JavaScript.

Sobald Sie sich daran gewöhnt haben, thissind die Regeln eigentlich ziemlich einfach. Der ECMAScript 5.1 Standard definiert this:

§11.1.1 Das thisSchlüsselwort

Das thisSchlü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 ( objim 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, thisArgdie 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.prototypeFunktionen werden sie für ein Funktionsobjekt aufgerufen, aber anstatt ThisBinding auf das Funktionsobjekt zu setzen, wird ThisBinding auf das gesetzt thisArg.

Bei den Array.prototypeFunktionen wird das callbackfnAngegebene in einem Ausführungskontext aufgerufen, in dem ThisBinding auf gesetzt ist, thisArgfalls 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 thisauf Bibliotheksfunktionen verweisen, sollten Sie in der Dokumentation nach Garantien suchen, welchen Wert der Wert thisbeim 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 newOperator 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 thisdas 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 Pfeilfunktion this... auf die Werte thisin 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.

  1. Was ist der Wert thisan der markierten Linie? Warum?

window - Die markierte Zeile wird im anfänglichen globalen Ausführungskontext ausgewertet.

    if (true) {
        // What is `this` here?
    }
  1. Was ist der Wert thisin der markierten Zeile, wenn obj.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);
  

  1. Was ist der Wert thisan der markierten Linie? Warum?

window

In diesem Beispiel gibt der JavaScript-Interpreter Funktionscode ein. Da myFun/ obj.myMethodjedoch für ein Objekt nicht aufgerufen wird, wird ThisBinding auf gesetzt window.

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);
  

  1. Was ist der Wert thisan der markierten Linie? Warum?

window

Dieser war schwierig. Bei der Auswertung des Eval-Codes thisist obj. Im Eval-Code wird myFunjedoch kein Objekt aufgerufen, sodass ThisBinding windowfü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()");
        }
    };
  1. Was ist der Wert thisan der markierten Linie? Warum?

obj

Die Zeile myFun.call(obj);ruft die spezielle integrierte Funktion auf Function.prototype.call(), die thisArgals 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);
  

168 Mahesha999 Jul 08 2013 at 00:32

Das thisSchlüsselwort verhält sich in JavaScript anders als in anderen Sprachen. In objektorientierten Sprachen thisbezieht sich das Schlüsselwort auf die aktuelle Instanz der Klasse. In JavaScript wird der Wert von thisdurch den Aufrufkontext von function ( context.function()) bestimmt und wo er aufgerufen wird.

1. Bei Verwendung im globalen Kontext

Wenn Sie thisim globalen Kontext verwenden, ist es an ein globales Objekt gebunden ( windowim Browser).

document.write(this);  //[object Window]

Wenn Sie thisinnerhalb einer im globalen Kontext definierten Funktion verwenden, thisist 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 f1ist eine Methode des globalen Objekts gemacht. Daher können wir es auf windowObjekt auch wie folgt aufrufen :

function f()
{
    return this;
}

document.write(window.f()); //[object Window]

2. Bei Verwendung innerhalb der Objektmethode

Wenn Sie ein thisSchlüsselwort in einer Objektmethode verwenden, thiswird 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, thises 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, thisdh 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 thisInside-Funktion verwenden, die ohne Kontext aufgerufen wird (dh nicht für ein Objekt), ist sie an das globale Objekt ( windowim 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 newOperator 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 thishö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 newSchlüsselwort aufgerufen wird ), zeigt der thisFunktionskö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, thisbezieht 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 thisverwendet 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])Legt obj1den Wert von thisinside fest fun()und ruft fun()übergebende Elemente von argsArrayals Argumente auf.
  • fun.call(obj1 [, arg1 [, arg2 [,arg3 [, ...]]]])- Sets obj1als der Wert von thisinnen fun()und Anrufen fun()vorbei arg1, arg2, arg3, ...als Argumente.
  • fun.bind(obj1 [, arg1 [, arg2 [,arg3 [, ...]]]])- Gibt den Verweis auf die Funktion zurück, funwobei der thisinnere Spaß an obj1und die Parameter funan die angegebenen Parameter gebunden sind arg1, arg2, arg3,....
  • Inzwischen ist der Unterschied zwischen apply, callund bindmüssen offensichtlich geworden sind. applyErmöglicht die Angabe der Argumente, die als Array-ähnliches Objekt fungieren sollen, dh ein Objekt mit einer numerischen lengthEigenschaft und entsprechenden nicht negativen ganzzahligen Eigenschaften. Während callermöglicht direkt die Argumente der Funktion zu spezifizieren. Beide applyund callrufen sofort die Funktion im angegebenen Kontext und mit den angegebenen Argumenten auf. Gibt andererseits bindeinfach die an den angegebenen thisWert 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. thisInside Event Handler

  • Wenn Sie den Ereignishandlern eines Elements eine Funktion direkt zuweisen, thisbezieht sich die Verwendung der Funktion zur direkten Behandlung innerhalb des Ereignisses auf das entsprechende Element. Eine solche direkte Funktionszuweisung kann unter Verwendung einer addeventListenerMethode oder durch herkömmliche Ereignisregistrierungsmethoden wie erfolgen onclick.
  • Wenn Sie thisdirekt innerhalb der Ereigniseigenschaft (wie <button onclick="...this..." >) des Elements verwenden, bezieht sich dies auf das Element.
  • Die Verwendung von thisindirekt über die andere Funktion, die innerhalb der Ereignisbehandlungsfunktion oder der Ereigniseigenschaft aufgerufen wird, wird jedoch in das globale Objekt aufgelöst window.
  • 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. thisin der ES6-Pfeilfunktion

In einer Pfeilfunktion thisverhä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 
66 user3459110 Oct 26 2014 at 22:07

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 thisals protokolliert window. Dies liegt daran, dass windowes sich um die globale Variable im Bereich eines Webbrowsers handelt.

Wenn Sie denselben Code in einer Umgebung wie node.js ausführen, wird thisauf 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 , thiswird in keiner der Umgebungen mehr auf die globale Variable verwiesen. Dies geschieht, um Verwirrungen im strengen Modus zu vermeiden. thiswü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 forEachund aufgerufen haben slice, sollten Sie bereits wissen, dass sich die thisVariable in diesem Fall auf die bezieht, Objectauf die Sie diese Funktion aufgerufen haben (Beachten Sie, dass in Javascript fast alles ein ist Object, einschließlich Arrays und Functions). 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 Objecteine Eigenschaft enthält, die a enthält Function, wird die Eigenschaft als Methode bezeichnet. Wenn diese Methode aufgerufen wird, wird ihre thisVariable immer auf die Variable gesetzt, der Objectsie 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 thisin 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 newSchlü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 newSchlüsselwort verwenden.

  1. Das Aufrufen der Funktion mit dem newSchlüsselwort würde sofort einen ObjectTyp initialisieren Person.
  2. Der Konstruktor hierfür Objecthat seinen Konstruktor auf gesetzt Person. Beachten Sie auch, dass typeof awalzurückkehren würde Objectnur.
  3. Diesem neuen Objectwürde der Prototyp von zugewiesen Person.prototype. Dies bedeutet, dass jede Methode oder Eigenschaft im PersonPrototyp für alle Instanzen von verfügbar ist Person, einschließlich awal.
  4. Die Funktion Personselbst wird jetzt aufgerufen. thisein Verweis 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 constructorFunktionen sind. Sie sind nur normale Funktionen und newkö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: callundapply

Also ja, da functions 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 callund apply, und beide können verwendet werden, um den Wert von thisin 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 thisin der Funktion fooals Referenz auf thisArg. Alle anderen übergebenen Parameter callwerden fooals 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 thisin einer beliebigen Funktion zu ändern .

applyist fast dasselbe wie zu callakzeptieren, dass nur zwei Parameter benötigt werden: thisArgund ein Array, das die Argumente enthält, die an die Funktion übergeben werden sollen. Der obige callAufruf kann also folgendermaßen übersetzt werden apply:

foo.apply(thisArg, [1,2,3])

Beachten Sie, dass callund applyden Wert des Aufrufs von thisset by dot method überschreiben kann, den wir im zweiten Aufzählungszeichen besprochen haben. Einfach genug :)

Präsentieren .... bind!

bindist ein Bruder von callund apply. Es ist auch eine Methode, die von allen Funktionen des globalen FunctionKonstruktors in Javascript geerbt wird . Der Unterschied zwischen bindund call/ applybesteht darin, dass beide callund applydie Funktion tatsächlich aufrufen. bindGibt andererseits eine neue Funktion mit der Voreinstellung thisArgund 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 callund apply, bindwird auch den Wert der Überfahrt thisSatz von Punkt-Methodenaufruf.

Beachten Sie auch, dass keine dieser drei Funktionen Änderungen an der ursprünglichen Funktion vornimmt. callund applywürde den Wert von frisch konstruierten Funktionen zurückgeben, während binddie 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 thismit dem verschachtelten Bereich geändert hat, aber wir wollten den Wert von thisvom ursprünglichen Bereich. Also wir ‚kopiert‘ thisauf thatund verwendet kopieren die statt this. Clever, was?

Index:

  1. Was ist thisstandardmäßig enthalten?
  2. Was ist, wenn wir die Funktion als Methode mit Objekt-Punkt-Notation aufrufen?
  3. Was ist, wenn wir das newSchlüsselwort verwenden?
  4. Wie manipulieren wir thismit callund apply?
  5. Verwenden von bind.
  6. Kopieren, thisum Probleme mit verschachtelten Bereichen zu lösen.
49 arunjitsingh Jun 27 2010 at 21:10

"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

18 carlodurso Oct 30 2014 at 10:58

Da dieser Thread aufgetaucht ist, habe ich einige Punkte für Leser zusammengestellt, die neu im thisThema sind.

Wie wird der Wert von thisbestimmt?

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 windowObjekt definiert . Daher thisbezieht sich eine globale Funktion auf das globale windowObjekt (und hat dessen Wert) .

Wenn use strict, thisdie gebunden sind , nicht auf jedes Objekt in der globalen und in anonymen Funktionen enthält einen Wert von undefined.

Das thisSchlüsselwort wird am meisten missverstanden, wenn: 1) wir eine verwendete Methode ausleihen this, 2) thiseiner Variablen eine verwendete Methode zuweisen , 3) eine verwendete Funktion thisals Rückruffunktion übergeben wird und 4) thisinnerhalb eines Abschlusses verwendet wird - eine innere Funktion. (2)

Was hält die Zukunft

In ECMA Script 6 definiert , übernehmen Pfeilfunktionen die thisBindung 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 thisMechanismus zugunsten eines allgemeineren lexikalischen Geltungsbereichs deaktivieren . (1)


Verweise:

  1. this & Object Prototypes von Kyle Simpson. © 2014 Getify Solutions.
  2. javascriptissexy.com - http://goo.gl/pvl0GX
  3. Angus Croll - http://goo.gl/Z2RacU
18 Seph Oct 07 2013 at 02:46

thisbezieht 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;

thiswü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 thiswird auf das Fensterobjekt verwiesen.

15 blockhead Jun 27 2010 at 20:15

Jeder Ausführungskontext in Javascript hat diesen Parameter, der festgelegt wird durch:

  1. Wie die Funktion aufgerufen wird (einschließlich als Objektmethode, Verwendung von Aufruf und Anwendung , Verwendung von Neu )
  2. Verwendung von binden
  3. Lexikalisch für Pfeilfunktionen (sie übernehmen das Dies ihres äußeren Ausführungskontexts)
  4. Gibt an, ob sich der Code im strengen oder im nicht strengen Modus befindet
  5. Ob der Code mit aufgerufen wurde eval

Sie können den Wert festgelegt dies mit func.call, func.applyoder 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.

11 ArmanMcHitarian Apr 23 2013 at 19:57

Daniel, tolle Erklärung! Ein paar Worte dazu und eine gute Liste von thisAusführungskontextzeigern bei Ereignishandlern.

Mit zwei Worten, thisin 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)">
11 zangw Nov 29 2015 at 13:01

Hier ist eine gute Quelle von thisin JavaScript.

Hier ist die Zusammenfassung:

  • global dies

    In einem Browser ist im globalen Bereich thisdas windowObjekt

    <script type="text/javascript">
      console.log(this === window); // true
      var foo = "bar";
      console.log(this.foo); // "bar"
      console.log(window.foo); // "bar"
    

    Bei der nodeVerwendung der Antwort thisist dies der oberste Namespace. Sie können es als bezeichnen global.

    >this
      { ArrayBuffer: [Function: ArrayBuffer],
        Int8Array: { [Function: Int8Array] BYTES_PER_ELEMENT: 1 },
        Uint8Array: { [Function: Uint8Array] BYTES_PER_ELEMENT: 1 },
        ...
    >global === this
     true
    

    Bei der nodeAusführung von einem Skript aus thisbeginnt 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 thisArgbereitgestellt wird (siehe weiter unten), verwenden sowohl im Knoten als auch in einem Browser thisin einer Funktion, die nicht mit newVerweisen 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 thisseinundefined

<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 newder thises 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 prototypeEigenschaft, der Sie Werte zuweisen können. Wenn Sie eine Instanz erstellen, indem Sie Ihre Funktion mit aufrufen, erhalten newSie Zugriff auf die Werte, die Sie der prototypeEigenschaft 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 thisin 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 thiswird 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 bindden 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, thisbefindet 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, evalum 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 withhinzufügen this, thisohne thisexplizit 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 thisauf 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>
9 ArupHore Jan 31 2017 at 15:29

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:

  1. Global (dh außerhalb aller Funktionen)
  2. Inside Direct-Aufruf "Non Bound Function" (dh eine Funktion, die nicht durch Aufrufen von functionName.bind gebunden wurde )
  3. Inside Indirect "Non Bound Function" Aufruf über functionName.call und functionName.apply
  4. Innerhalb des Aufrufs "Gebundene Funktion" (dh eine Funktion, die durch Aufrufen von functionName.bind gebunden wurde )
  5. Während der Objekterstellung durch "neu"
  6. Inside Inline DOM-Ereignishandler

Im Folgenden wird jeder dieser Kontexte einzeln beschrieben:

  1. 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.

  2. 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.

  3. 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 .

  4. 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.

  5. 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.

  6. 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

  1. Im globalen Kontext bezieht sich "dies" immer auf das "Fenster" -Objekt

  2. 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.

  3. Der Wert von "this" innerhalb einer nicht gebundenen Funktion ist die Referenz auf ein Objekt, in dessen Kontext die Funktion aufgerufen wird ( "aktuelles Objekt" ).

  4. Der Wert von "this" innerhalb einer nicht gebundenen Funktion kann durch Aufrufen und Anwenden von Methoden der Funktion überschrieben werden .

  5. Der Wert von "this" ist für eine gebundene Funktion festgelegt und kann nicht durch Aufrufen und Anwenden von Methoden der Funktion überschrieben werden .

  6. 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.

  7. Der Wert von "this" innerhalb eines Konstruktors ist das Objekt, das erstellt und initialisiert wird

  8. Der Wert "this" in einem Inline-DOM-Ereignishandler bezieht sich auf das Element, für das der Ereignishandler angegeben ist.

9 DmitriPavlutin Nov 08 2016 at 19:17

Der wahrscheinlich ausführlichste und umfassendste Artikel thisist der folgende:

Schonende Erklärung dieses Schlüsselworts in JavaScript

Die Idee dahinter thisist zu verstehen, dass die Funktionsaufruftypen die signifikante Bedeutung für die Einstellung des thisWerts haben.


Wenn mit Schwierigkeiten zu identifizieren this, nicht sich fragen:

Woher kommt thises ?

aber Sie fragen Sie sich:

Wie wird die Funktion aufgerufen ?

Für eine Pfeilfunktion (Sonderfall der Kontexttransparenz) fragen Sie sich:

Welchen Wert hat thiswo die Pfeilfunktion definiert ist ?

Diese Einstellung ist richtig im Umgang mit thisund erspart Ihnen Kopfschmerzen.

7 JamesDrinkard Jul 13 2016 at 02:03

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:

  1. Wenn wir ein Verfahren (das verwendet passieren diese ) als Argument als Callback - Funktion verwendet werden.
  2. 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.
  3. 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.
  4. 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.

6 Nipuna Aug 09 2014 at 16:22

thisist eines der missverstandenen Konzepte in JavaScript, da es sich von Ort zu Ort kaum anders verhält. thisBezieht sich einfach auf den "Eigentümer" der Funktion, die wir gerade ausführen .

thishilft 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 thisist

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 thisunterschieden 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 thisauf 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. Personwird aufgerufen und thisso 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 newSchlüsselwort vermissen , whatIsThisverweist es auf den globalsten Kontext, den es finden kann ( window)

Mit Event-Handlern

Wenn der Ereignishandler inline ist, thisbezieht 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>

thisBezieht 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 ?
6 mrmaclean89 Sep 17 2017 at 05:11

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;
5 Trombe Jul 03 2017 at 17:07

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.

4 SimonGroenewolt Jun 27 2010 at 20:15

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.)

3 unclexo Jul 25 2018 at 14:04

Ein paar Infos zu diesem Keyword

Lassen Sie uns das thisSchlü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, exportsist nur ein Hinweis aufmodule.exports

1 PRADEEPSINGHChundawat Apr 06 2016 at 14:15

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

1 gman Jan 29 2019 at 01:37

Ich habe eine andere Einstellung thisals 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, thisist 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 thisFunktion ü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.bJavaScript verwenden, wird zuerst das Objekt überprüft, auf das direkt afür die Eigenschaft verwiesen wird b. Wenn bdas 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 classSchlüsselwort. Für die Zwecke, thisobwohl es keine Rolle spielt. Was zählt, ist, dass, wenn es im Objekt anach Eigenschaften sucht, bwenn es Eigenschaften bauf dem Objekt findet, oder in seiner Prototypkette, wenn bes eine Funktion ist, die gleichen Regeln wie oben gelten. Die Funktionsreferenzen bwerden mit der callMethode aufgerufen und aals objectForThis übergeben, wie oben in dieser Antwort gezeigt.

Jetzt. Stellen wir uns vor, wir erstellen eine Funktion, die explizit festgelegt wird, thisbevor 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 barFunktion eingeben, die wir aufrufen, fooaber explizit ein anderes Objekt für objectForThis übergeben haben. Wenn wir also bei foo ankommen, thisist dies das innere Objekt.

Dies ist, was beide bindund =>Funktionen effektiv tun. Sie sind mehr syntaktischer Zucker. Sie erstellen effektiv eine neue unsichtbare Funktion genau wie baroben, die explizit festgelegt wird, thisbevor die angegebene Funktion aufgerufen wird. Im Falle von bind thiswird 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.bindwir , 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 bindwird eine neue unsichtbare Funktion erstellt, die die angegebene Funktion mit einem gebundenen Wert aufruft, für den objectForThisjedoch im Gegensatz zu binddem 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 foobinden objan 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 fooerstellt wurde. Diese unsichtbare Funktion ignoriert das thisübergebene und wird objals 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);
WillemvanderVeen Aug 22 2018 at 00:12

Zusammenfassung thisJavascript:

  • Der Wert von thiswird dadurch bestimmt, wie die Funktion nicht aufgerufen wird, wo sie erstellt wurde!
  • Normalerweise wird der Wert von thisdurch das Objekt bestimmt, das vom Punkt übrig bleibt. ( windowim globalen Raum)
  • In Ereignis-Listenern thisbezieht sich der Wert von auf das DOM-Element, für das das Ereignis aufgerufen wurde.
  • Wenn in function mit dem newSchlüsselwort aufgerufen wird, thisbezieht sich der Wert von auf das neu erstellte Objekt
  • Sie können den Wert der Manipulation thismit 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.

Lord May 20 2020 at 16:43

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:

Die Ausgabe ist dieselbe, da wir diese Variable im globalen Bereich und im Funktionsbereich protokolliert haben. Wir haben den Kontext nicht geändert. In beiden Fällen war der Kontext in Bezug auf das Witwenobjekt derselbe .

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?