2011-12-22 111 views
2

好了的變量,我偶然發現了這段代碼..奇特的JavaScript結構:在對象定義對象類型

如何來工作的嗎? JavaScript使用什麼樣的邪惡方案來解決變量?

我認爲它是一種C++類型的人:類/對象定義包含一個不存在的對被定義類的對象的引用。真的,怎麼樣?

(說實話,我理解部分 - 我可以推斷出怎樣及何時JS解析名稱..但也許這樣的問題會更多的使用給別人,有一天一個稻草人概念)

有罪代碼:

function Sio() { 
    this.someValue = 5; 
    this.doStuff = function() { 
     console.log("look: "+howDoYouResolveThisYouFoulCreature.someValue); 
    }; 
} 

var howDoYouResolveThisYouFoulCreature = new Sio(); 

這似乎是錯誤的。

回答

3

很多的概念在這裏,我不知道哪一個是給你的煩惱......

兩個最有可能的有new/thisvar

new/this

當調用的this值由在其中調用它的上下文確定的函數。

如果使用new關鍵字,則創建函數的實例並將該實例作爲上下文。

當您致電howDoYouResolveThisYouFoulCreature.doStuff()時,您正在以全局身份訪問該實例。它通常會更有意義:

this.doStuff = function() { 
    console.log("look: "+ this.someValue); 
}; 

由於foo.doStuff(),使foodoStuff()這invokation上下文(這使得Sio不同實例之間的功能可重複使用)

var

  1. JavaScript中的範圍在功能級別。
  2. 使用var something函數內的任何地方都會範圍變量到功能
  3. 它被認爲是很好的做法,使用單一var聲明在函數的頂部,以避免混亂

此外,doStuff功能在howDoYouResolveThisYouFoulCreature之前沒有被調用。在那之前,所有重要的是函數在語法上是正確的,這個變量是什麼類型並不重要。

1

它的工作原理是在創建howDoYouResolveThisYouFoulCreature之前不執行this()this.doStuff。請記住,無論doStuff()被調用的變量名稱是多少,您都將始終使用console.log howDoYouResolveThisYouFoulCreature.someValue。

1

這樣做是因爲:

var howDoYouResolveThisYouFoulCreature = new Sio(); 

...其實解析爲:

var howDoYouResolveThisYouFoulCreature; 
howDoYouResolveThisYouFoulCreature = new Sio(); 

所以在功能 doStuff分配時, var已聲明。

編輯:忘記了,我是愚蠢的。原來pimvdb是正確的,而這裏的證明(also on jsfiddle):

function A() { 
    this.logValue = function() { 
     if (b === undefined) { 
      console.log('Wah, wah, wah...'); 
     } else { 
      console.log(b.someValue); 
     } 
    }; 
} 

function B() { 
    this.someValue = 42; 
} 

var a = new A(); 
a.logValue(); // Wah, wah, wah... 

var b = new B(); 
a.logValue(); // 42 

所以執行上下文是關鍵。當構建Sio(或者在這種情況下,A)時,它的範圍是在某個時刻可以定義b可能是。該變量在函數被調用之前不會被解析,在此時它可能被定義。或不。沒什麼大不了的。 :-)

+0

這不一定重要;如果該函數引用一個不存在的變量,也可以爲該變量分配一個函數。 – pimvdb 2011-12-22 15:59:48