Alıcıdan döndürülen bir işlevin `this` anahtar sözcüğünün değeri


15

Aşağıdaki örnekte bu anahtar kelimenin beklenmeyen bir değerini buldum :

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


x.func1(x)

Değeri bu anahtar kelime nesnesidir x o nesneden yürütüldüğünde sanki sadece bekliyoruz alma yönteminin sahip bu anahtar kelimeyi arayarak nesne eşittir x

bu örnek bize farkı gösterir

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

x.func2()(x);

Her iki örnek de func1 alıcı fonksiyonu ve FUNC2 nesnesinin bir yöntem olup, nesne ile ilgili yürütülür x ve geri fonksiyonu daha sonra yürütülür. Öyleyse neden ilk örnekte bu değer x nesnesi yerine global nesneye eşit değildir .


3
Gerçekten, gerçekten ilginç bir soru. Bu kırışıklığı daha önce hiç düşünmemiştim.
TJ Crowder

1
" O nesneden yürütüldüğünde sanki " - ama edilmektedir orada, o nesne üzerinde yürütülen: x.func1().
Bergi

Yanıtlar:


13

Bu çok ilginç bir soru.

Bunun nedeni, bir özellik erişimi sonucunda işlevin hemen çağrılmasıdır. Yani bunlar temelde eşdeğerdir:

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

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

Her iki durumda da:

  1. Özelliğin değeri okunur, bu da işlev başvurusu ile sonuçlanır.
  2. Bu işlev, aynı özellik erişim ifadesinin bir parçası olarak yürütülür.

Aslında func1bir erişimci özelliktir ve func2önemli değildir, bir veri özelliktir. Özelliğin okunmasından kaynaklanan değer bu şekilde kullanılır.


1
Tüm ifadenin işlev nesnesine değerlendirileceğini ve sonra yürütüleceğini düşündüm. Teşekkürler anladım
Kirollos Nasr

1
@KirollosNasr Evet, öyle, ancak ifadede , bir işlevi de değerlendiren ancak üye erişim ifadesi olmayan (sorunuzdan) aksine, sonraki çağrının bağlamı olarak x.func1referansı tutar . xx.func2()
Bergi

1
@Bergi - Sanırım demek istediniz x.func2()(x);?
TJ Crowder

1
@TJCrowder Evet, içindeki ifadelere bakıyorum x.func1(x)vex.func2()(x)
Bergi

1
@ Bergi evet zor bir parçası var. Ama şimdi daha açık TJ Crowder ve siz sayesinde
Kirollos Nasr
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.