吃完晚饭休息, 随便发点东西
之前半夜无聊发了点东西, 关于如何优雅地遍历对象 /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 还是无法遍历的.
1
iloahz 2018-05-24 19:35:00 +08:00 via Android
不应该是不要改原生类型的原型么。。。
|
2
murmur 2018-05-24 19:46:02 +08:00
我也在想,动不动搞自己类数组出来是图个啥
|
5
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 而已 |
6
yushiro 2018-05-24 19:50:05 +08:00 via iPhone
ES6 里面用 for of,专门解决这个问题的
|
7
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' |
8
des 2018-05-24 20:14:07 +08:00 via Android
for (const key in Object.keys(obj))
??? 写错了吧? |
9
Biwood 2018-05-24 20:53:28 +08:00 via Android
假如需要用 return 中断循环操作怎么办? forEach 无法中断吧。另外,修改原生对象的原型这种问题应该在调试的时候就能被发现,出现几率较低,可以忽略。
|
12
tommyZZM 2018-05-24 23:43:31 +08:00
for title question, see this
https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#5-for-in |
14
wengjin456123 2018-05-25 09:01:47 +08:00
是因为会遍历到原型链上的?
|
15
wengjin456123 2018-05-25 09:02:34 +08:00
一般考虑清楚就可以自由选择了
|