国际热核聚变实验堆|web前端 - JS中的4个for循环( 二 )


Array.prototype.fatherName = “Father”;
const arr = [1 2 3
;
arr.name = “Hello world”;
let index;
for(index in arr) {
console.log(“arr[“ + index + “
= “+ arr[index
);

操作的结果是:
arr[0
= 1
arr[1
= 2
arr[2
= 3
arr[name
= Hello world
arr[fatherName
= Father
至此 , 我们可以发现for-in并不适合遍历Array中的元素 , 它更适合遍历对象的属性 , 这也是它创建的初衷 。 有一个例外 , 那就是稀疏数组 , 阅读以下示例:
let key;
const arr = [
;
arr[0
= “a”;
arr[100
= “b”;
arr[10000
= “c”;
for(key in arr) {
if(arr.hasOwnProperty(key) &&
/$|^[1–9
\\d*$/.test(key) &&
key <= 4294967294
) {
console.log(arr[key
);


For-in 仅遍历现有实体 。 上例中for-in遍历了3次(分别遍历属性为“0”、“100”、“10000”的元素 , 普通for循环会遍历10001次) 。 因此 , 只要处理得当 , for-in 也可以在遍历 Array 中的元素方面发挥巨大的作用 。
为了避免重复工作 , 我们可以包装上面的代码:
function arrayHasOwnIndex(array prop) {
return array.hasOwnProperty(prop) &&
/$|^[1–9
\\d*$/.test(prop) &&
prop <= 4294967294; // 2-2

用法示例如下:
for (let key in arr) {
【国际热核聚变实验堆|web前端 - JS中的4个for循环】if (arrayHasOwnIndex(arr key)) {
console.log(arr[key
);


2.4、 for-in性能
如上所述 , 每次迭代操作都会同时搜索实例或原型属性 。 for-in 循环的每次迭代都会产生更多的开销 , 所以它比其他循环类型慢 , 一般速度是其他循环类型的 1/7 。
因此 , 除非您明确需要迭代具有未知数量属性的对象 , 否则您应该避免使用 for-in 循环 。 如果需要遍历有限数量的已知属性列表 , 使用其他循环会更快 , 例如以下示例:
const obj = {
“prop1”: “value1”
“prop2”: “value2”
;
const props = [“prop1” “prop2”
;
for(let i = 0; i <props.length; i++) {
console.log(obj[props[i

);

在上面的代码中 , 对象的属性存储在一个数组中 。 与for-in搜索每个属性相比 , 代码只关注给定的属性 , 节省了循环的开销和时间 。
3、forEach
在 ES5 中 , 引入了一个新循环 , 即 forEach 循环 。
const arr = [1 2 3
;
arr.forEach((data) => {
console.log(data);
);
操作结果:
1
2
3
forEach 方法对数组中包含有效值的每一项执行一次回调函数 , 那些已经被删除(使用delete 方法等)或从未赋值的项将被跳过(不包括那些未定义的项) 或空值) 。 回调函数会依次传入三个参数:
数组中当前项的值;
当前项在数组中的索引;
数组对象本身;
需要注意的是 , forEach 遍历的范围会在第一次调用回调之前确定 。 调用 forEach 后添加到数组的项目不会被回调访问 。
如果现有值发生变化 , 则传递给callback的值就是forEach遍历它们时的值 。 不会遍历已删除的项目 。
const arr = [
;
arr[0
= “a”;
arr[3
= “b”;
arr[10
= “c”;
arr.name = “Hello world”;
arr.forEach((data index array) => {
console.log(data index array);
);
操作结果:
a 0 [“a” 3: “b” 10: “c” name: “Hello world”

b 3 [“a” 3: “b” 10: “c” name: “Hello world”

c 10 [“a” 3: “b” 10: “c” name: “Hello world”

这里的索引是Number类型的 , 不会像for-in那样遍历原型链上的属性 。