乐趣区

关于foreach:对象数组的遍历方法总结

遍历对象

办法 规范 形容 返回值 特点
for…in ES5 遍历对象的所有可枚举属性 可枚举
原型链上可枚举
蕴含原型链上的可枚举属性
可 break
Object.keys() ES5 返回对象所有可枚举属性 可枚举 返回的数组中的值都是字符串(不是也转 string)
Object.getOwnPropertyNames() ES6 对象本身的所有属性名 可枚举
不可枚举
蕴含不可枚举的属性
Object.getOwnPropertySymbols() ES6 返回对象本身的 Symbol 属性组成的数字,不蕴含字符串振兴 symbol 属性的值(可枚举和不可枚举)
Reflect.ownKeys() ES6 返回一个数组,蕴含对象本身的所有属性 可枚举
不可枚举
symbol 类型
Object.values() ES8 返回对象所有可枚举属性值的数组 可枚举
Object.entries() ES8 返回对象本身可枚举属性的键值对数组 可枚举

js 分为函数对象和一般对象,每个对象都有__proto__属性,只有函数对象才有 prototype 属性
Object.defineProperties() 办法间接在一个对象上定义新的属性或批改现有属性,并返回该对象。该办法默认 enumerable 为 false

可枚举属性:外部“可枚举 (enumerable)”标记设置为 true 的属性
不可枚举属性:与可枚举属性相同

var obj=function(){
    this.name = "张三";
    this.age = 10
}; // 构造函数
var newobj = new obj(); // 创立实例,实例对象会继承构造函数的原型属性
obj.prototype.friend = "李四"; // 在原型上增加属性

// 在对象 newobj 上定义新的属性
Object.defineProperties(newobj,{
    "city":{
        value: "杭州",
        enumerable: true,// 是否为枚举属性
    },
    "height":{
        value: '2m',
        enumerable: false,// 是否为枚举属性
    },
    [Symbol('sex')]:{
        value: 'symbol_sex',
        enumerable: true
    },
})

for(var i in newobj){console.log(i)} //name age city friend
Object.keys(newobj) //["name", "age", "city"]
Object.getOwnPropertyNames(newobj) //["name", "age", "city", "height"]
Object.ownKeys(newobj) //["name", "age", "city", "height", Symbol(sex)]
Object.values(newobj) // ["张三", 10, "杭州"]
Object.entries(newobj) //[["name", "张三"],["age", 10],["city", "杭州"]]
Object.getOwnPropertySymbols(newobj) //[Symbol(sex)]

遍历数组

办法 规范 特点 break
forEach() ES5 不扭转原数组
无返回值
map() ES5 不扭转原始数据
返回一个新数组
for of ES6
for await of ES9 异步遍历
filter() ES6 不扭转原数组
返回符合条件的元素
some()
every()
ES6 不扭转原数组
返回 true 或 false
reduce() ES6 累加器
不扭转原数组
find() ES6 返回第一个符合条件的元素
不扭转原数组
findIndex() ES6 返回第一个符合条件的索引值
不扭转原数组
keys() ES6 返回数组的索引值
values() ES6 返回数组的元素
entries() ES6 返回数组的键值对
//for await of
function Gen (time) {return new Promise((resolve,reject) => {setTimeout(function () {resolve(time)
        },time)
    })
}
async function test () {let arr = [Gen(2000),Gen(100),Gen(3000)]
    for await (let item of arr) {console.log(Date.now(),item)
        if(item===100){break;}
    }
}
// 1648631137863 2000
// 1648631137863 100
test()

//keys()、values()、entries()
var arr = ["周一","周二","周三"];
var iterator1 = arr.keys();
var iterator2 = arr.values() 
var iterator3 = arr.entries() 

for (let item of iterator1) {console.log(item); // 0 1 2
}
for (let item of iterator2) {console.log(item); // 周一 周二 周三
}
for (let item of iterator3) {console.log(item); //[0,"周一"] [1,"周二"] [2,"周三"]
}

其它循环

办法 表列 B 特点 break
for 循环代码块肯定的次数
while 当指定的条件为 true 时循环指定的代码块 先判断再执行
do…while 直反复直到指定的条件为 false 先执行再判断

性能比拟

var data=[];
for(var i=0;i<1000000;i++){data.push(i)
}

//forEach
console.time('forEach')
var result1=[];
data.forEach(item=>{result1.push(item);
})
console.timeEnd('forEach') //39ms

//map
console.time('map')
var result2=[];
data.map(item=>{result2.push(item);
})
console.timeEnd('map') //33.ms

//for of
console.time('for...of')
var result3=[];
for(var item of data){result3.push(item)
}
console.timeEnd('for...of') //25.ms

//for in
console.time('for...in')
var result4=[];
for(var item in data){result4.push(data[item])
}
console.timeEnd('for...in') //169ms

//for
console.time('for 循环')
var result5=[];
for(var i=0;i<data.length;i++){result5.push(data[item])
}
console.timeEnd('for 循环') //17ms
退出移动版