遍历一个对象身上属性的方法有哪些
# 首先列举一下有哪几种方式:
- Object.keys
- for in
- Object.getOwnPropertyNames
# 用法和区别
首先我们创建一个对象用于枚举属性,方便做对比:
function Person(name, age) {
this.name = name
this.age = age
}
Person.prototype.sex = 1 // 原型上定义一个属性 sex
var per = new Person('芒果', 25)
Object.defineProperty(per, 'hobby', {
enumerable: false // 给per定义一个不可枚举的属性hobby
})
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 1. Object.keys
该方法返回一个对象可枚举的所有属性组成的数组,不包含继承属性
Object.keys(per) // ["name", "age"]
per.__proto__.sex // 1
// 可以看出只打印出了per自身的两个属性,原型上的sex并未输出
1
2
3
4
5
2
3
4
5
# 2. for in
会遍历对象中所有的可枚举属性(包括自有属性和继承属性)
for (item in per) {
console.log(item) // name, age, sex
}
// 可以看出打印出了per自身的属性和原型上继承来的sex属性,但是不可枚举属性hobby并没有输出
1
2
3
4
5
2
3
4
5
# 3. Object.getOwnPropertyNames
返回对象的所有自身属性的属性名(包括不可枚举的属性)组成的数组,但不会获取原型链上的属性。
Object.getOwnPropertyNames(per) // ["name", "age", "hobby"]
// 可以看出打印出了per自身的属性包括了不可枚举的hobby,但是没有输出原型上的属性sex
1
2
3
2
3
# 注意:
当Symbol类型的值作为一个对象的属性时,上面这三种方式都是无法获取到的,在上面的基础上我们给per加一个属性:
person[Symbol()] = "SYMBOL"
Object.getOwnPropertyNames(per) // ["name", "age", "hobby"]
for (item in per) {
console.log(item) // name, age, sex
}
Object.keys(per) // ["name", "age"]
// 可以看出这三种方式都没有输出 这个属性
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
因此利用该特性,我们可以把一些不需要对外操作和访问的属性使用Symbol来定义。
想要获取到Symbol类型的属性,可以使用 Object.getOwnPropertySymbols
方法。