Der Wert des Schlüsselworts `this` einer Funktion, die von einem Getter zurückgegeben wurde


15

Ich habe im folgenden Beispiel einen unerwarteten Wert dieses Schlüsselworts gefunden:

let x = {
    z : 10 ,
    get func1() {
        return function(v) {
            console.log(this === v);
        }
    }
}


x.func1(x)

Der Wert dieses Schlüsselworts ist das Objekt x, als ob es von diesem Objekt ausgeführt wird. Ich erwarte nur die Funktion get , die es gibt dieses Schlüsselwort hat, dem aufrufenden Objekt x entspricht

Dieses Beispiel zeigt uns den Unterschied

let x = {
    func2() {
        return function(v) {
            console.log(this === v);
        }
    }
}

x.func2()(x);

In beiden Beispielen werden func1, die die Getter-Funktion ist, und func2, die eine Methode des Objekts ist, vom Objekt x ausgeführt , und die zurückgegebene Funktion wird dann ausgeführt. Warum entspricht dieser Wert im ersten Beispiel nicht dem globalen Objekt anstelle des Objekts x ?


3
Wirklich sehr, sehr interessante Frage. Ich hätte noch nie an diese Falte gedacht.
TJ Crowder

1
" als ob es von diesem Objekt ausgeführt wird " - aber es wird für dieses Objekt ausgeführt, genau dort : x.func1().
Bergi

Antworten:


13

Das ist ein sehr interessante Frage.

Dies liegt daran, dass die Funktion sofort nach dem Ergebnis eines Eigenschaftszugriffs aufgerufen wird. Diese sind also grundsätzlich gleichwertig:

let x = {
    get func1() {
        return function(v) {
            console.log(this === v);
        };
    },
    func2(v) {
        console.log(this === v);
    }
};

x.func1(x);
x.func2(x);

In beiden Fällen:

  1. Der Wert der Eigenschaft wird gelesen, was zu einer Funktionsreferenz führt.
  2. Diese Funktion wird als Teil desselben Eigenschaftszugriffsausdrucks ausgeführt.

Die Tatsache, dass func1es sich um eine Accessor-Eigenschaft und func2eine Dateneigenschaft handelt, spielt keine Rolle. Es kommt darauf an, wie der Wert verwendet wird, der sich aus dem Lesen der Eigenschaft ergibt.


1
Ich dachte, dass der gesamte Ausdruck für das Funktionsobjekt ausgewertet und dann ausgeführt wird. Danke, verstanden
Kirollos Nasr

1
@KirollosNasr Ja, das ist es, aber im Ausdruck x.func1wird der Verweis xals Kontext für den nachfolgenden Aufruf beibehalten , im Gegensatz zu x.func2()(aus Ihrer Frage), die ebenfalls eine Funktion auswertet, aber kein Mitgliedszugriffsausdruck ist.
Bergi

1
@Bergi - ich denke du meintest x.func2()(x);?
TJ Crowder

1
@TJCrowder Ja, ich beziehe mich auf die Ausdrücke im Inneren x.func1(x)undx.func2()(x)
Bergi

1
@Bergi Ja, es hat einen schwierigen Teil. Aber jetzt ist es klarer Dank an TJ Crowder und Sie
Kirollos Nasr
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.