2016-04-13 38 views
4
function wrap(func) { 
    console.log('0', this) 
    return function x() { 
    console.log('1', this) 
    func() 
    return function z() { 
     console.log('3', this) 
    } 
    } 
} 

var obj = { 
    x: 5, 
    test: wrap(function y() { 
    console.log('2', this) 
    }) 
} 

obj.test()() 

Yukarıdaki kodAşağıdaki kod snippet'inde `this` değerindeki değişiklik için bir açıklama var mı?

// 0 Window 
// 1 Object 
// 2 Window 
// 3 Window 

sorun this değerinin ne olması gerektiğini dikte eden anlamakta yaşıyorum kaydeder.

// 0 Window bu şal ilk çağrıldığında, ve bu noktada değeri thisobj

// 1 Object ayarlı olmamalıdır çünkü mantıklı anlamda obj.test artık düzgün obj

olarak this kaydeder function x(), eşittir yapar

// 2 Window Bunun neden olduğundan emin değilim. Neden this değeri func()'a yayılmaz? this'un işlevin sahibine başvurması gerektiğini düşündüm. Bu, içte function y() yaratılmış olsa bile, bir şekilde pencereye kaldırılmış olduğu anlamına mı geliyor? function z() ile Keza

// 3 Window neden this değeri değil function x() aşağı geçirildi. this'un değeri oralarda çoğaltılmıyor mu?

+0

"func" işlevi "wrap" fonksiyonuna geçtiğinden, "wrap" fonksiyonunda "this" değeri ile aynı değeri alacağına inanıyorum. –

+0

'z' işlevine gelince, global kapsam içinde yürütülür, böylece' this' değerinin 'window' olduğu anlaşılır. –

+3

Yehuda Katz bu konuda oldukça iyi bir blog yazısı yazdı: http://yehudakatz.com/2011/08/11/understanding-javascript-function-invocation-and-this/ –

cevap

0

this arasında çoğunlukla doğru rehberlik eden kural 4. varsayılan (global) davanızı

// 2 Pencere test makale, sırayla, fonksiyon çağrıları için

  • wrap.call(window, function() {})
  • obj.test.call(obj)
  • desugar
  • y.call(window)
  • z.call(window)

akılda tutulması gereken şey thisdeğil işlev bildirimleri yayılması yapmasıdır. this değeri, tamamen çağrılan işleve bağlıdır.

Kafamın karışık olmasının nedeni, sizin için this değerini koruyan, ok işlevlerinde çok fazla kullanılmamın sebebiydi.

function wrap(func) { 
    return() => { 
    console.log(this) 
    return() => { 
     console.log(this) 
     func() 
     return() => console.log(this) 
    } 
    } 
} 

bu

function wrap(func) { 
    var _this = this; 

    return function() { 
    console.log(_this); 
    return function() { 
     console.log(_this); 
     func() 
     return function() { 
     return console.log(_this); 
     }; 
    }; 
    }; 
} 

için desugars ve açıkça this değerini aşağı geçmek zorunda olduğunu göstermektedir. Ok işlevleriyle bile olsa, func numaralı aramanın this değerini koruyamayacağını unutmayın. Bunu yapmak için func.call(this) yapmam gerek.

0

'Bu' bağ çok kafa karıştırıcı. Ancak, aşağıdaki kuralları hatırlarsanız, anlaşılması daha kolay olacaktır. bir yöntem gibi sert

  • açık veya

    1. yeni operatör çağrı yoluyla bağlanması veya içeren nesne ile bağlanma
    2. örtülü yöntemleri uygulanır: 'Bu' bu siparişleri bağlar için JavaScript belgelere göre, dört kurallar vardır
    3. varsayılan (global) bir nesnenin betiklerinizden itibaren

    , sadece kuralları 3. ve 4. hiçbir yeni operatörler olduğundan uygulamak ve arama veya yöntemler uygulanır.

    Yani açıklamalar şunlardır:

    // 0 Pencere - (global) kuralı 4. varsayılan

    // 1 Nesne - örtük 3 Bir nesnenin bir yöntem gibi, nesneyi içeren bağlayıcı kural #, obj.Kural # (global)

    // 3 Pencere 4 varsayılan - -