javascript遍歷對象的五種方式實例代碼

準備

先來準備一個測試對象obj。

代碼清單1

var notEnum = Symbol("繼承不可枚舉symbol");
var proto = {
    [Symbol("繼承可枚舉symbol")]: "繼承可枚舉symbol",
    name: "繼承可枚舉屬性"
};
// 不可枚舉屬性
Object.defineProperty(proto, "age", {
    value: "繼承不可枚舉屬性"
});
// 不可枚舉symbol屬性
Object.defineProperty(proto, notEnum, {
    value: "繼承不可枚舉symbol"
});

var obj = {
    job1: "自有可枚舉屬性1",
    job2: "自有可枚舉屬性2",
    [Symbol("自有可枚舉symbol")]: "自有可枚舉symbol"
};
// 繼承
Object.setPrototypeOf(obj, proto);
// 不可枚舉屬性
Object.defineProperty(obj, "address", {
    value: "自有不可枚舉屬性"
});
// 不可枚舉symbol屬性
var ownNotEnum = Symbol("自有不可枚舉symbol");
Object.defineProperty(obj, ownNotEnum, {
    value: "自有不可枚舉symbol"
});

五種武器

for…in

這個是對象遍歷界的老兵瞭,通過這種方式可以遍歷對象自身及繼承的所有可枚舉屬性(不包括Symbol類型)。

代碼清單2

for(var attr in obj){
    console.log(attr,"==",obj[attr]);
}
/*
job1 == 自有可枚舉屬性1
job2 == 自有可枚舉屬性2
name == 繼承可枚舉屬性
*/

Object.keys

獲取對象自身所有可枚舉屬性(不包括Symbol類型)組成的數組

代碼清單3

Object.keys(obj).map((attr)=>{
    console.log(attr,"==",obj[attr]);
});
/*
job1 == 自有可枚舉屬性1
job2 == 自有可枚舉屬性2
*/

Object.getOwnPropertyNames

獲取對象自身所有類型為非Symbol的屬性名稱(包括不可枚舉)組成的數組

代碼清單4

Object.getOwnPropertyNames(obj).map((attr)=>{
    console.log(attr,"==",obj[attr]);
});
/*
job1 == 自有可枚舉屬性1
job2 == 自有可枚舉屬性2
address == 自有不可枚舉屬性
*/

Object.getOwnPropertySymbols

獲取對象自身所有類型為Symbol的屬性名稱(包括不可枚舉)組成的數組

代碼清單5

Object.getOwnPropertySymbols(obj).map((attr)=>{
    console.log(attr,"==",obj[attr]);
});
/*
Symbol(自有可枚舉symbol) == 自有可枚舉symbol
Symbol(自有不可枚舉symbol) == 自有不可枚舉symbol
*/

Reflect.ownKeys

獲取一個對象的自身的所有(包括不可枚舉的和Symbol類型)的屬性名稱組成的數組

代碼清單6

Reflect.ownKeys(obj).map((attr)=>{
    console.log(attr,"==",obj[attr]);
});
/*
job1 == 自有可枚舉屬性1
job2 == 自有可枚舉屬性2
address == 自有不可枚舉屬性
Symbol(自有可枚舉symbol) '==' '自有可枚舉symbol'
Symbol(自有不可枚舉symbol) '==' '自有不可枚舉symbol'
*/

總結

武器庫的說明書,根據需要選擇合適的武器吧。

api 操作 自身屬性 不可枚舉屬性 繼承屬性 Symbol屬性
for…in 遍歷 yes no yes no
Object.keys 返回屬性數組 yes no no no
Object.getOwnPropertyNames 返回非Symbol屬性數組 yes yes no no
Object.getOwnPropertySymbols 返回Symbol屬性數組 yes yes no yes
Reflect.ownKeys 返回屬性數組 yes yes no yes

五種武器裡最牛的就是Reflect.ownKeys瞭,無論Symbol還是不可枚舉通吃, 簡直就是Object.getOwnPropertyNames和Object.getOwnPropertySymbols合體的效果。

擴展

Object.values

獲取對象自身所有可枚舉屬性(不包括Symbol類型)的值組成的數組

代碼清單7

Object.values(obj).map((val)=>{
    console.log(val);
});
/*
自有可枚舉屬性1
自有可枚舉屬性2
*/

Object.entries

獲取對象自身所有可枚舉屬性(不包括Symbol類型)的鍵值對數組

代碼清單7

Object.entries(obj).map((val)=>{
    console.log(val);
});
/*
[ 'job1', '自有可枚舉屬性1' ]
[ 'job2', '自有可枚舉屬性2' ]
*/

hasOwnProperty

檢測一個對象自身屬性中是否含有指定的屬性,返回boolean

引用自MDN: JavaScript 並沒有保護 hasOwnProperty 屬性名,因此某個對象是有可能存在使用這個屬性名的屬性,所以直接使用原型鏈上的 hasOwnProperty 方法

代碼清單8

for(var attr in obj){
    if(Object.prototype.hasOwnProperty.call(obj,attr)){
        console.log("自有屬性::",attr);
    }else{
        console.log("繼承屬性::",attr);
    }
}
/*
自有屬性:: job1
自有屬性:: job2
繼承屬性:: name
*/

propertyIsEnumerable

檢測一個屬性在指定的對象中是否可枚舉,返回boolean

代碼清單9

Reflect.ownKeys(obj).map((attr) => {
    if (Object.prototype.propertyIsEnumerable.call(obj, attr)) {
        console.log("可枚舉屬性::", attr);
    } else {
        console.log("不可枚舉屬性::", attr);
    }
});
/*
可枚舉屬性:: job1
可枚舉屬性:: job2
不可枚舉屬性:: address
可枚舉屬性:: Symbol(自有可枚舉symbol)
不可枚舉屬性:: Symbol(自有不可枚舉symbol)
*/

參考

MDN Object

總結

到此這篇關於javascript遍歷對象的五種方式的文章就介紹到這瞭,更多相關javascript遍歷對象內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: