2016-05-11 45 views
5

我對Javascript還相當陌生,試圖根據in運算符的工作原理確定for...in循環的工作原理。In-in循環之前和之後的運算符

This解決了困惑。

但是,我現在很困惑,爲什麼in運算符在除最後一個之外的所有場景中都返回false

它看起來像for...in循環正在obj中使用其最後一次迭代的值創建密鑰keyTest。

我的理解是否正確?當用於遍歷所有對象鍵時,for...in循環是否會在它們遍歷的對象中創建鍵/值?

如果是這樣,任何幫助理解會有幫助。

var keyTest, obj = {} 
keyTest in obj; // false 
for(var keyTest in obj) { obj[keyTest] }; 
keyTest in obj; // false 

obj = { a : 1, b : 2 }; 
keyTest in obj; // false 
for(var keyTest in obj) { obj[keyTest] }; 
keyTest in obj; // true 
obj[keyTest] // 2 
+1

「for-in」只是遍歷對象鍵,僅此而已。 – zerkms

+0

如果對象包含給定屬性,則'in'將返回true。 keytest和obj都是獨立的對象,都不是另一個的屬性.... –

回答

3

for...in循環中使用要經過所有的對象鍵,當他們遍歷對象創建鍵/值?

不,但他們將鍵指定給迭代變量(您的情況爲var keyTest)。這就是爲什麼你的例子會產生你看到的結果。

// keyTest = undefined (initialisation of the hoisted variable) 
var keyTest, obj = {} // keyTest === undefined 
keyTest in obj; // keyTest === undefined 
for(var keyTest in obj) { obj[keyTest] }; // `obj` is empty and `keyTest` stays what it is 
keyTest in obj; // false // keyTest === undefined 

// keyTest = undefined (initialisation of the hoisted variable) 
obj = { a : 1, b : 2 }; // keyTest === undefined 
keyTest in obj; // keyTest === undefined 
for(var keyTest in obj) { obj[keyTest] }; // keyTest = "a", keyTest = "b" 
keyTest in obj; // keyTest === "b" 
1

我現在困惑,爲什麼在運算符返回false

in運營商接受2個操作數:

  • 留在e是測試
  • ,右邊的鍵名被測試的對象對

因此,對於這個代碼片斷

var keyTest, obj = {} 
keyTest in obj; // false 

keyTestundefined(你還沒有初始化它價值)。因此,您正在檢查是否"undefined"(它將被轉換爲字符串,因爲對象只能*保存字符串屬性)是obj對象鍵之一,因此不是false

for(var keyTest in obj) { obj[keyTest] }; 
keyTest in obj; // true 

這裏因爲循環結束後的keyTest變量保存最新的迭代鍵的值返回true。所以你正在測試一個實際的鍵是否在對象中。

2

這是吊裝問題。在es5中沒有塊級作用域,因此你的keyTest變量在範圍的開始處被提升並聲明(函數或全局,它取決於你在哪裏運行你的代碼)。

所以var keyTest不是塊變量,而是範圍變量,因此它引用在您的代碼的每一行中在此範圍內使用的相同變量。這就是爲什麼你的for循環將迭代的最後一個值賦給這個變量的原因。


如果談論你的榜樣,爲什麼你有兩種不同的結果的原因是,在第一個例子中,你有沒有鑰匙放在obj,所以for循環不會做任何迭代,因此將不再將任何值分配給您的keyTest,以便它仍然未定義。


但是,例如es6具有塊級變量。因此,如果在for循環中將var更改爲let(塊級變量聲明關鍵字),並在es6兼容的環境中運行此代碼,則會得到不同的輸出。也許這會幫助你理解正在發生的事情。

//es6 code 
var keyTest; 
obj = { a : 1, b : 2 }; 
keyTest in obj; // false 
for(let keyTest in obj) { obj[keyTest] }; 
keyTest in obj; // false 
obj[keyTest] // undefined