2013-10-09 11 views
6

Sto imparando javascript e mi sono imbattuto in un dubbio. Perché il valore di "questo" non è definito nel primo esempio, ma viene stampato correttamente nel secondo.Perché il valore di "questo" cambia?

Esempio 1:

var myNamespace = { 
    myObject: { 
     sayHello: function() { 
      console.log("name is " + this.myName); 
     }, 
     myName: "john" 
    } 
}; 

var hello = myNamespace.myObject.sayHello; 

hello(); // "name is undefined" 

Esempio 2:

var myNamespace = { 
    myObject: { 
     sayHello: function() { 
      console.log("Hi! My name is " + this.myName); 
     }, 
     myName: "Rebecca" 
    } 
}; 

var obj = myNamespace.myObject; 

obj.sayHello();//"Hi! My name is Rebecca" 

Perché il valore di "questo" cambiamenti all'interno della funzione. Che concetto mi manca?

+4

Ecco come funziona "questo". https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this – SLaks

+2

L'aspettativa è giusta, la semantica 'this' di JavaScript è interrotta. :-) – Waldheinz

+0

non è javascript "java script" .. molto molto bella differenza .. :) –

risposta

3

primo caso in cui si sono solo ottenere il riferimento della funzione al vairable hello, e invocando dal contesto globale (finestra browser, globale nel nodo), quindi this diventa ciò che ha invocato la funzione ad eccezione di (funzioni associate). È sempre possibile impostare il contesto in modo esplicito utilizzando function.call o impostare il contesto esplicitamente alla funzione utilizzando Ecma5 function.bind

hello.call(myNamespace.myObject); //now you are setting the context explicitly during the function call. 

o semplicemente legarlo mentre ottenere il riferimento alla funzione.

var hello = myNamespace.myObject.sayHello.bind(myNamespace.myObject); //Now no matter where you call it from `this` will point to the context of myObject 

Secondo caso si invoca dall'oggetto stesso in modo this punti all'oggetto.

1

Nel primo caso, l'oggetto implicito this è l'ambito globale. Poiché non esiste uno myName nell'ambito globale, si ottiene undefined.

Se si desidera una funzione libera con il corretto this, utilizzare bind:

var hello = myNamespace.myObject.sayHello.bind(myNamespace.myObject); 
Problemi correlati