首先给出结论。从性能上看。for循环 > for-of > forEach > for-in
引用自撒网要见鱼的博客
其中,缓存数组长度的for循环是最优的。但是在chrome的v8引擎中对数组长度的缓存做了优化,只要数组长度不变,for循环不会每次去计算数组长度的,因此缓存数组长度可能在基于ie内核的浏览器里可能会有性能的提升。
当然,这并不以为着为了追求性能就要使用for循环。这还是要看情况而定,毕竟现在硬件的发展,对js的性能的要求也不像以前那么偏执了。
-
forEach只能用于数组。
-
for…in 语句以原始插入顺序迭代对象的可枚举属性。
对于这个原始插入顺序,是按照继承和原型链的顺序的。以数组举例:自身 -> Array.prototype -> Object.prototype
接下来证明这一点:
Object.prototype.objCustom = function() {};
Array.prototype.arrCustom = function() {};
let iterable = [3, 5, 7];
iterable.foo = 'hello';
for (let i in iterable) {
console.log(i); // logs 0, 1, 2, "foo", "arrCustom", "objCustom"
}
for (let i in iterable) {
if (iterable.hasOwnProperty(i)) {
console.log(i); // logs 0, 1, 2, "foo"
}
}
for (let i of iterable) {
console.log(i); // logs 3, 5, 7
}
这部分是mdn文档里的。已经运行过了。接下来我调换顺序又创建了两个函数然后输出。
始终是自身的属性先于数组原型的属性再是对象原型的属性这个顺序。
另外说一点:使用hasOwnProperty()
来检查,只会记录对象自己的可枚举属性(不是继承的)
-
for…of 语句遍历可迭代对象定义要迭代的数据。
如果你不想修改语句块中的变量 , 也可以使用const代替let。
for…of迭代出的数据是基于可迭代对象的默认迭代器的。这一点和…扩展运算符分割元素异曲同工。
以Map为例
let iterable = new Map([["a", 1], ["b", 2], ["c", 3]]);
for (let entry of iterable) {
console.log(entry);
}
// ["a", 1]
// ["b", 2]
// ["c", 3]
for (let [key, value] of iterable) {
console.log(value);
}
// 1
// 2
// 3