为..in - 被迭代的对象在进入循环之前是否只计算一次
for ... in - Is the object being iterated evaluated just once before entering the loop?
当我使用 for ...循环中,例如:
for(var i in object) {}
我想知道有问题的object
是只评估一次还是每次循环时。
我在浏览器(也在节点中(进行了快速测试,例如:
for(var i in (console.log('INIT'), [1, 2, 3, 4])) { console.log('KEY', i); }
我得到:
INIT
KEY 0
KEY 1
KEY 2
KEY 3
因此,根据这些经验证据,我可以假设这确实只被评估过一次。
但是,这种行为是标准的吗?
从 Mozilla 文档中,for...in
循环将迭代对象本身的所有可枚举属性以及对象从其构造函数原型继承的属性。 在访问之前删除的(可枚举(属性以后将不再访问。添加到发生迭代的对象的属性可以在迭代中访问或省略。
简而言之,@Amit发布的示例的结果无法保证,尽管Chrome和IE可能会对for ..in
循环使用不同的规范。但是,至少删除一个元素似乎可以阻止它在Chrome中被访问:
var obj = { a: 1, b: 2, c: 3 };
for(var k in obj) {
document.write(k);
delete obj['c'];
}
,(console.log('INIT'), [1, 2, 3, 4])
是一个计算结果为 [1, 2, 3, 4]
的表达式,因此它不是问题的有效证据。更好的经验证据可以通过以下方式获得:
var obj = { a: 1, b: 2, c: 3 };
for(var k in obj) {
document.write(k);
obj.d = 4;
}
而且我们看不到"d"...
ECMAScript® 语言规范第 12.6.4 节对此没有说太多,只是右侧的表达式被计算一次并强制转换为对象:
- 让 exprRef 是计算表达式的结果。
- 让 experValue 成为 GetValue(exprRef(。
- 如果 experValue 为
null
或undefined
,则返回 (normal、empty、empty(。- 让 obj 成为 ToObject(experValue(。
这说明当时评估该对象的任何键或值
。事实上,引用段落后面的部分表明可以在迭代期间检索密钥:
- 重复
- 设 P 是 obj 的下一个属性的名称,其 [[Enumerable]] 属性为
true
。如果没有这样的属性,则返回(正常,V,空(。
但这两个方向都没有要求。所以。。。这可能取决于实现(浏览器(。
当您说对象仅计算一次时,可以具有不同的含义:
- 对象引用仅计算一次。当该对象是表达式(如函数调用(的结果时,这一点很重要。但这肯定是理所当然的,而不是你的意思;
- 对象的键(属性(枚举一次,但值是按需检索的;
- 对象的键和值检索一次。这可以在 1 级或嵌套级别完成,但内存成本可能很高。
这个测试用例在我的浏览器(FireFox(中显示第二次发生,而不是第三次:
var obj = {a: 1, b: 2, c: 3};
for (key in obj) {
document.write('obj[' + key + '] = ' + obj[key] + '<br>');
if (key=='a') {
// modify a value that is still to be visited
obj["c"] = 4;
// add a key/value pair
obj["d"] = 9;
}
}
输出是(您可能也可以在浏览器中看到(:
目标[a] = 1
目标[b] = 2
obj[c] = 4
因此,键只检索一次,即按需值(即不在循环开始时(。
- 检查字符串是否包含计算
- iFrame 是否计算页面浏览量
- 计算多边形是否足够大,可以在 gmap 上可见
- Ember-自定义计算属性,用于检查是否存在所有依赖字段
- 了解网页和桌面应用程序是否在同一台计算机上启动
- 是否有HQMF到QRDA cat 3计算的简单示例
- 计算日期选择器+时间选择器是否在东部标准时区的过去
- 使用JavaScript计算用户是否超过16岁
- 如何在Ember.js中创建一个计算属性来查看单个EmberData属性是否脏
- 年龄验证输入框 - 计算是否超过 18 岁
- 使用 JavaScript 或 C# 检查客户端计算机上是否安装了 Java 应用程序(不是 JAVA!)
- 如何提高javascript html5程序的整体性能:是否可以在两台计算机上同步两个版本
- 是否有一个JavaScript库可以在没有UI的情况下进行电子表格计算
- 当网页存储在计算机上时,cookie 是否有效
- 是否应该在同一台计算机上的两个火狐浏览器共享相同的cookie
- 计算线是否穿过圆,在某些角度出现奇怪的行为
- 是否可以通过在 javascript 中使用正则表达式来计算具有输入年份出生的年龄
- 是否可以从外部样式表中获取 dom 元素的特定 css 属性的值,而不是从计算的样式表中获取
- 是否可以在评估右侧之前强制“=”的左侧完全计算为引用
- 什么是覆盖率的因素 是否有任何计算覆盖率的算法