5

我对 Javascript 还很陌生,并试图根据运算符的工作方式准确地弄清楚for...in循环是如何in工作的。

消除了混乱。

但是,我现在很困惑,为什么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
4

3 回答 3

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"
于 2016-05-12T00:02:29.983 回答
2

是吊装问题。es5 中没有块级作用域,因此您的keyTest变量在作用域的开头被提升和声明(函数或全局,这取决于您运行代码的位置)。

所以var keyTest不是块变量,而是范围变量,因此它在代码的每一行中引用相同的变量,它在这个范围内使用。这就是为什么您的for循环将迭代的最后一个值分配给该变量的原因。


如果要谈论您的示例,您得到两个不同结果的原因是,在第一个示例中,您的 中没有键obj,因此for循环不会进行任何迭代,因此不会为您分配任何值,keyTest因此它将仍然未定义。


但是例如 es6 有块级变量。因此,如果您在循环中更改varlet(块级变量声明关键字)for并在 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
于 2016-05-12T00:16:28.767 回答
1

我现在对 in 运算符返回的原因感到困惑false

in运算符接受 2 个操作数:

  • 左边一个是要测试的键名
  • 正确的是要测试的对象

所以对于这个代码片段

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

是(您尚未使用该值对其进行初始化)keyTestundefined因此,您正在检查"undefined"(它将被转换为字符串,因为对象只能*保存字符串属性)是否是obj对象键之一,因此不是false

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

在这里它返回true是因为keyTest变量保存了循环完成后最新迭代键的值。因此,您正在测试对象中是否存在实际键。

于 2016-05-12T00:02:42.950 回答