博客 / 詳情

返回

對象、數組的遍歷方法總結

遍歷對象

方法 標準 描述 返回值 特點
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
user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.