2012-10-17 23 views
6

Bana neden fn ikinci çağrısının bir hata verdiğini açıklayabilir misiniz? Kod aşağıda. Javascript 'this'

function Test(n) { 
    this.test = n; 

    var bob = function (n) { 
     this.test = n; 
    }; 

    this.fn = function (n) { 
    bob(n); 
    console.log(this.test); 
    }; 
} 

var test = new Test(5); 

test.fn(1); // returns 5 
test.fn(2); // returns TypeError: 'undefined' is not a function 

Burada hata http://jsfiddle.net/KjkQ2/

+5

Her ikisi de benim için '5' yazıyor: http://jsfiddle.net/jEgLM/ –

+1

P.S. Muhtemelen bob.call (bu, n) 'yi istiyorsun. –

+0

jsbin.com'u deneyin – scusyxx

cevap

6

Global kapsamdan bob işleviniz çağrılmaktadır. İlk olarak, this.test, oluşturduğunuz değişkenin üzerine yazan test adlı global bir değişkene işaret ediyor. console.log(window.test)'u çalıştırırsanız, ne olacaksınız. kodunuzu amaçlandığı gibi, sen

// Just use closures instead of relying on this 
function Test(n) { 
    var test = n; 

    var bob = function (n) { 
     test = n; 
    }; 

    this.fn = function (n) { 
    bob(n); 
    console.log(test); 
    }; 
} 
+0

ilk çözümünüz işe yaramaz. 'this',' this.bob() 'gibi çağrıldığında 'window' için referansta bulunuyor; – jAndy

+0

@jAndy Doğru değil, 'test.fn()' olarak adlandırıldı, yani 'test' bağlamdır. Bkz. Http://jsfiddle.net/jEgLM/1/ –

+0

Yay, benim hatam - noktayı gözden kaçırdı. – jAndy

3

.fn içinde bob(n) arayarak yeniden üreten bir JSfiddle, öyle (bir tarayıcıda window) global context içinde denir. Şimdi, daha önce oluşturduğunuz test işlevinize temel olarak window.test = n; ayarlıyorsunuz. Biz bu daha açık yazarsan

, bu daha belirgin hale gelir:

this.fn = function (n) { 
    bob.call(this,n); 
    console.log(this.test); 
}; 
: Örneğin .call() kullanarak, açık bir bağlam bob() arayarak

// in the global scope, `test` gets written to the `global object` 
// window.test = new Test(5); 
var test = new Test(5); 

test.fn(1); // returns 5 
test.fn(2); // returns TypeError: 'undefined' is not a function 

yapabilirsiniz "geçici çözüm" bu konu


Burada kötülüğün kökü, çalışma zamanı sırasında this değerinin dinamik olarak atanmasıdır. Beni yanlış anlamayın, aslında ECMAscript'in harika bir özelliği - bu sadece sizin için sorun. Bir işlevi çağırdığınızda, "sadece bu gibi", this her zaman genel nesneyi başvuruyor.

0

Sen bob.call(this, n) aramak istediğiniz aşağıdaki

function Test(n) { 
    this.test = n; 

    // If a function needs 'this' it should be attached to 'this'  
    this.bob = function (n) { 
     this.test = n; 
    }; 

    this.fn = function (n) { 
    // and called with this.functionName 
    this.bob(n); 
    console.log(this.test); 
    }; 
} 

VEYA

function Test(n) { 
    this.test = n; 

    var bob = function (n) { 
     this.test = n; 
    }; 

    this.fn = function (n) { 
    // Make sure you call bob with the right 'this' 
    bob.call(this, n); 
    console.log(this.test); 
    }; 
} 

VEYA kapatma bazlı nesnelerden birini gerekir davranmaya için

sadece bob(n) değil. Eğer bob(n) çağırdığınızda

, this değeri değil senin nesne, bu window var olduğunu. Bu nedenle, test değişkeniniz 1 ile değiştirilir.

jsFiddle'da, kod bir işlevle sarılır, bu nedenle window.test ilk başta yoktur.

İlgili konular