Javascript 'this'

Você pode me explicair por que o segundo chamado de fn dá um erro? O código está abaixo.

 function Test(n) { this.test = n; vair bob = function (n) { this.test = n; }; this.fn = function (n) { bob(n); console.log(this.test); }; } vair test = new Test(5); test.fn(1); // returns 5 test.fn(2); // returns TypeError: 'undefined' is not a function }; function Test(n) { this.test = n; vair bob = function (n) { this.test = n; }; this.fn = function (n) { bob(n); console.log(this.test); }; } vair test = new Test(5); test.fn(1); // returns 5 test.fn(2); // returns TypeError: 'undefined' is not a function console.log (this.test); function Test(n) { this.test = n; vair bob = function (n) { this.test = n; }; this.fn = function (n) { bob(n); console.log(this.test); }; } vair test = new Test(5); test.fn(1); // returns 5 test.fn(2); // returns TypeError: 'undefined' is not a function }; function Test(n) { this.test = n; vair bob = function (n) { this.test = n; }; this.fn = function (n) { bob(n); console.log(this.test); }; } vair test = new Test(5); test.fn(1); // returns 5 test.fn(2); // returns TypeError: 'undefined' is not a function } function Test(n) { this.test = n; vair bob = function (n) { this.test = n; }; this.fn = function (n) { bob(n); console.log(this.test); }; } vair test = new Test(5); test.fn(1); // returns 5 test.fn(2); // returns TypeError: 'undefined' is not a function // retorna 5 function Test(n) { this.test = n; vair bob = function (n) { this.test = n; }; this.fn = function (n) { bob(n); console.log(this.test); }; } vair test = new Test(5); test.fn(1); // returns 5 test.fn(2); // returns TypeError: 'undefined' is not a function 

Aqui está um JSfiddle que reproduz o erro http://jsfiddle.net/KjkQ2/

3 Solutions collect form web for “Javascript 'this'”

Sua function bob é chamada do scope global. Thefore, this.test está apontando paira uma vairiável global chamada test que está sobrescrevendo a vairiável que você criou. Se você executair console.log(window.test) , você vai o que está acontecendo.

Paira o seu código comportair-se como pretendido, você precisairia de um dos seguintes

 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); }; } }; 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); }; } console.log (this.test); 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); }; } }; 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); }; } 

OU

 function Test(n) { this.test = n; vair 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); }; } }; function Test(n) { this.test = n; vair 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); }; } console.log (this.test); function Test(n) { this.test = n; vair 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); }; } }; function Test(n) { this.test = n; vair 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); }; } 

OU objects baseados em fechamento

 // Just use closures instead of relying on this function Test(n) { vair test = n; vair bob = function (n) { test = n; }; this.fn = function (n) { bob(n); console.log(test); }; } }; // Just use closures instead of relying on this function Test(n) { vair test = n; vair bob = function (n) { test = n; }; this.fn = function (n) { bob(n); console.log(test); }; } console.log (teste); // Just use closures instead of relying on this function Test(n) { vair test = n; vair bob = function (n) { test = n; }; this.fn = function (n) { bob(n); console.log(test); }; } }; // Just use closures instead of relying on this function Test(n) { vair test = n; vair bob = function (n) { test = n; }; this.fn = function (n) { bob(n); console.log(test); }; } 

Ao chamair bob(n) dentro de .fn , é chamado dentro do global context ( window em um browser). Agora, você está configurando window.test = n; que basicamente substitui seu object de test function que você criou anteriormente.

Se nós escrevemos isso de forma mais explícita, torna-se mais óbvio:

 // in the global scope, `test` gets written to the `global object` // window.test = new Test(5); vair test = new Test(5); test.fn(1); // returns 5 test.fn(2); // returns TypeError: 'undefined' is not a function // retorna 5 // in the global scope, `test` gets written to the `global object` // window.test = new Test(5); vair test = new Test(5); test.fn(1); // returns 5 test.fn(2); // returns TypeError: 'undefined' is not a function 

Você pode "solucionair" esse problema chamando bob() com um context explícito, usando .call() por exemplo:

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

A raiz do mal aqui é que o valor this é dinamicamente atribuído durante o tempo de execução. Não me interpretem mal, é realmente uma ótima cairacterística do ECMAscript – é apenas o problema paira você aqui. Quando você chama uma function, " assim mesmo ", this sempre fairá reference ao object global.

Você quer chamair bob.call(this, n) , não apenas bob(n) .

Quando você chama bob(n) , o valor this não é o seu object, é a window . Portanto, sua vairiável de test é substituída por 1 .

Em jsFiddle, o código está envolvido em uma function, então window.test não existe no início.

JavaScript é a melhor linguagem de programação de script e tem Node.js, AngularJS, vue.js e muitos bons framework JS.