Wartość słowa kluczowego `this` funkcji zwróconej z gettera


15

W poniższym przykładzie znalazłem nieoczekiwaną wartość tego słowa kluczowego:

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


x.func1(x)

Wartością tego słowa kluczowego jest obiekt x, tak jakby został wykonany z tego obiektu, oczekuję, że tylko funkcja get, która ma to słowo kluczowe, jest równa obiektowi wywołującemu x

ten przykład pokazuje nam różnicę

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

x.func2()(x);

W obu przykładach func1, która jest funkcją gettera, i func2, która jest metodą obiektu, są wykonywane z obiektu x , a następnie zwracana funkcja jest wykonywana. Dlaczego więc ta wartość w pierwszym przykładzie nie jest równa obiektowi globalnemu zamiast obiektowi x .


3
Naprawdę bardzo interesujące pytanie. Nigdy wcześniej nie myślałam o tej zmarszczce.
TJ Crowder

1
Jakby to wykonany z tego obiektu ” - ale to jest wykonywane na tym obiekcie, tam: x.func1().
Bergi

Odpowiedzi:


13

To bardzo interesujące pytanie.

Jest tak, ponieważ funkcja jest wywoływana natychmiast po uzyskaniu dostępu do właściwości. Są to zasadniczo równoważne:

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

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

W obu przypadkach:

  1. Wartość właściwości jest odczytywana, co powoduje odwołanie do funkcji.
  2. Ta funkcja jest wykonywana jako część tego samego wyrażenia dostępu do właściwości.

Fakt, że func1jest to właściwość akcesorium i func2właściwość danych, nie ma znaczenia. Liczy się sposób, w jaki używana jest wartość wynikająca z odczytu właściwości.


1
Myślałem, że całe wyrażenie zostanie ocenione do obiektu funkcji, a następnie wykonane. Dzięki,
rozumiem

1
@KirollosNasr Tak, tak, ale w wyrażeniu x.func1zachowuje odniesienie xjako kontekst dla następnego wywołania, w przeciwieństwie do x.func2()(z twojego pytania), które ocenia również funkcję, ale nie jest wyrażeniem dostępu do członka.
Bergi

1
@Bergi - Myślę, że miałeś na myśli x.func2()(x);?
TJ Crowder

1
@TJCrowder Tak, odnoszę się do wyrażeń wewnątrz x.func1(x)ix.func2()(x)
Bergi

1
@Bergi tak, ma trudną część. Ale teraz jest bardziej jasne Dzięki TJ Crowder i tobie
Kirollos Nasr
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.