2013-10-09 128 views
6

我正在學習JavaScript,並且我遇到了疑問。爲什麼「this」的值在第一個示例中未定義,但在第二個示例中正確輸出。爲什麼「this」的值會改變。?

例1:

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

var hello = myNamespace.myObject.sayHello; 

hello(); // "name is undefined" 

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

爲什麼的函數內的 「本」 的值發生變化。我缺少什麼概念?

+4

這就是'這個'的工作原理。 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/這個 – SLaks

+2

你的期望很好,JavaScript的這種語義被打破了。 :-) – Waldheinz

+0

它是JavaScript不是「java腳本」..非常非常大的區別.. :) –

回答

3

您是剛開始的vairable hello函數的引用第一種情況,以及全球範圍內(窗口調用它瀏覽器,全局節點),所以this成爲除(綁定函數)外調用函數的東西。您可以隨時設定明確使用function.call上下文或明確設置的情況下使用Ecma5 function.bind

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

功能或只是將它綁定在獲取函數引用。

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

第二種情況,你是從目標本身,以便this指向的對象調用它。

1

在第一種情況下,隱含的this對象是全局範圍。由於全局範圍中沒有myName,因此您將得到未定義的值。

如果你想用正確的this免費的功能,使用bind

var hello = myNamespace.myObject.sayHello.bind(myNamespace.myObject); 
相關問題