阅读 344

Javascript 对象的循环遍历

这是我参与更文挑战的第3天,活动详情查看: 更文挑战

一、对象的遍历方法

  1. for ... in
  2. Object.keys(), Object.values(), Object.entries()
  3. Object.getOwnPropertyNames()
  4. Object.getOwnPropertySymbols()
  5. Reflect.ownKeys()

二、对象属性遍历次序规则

以上5种方法遍历对象的属性时都遵守同样的属性遍历次序规则

  1. 属性名为数值,按照数值升序排序
  2. 属性名为字符串,按照生成时间升序排序
  3. 属性名为Symbol,按照生成时间升序排序

三、遍历方法对比

遍历方法自身属性继承属性可枚举性Symbol类型
for ... in自身继承可枚举不包含
Object.keys()自身可枚举不包含
Object.getOwnPropertyNames()自身可枚举和不可枚举不包含
Object.getOwnPropertySymbols()自身所有Symbol属性
Reflect.ownKeys()自身可枚举和不可枚举包含

四、遍历方法举例

以下的测试都是基于下面给出的对象,对象的属性特性已进行配置。
对于属性名为 Attr_X-X 的属性,
两个数字分别代表是否是自身属性和是否可枚举
第一个X表示———— 0:对象本身的属性 1:对象原型上的属性
第二个X表示———— 0:不可枚举 1:可枚举


let tep_0_0 = Symbol(`tep_0_0`)
let tep_0_1 = Symbol(`tep_0_1`)
let tep_1_0 = Symbol(`tep_1_0`)
let tep_1_1 = Symbol(`tep_1_1`)


let obj = {
    "name_0-1": `Happy_0-1`,
    "fruit_0-1": `Apple_0-1`,
    "country_0-1": `China_0-1`,
    "name_0-0": `Happy_0-0`,
    "fruit_0-0": `Apple_0-0`,
    "country_0-0": `China_0-0`,

    [tep_0_0]: `miracle_0-0`,
    [tep_0_1]: `miracle_0-1`,

    hello_0_1(){
        console.log(`fun_0-1`)
    },

    hello_0_0(){
        console.log(`fun_0-0`)
    }
}

obj.__proto__ = {
    "name_1-1": `Happy_1-1`,
    "fruit_1-1": `Apple_1-1`,
    "country_1-1": `China_1-1`,
    "name_1-0": `Happy_1-0`,
    "fruit_1-0": `Apple_1-0`,
    "country_1-0": `China_1-0`,

    [tep_1_0]: `miracle_1-0`,
    [tep_1_1]: `miracle_1-1`,

    hello_1_1(){
        console.log(`fun_1-1`)
    },

    hello_1_0(){
        console.log(`fun_1-0`)
    }
}

Object.defineProperty(obj, "name_0-0", {
    value: "Happy_0-0",
    writable: true,
    enumerable: false,
    configurable: true,
}
)

Object.defineProperty(obj, "fruit_0-0", {
    value: "Apple_0-0",
    writable: true,
    enumerable: false,
    configurable: true,
}
)

Object.defineProperty(obj, "country_0-0", {
    value: "China_0-0",
    writable: true,
    enumerable: false,
    configurable: true,
}
)

Object.defineProperty(obj, "name_1-0", {
    value: "Happy_1-0",
    writable: true,
    enumerable: false,
    configurable: true,
}
)

Object.defineProperty(obj, "fruit_1-0", {
    value: "Apple_1-0",
    writable: true,
    enumerable: false,
    configurable: true,
}
)

Object.defineProperty(obj, "country_1-0", {
    value: "China_1-0",
    writable: true,
    enumerable: false,
    configurable: true,
}
)

Object.defineProperty(obj, tep_0_0, {
    value: "miracle_0-0",
    writable: true,
    enumerable: false,
    configurable: true,
}
)

Object.defineProperty(obj, tep_1_0, {
    value: "miracle_1-0",
    writable: true,
    enumerable: false,
    configurable: true,
}
)

Object.defineProperty(obj, "hello_0_0", {
    value: "miracle_0-0",
    writable: true,
    enumerable: false,
    configurable: true,
}
)

Object.defineProperty(obj, "hello_1_0", {
    value: "miracle_1-0",
    writable: true,
    enumerable: false,
    configurable: true,
}
)


复制代码

for in


// 未进行过滤
for (let key in obj) {
    console.log(obj[key])
}

// 已进行过滤
for (const i in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, i)) {
        console.log(obj[i]);
    }
}

复制代码

image.png

image.png

总结

for in 循环会遍历对象自身继承可枚举属性,不包含Symbol属性。

如果只需要对象自身的属性,可以通过 Object.prototype.hasOwnProperty() 进行过滤。

Object.keys


console.log(Object.keys(obj))

复制代码

image.png

总结

ES5 引入了 Object.keys 方法,返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性(不含 Symbol 属性)的键名。

ES2017 引入了跟Object.keys配套的 Object.valuesObject.entries ,作为遍历一个对象的补充手段,供for...of循环使用。

这三种方法可以访问到的属性是相同的,只是分别返回了 属性名属性值[属性名,属性值]键值对

Object.getOwnPropertyNames()


console.log(Object.getOwnPropertyNames(obj))

复制代码

image.png

总结

Object.getOwnPropertyNames返回一个数组,包含对象自身的所有属性(不含 Symbol 属性,但是包括不可枚举属性)的键名。

Object.Object.getOwnPropertySymbols()


console.log(Object.getOwnPropertySymbols(obj))

复制代码

image.png

总结

Object.getOwnPropertySymbols返回一个数组,包含对象自身所有 Symbol 属性的键名。

Reflect.ownKeys()


console.log(Reflect.ownKeys(obj))

复制代码

image.png

总结

Reflect.ownKeys返回一个数组,包含对象自身的(不含继承的)所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举。

基本等同于Object.getOwnPropertyNames与Object.getOwnPropertySymbols之和。

文章分类
前端
文章标签