2013-10-09 3 views
6

Ich lerne Javascript und ich stieß auf Zweifel. Warum ist der Wert von "this" im ersten Beispiel undefiniert, wird aber im zweiten Beispiel korrekt ausgegeben.Warum ändert sich der Wert von "this"?

Beispiel 1:

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

var hello = myNamespace.myObject.sayHello; 

hello(); // "name is undefined" 

Beispiel 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" 

Warum in der Funktion den Wert von "dieser" Änderungen der Fall ist. Welches Konzept fehlt mir?

+4

So funktioniert 'this'. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this – SLaks

+2

Ihre Erwartung ist in Ordnung, JavaScript '' s' Semantik ist gebrochen. :-) – Waldheinz

+0

es ist Javascript nicht "java script" .. sehr sehr großer Unterschied .. :) –

Antwort

3

Erster Fall Sie nur die Referenz der Funktion zum vairable hello bekommen, und es von den globalen Kontext aufgerufen wird (Fenster in Browser, global im Knoten), also this wird, was die Funktion mit Ausnahme von (gebundenen Funktionen) aufgerufen hat. Sie können immer den Kontext explizit function.call oder stellen Sie den Zusammenhang ausdrücklich auf die Funktion mit Ecma5 function.bind

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

gesetzt oder es nur binden, während die Funktion getting.

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

Zweiter Fall, dass Sie es von dem Objekt selbst so this verweist auf das Objekt aufgerufen wird.

1

Im ersten Fall ist das implizite Objekt this der globale Bereich. Da im globalen Bereich kein myName vorhanden ist, werden Sie nicht definiert.

Wenn Sie eine kostenlose Funktion mit der richtigen this möchten, verwenden Sie bind:

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