为什么不要使用 for...in

2018-05-24 19:02:37 +08:00
 fulvaz

吃完晚饭休息, 随便发点东西

之前半夜无聊发了点东西, 关于如何优雅地遍历对象 /t/456374

楼下说使用 for...in 遍历对象的 key

然而 for...in 的前提是, 你需要保证 Array 的原型没有被改变过.

为啥? 因为 for...in 会遍历所指定对象全部 enumerable, 如果说你使用的某个库重写了 Array 的原型, 那么遍历的结果就会很奇怪了, 比如说

Array.prototype.val = 123;

obj = {1: 'a', 2: 'b'}

for (const key in Object.keys(obj)) {
	console.log(key);
}

上面代码的结果是 0, 1, val, 所以使用 for...in 必须要加 hasOwnProperty.

不然就乖乖用 forEach.

多说一句, 正常情况自己是不会重写 Array 的原型的, 但是你不能保证你用的第三方库没使用这种黑魔法.

再多说一句, 如果重写某个非 enumerable 的属性, 那么该属性还是 enumerable 的, 如 Array.forEach = something, for...in 还是无法遍历的.

3678 次点击
所在节点    问与答
15 条回复
iloahz
2018-05-24 19:35:00 +08:00
不应该是不要改原生类型的原型么。。。
murmur
2018-05-24 19:46:02 +08:00
我也在想,动不动搞自己类数组出来是图个啥
fulvaz
2018-05-24 19:47:33 +08:00
@iloahz 你不能保证你用的库不改呀
Pastsong
2018-05-24 19:48:36 +08:00
@fulvaz 可以保证这种库我不用
murmur
2018-05-24 19:49:04 +08:00
看错了,不过我记得 array.prototype 扩展的方法被遍历出来是 IE 专属错误?

Array.prototype.val = 123;

obj = {1: 'a', 2: 'b'}

for (var key in obj) {
console.log(key);
}

这个输出 1 2 没有 val

看来会的越多越容易出麻烦 当然写 var 是在 ie 做兼容写顺手了 没用 object.keys 而已
yushiro
2018-05-24 19:50:05 +08:00
ES6 里面用 for of,专门解决这个问题的
broker
2018-05-24 20:04:44 +08:00
for in 和 in operator 在一起时候会报错~

for (let a = b in c; false;); // does not parse

for (let a = (b in c); false;); // parses fine

另一个就是定义 enumerable

Boolean.prototype.foo = 'bar';

for (let a in ('' in {})) {
console.log(a);
} // prints 'foo'
des
2018-05-24 20:14:07 +08:00
for (const key in Object.keys(obj))

???
写错了吧?
Biwood
2018-05-24 20:53:28 +08:00
假如需要用 return 中断循环操作怎么办? forEach 无法中断吧。另外,修改原生对象的原型这种问题应该在调试的时候就能被发现,出现几率较低,可以忽略。
des
2018-05-24 21:29:53 +08:00
@Biwood 可以用 catch,2333
Garwih
2018-05-24 21:36:31 +08:00
@Biwood #9 可以用 every()
tommyZZM
2018-05-24 23:43:31 +08:00
DOLLOR
2018-05-25 07:57:24 +08:00
@Biwood
some()、every()
wengjin456123
2018-05-25 09:01:47 +08:00
是因为会遍历到原型链上的?
wengjin456123
2018-05-25 09:02:34 +08:00
一般考虑清楚就可以自由选择了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/457539

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX