定义:指那些内部 “可枚举” 标志设置为 true 的属性,对于通过直接的赋值和属性初始化的属性,该标识值默认为即为 true,对于通过 Object.defineProperty 等定义的属性,该标识值默认为 false。可枚举的属性可以通过 for…in 循环进行遍历(除非该属性名是一个 Symbol)。
获取可枚举属性:
- for-in
- Object.keys
两者的区别:
结果:for-in是遍历,而Objec.keys是返回一个数组
原理:for-in会走原型链,而Object.keys不会,就是for-in会遍历到继承的可枚举属性,后者则只获取自身的
1
2
3
4
5
6
7
8
9
10var obj = {
a: 1,
b: 2
}
console.log(Object.getOwnPropertyDescriptors(obj))
Object.prototype.test = 2
for(var x in obj) {
console.log(x) //a,b,test
}
Object.keys(obj) //["a", "b"]
判断方法:
getOwnPropertyDescriptor方法获取指定对象指定属性的描述对象1
2
3
4
5
6
7
8
9
10
11
12var obj = {
a: 1,
b: 2
}
console.log(Object.getOwnPropertyDescriptor(obj, 'a'))
{
configurable: true
enumerable: true
value: 1
writable: true
__proto__: Object
}getOwnPropertyDescriptors方法返回指定对象的所有自身属性(非继承属性的)描述对象1
2
3
4
5
6
7
8
9
10var obj = {
a: 1,
b: 2
}
console.log(Object.getOwnPropertyDescriptors(obj))
{
a: {value: 1, writable: true, enumerable: true, configurable: true}
b: {value: 2, writable: true, enumerable: true, configurable: true}
__proto__: Object
}propertyIsEnumerable,返回一个布尔值表示,指定的属性是否可枚举1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31var obj = {
a: 1
}
console.log(Object.getOwnPropertyDescriptor(obj, 'a'))
{
configurable: true
enumerable: true
value: 1
writable: true
__proto__: Object
}
var arr = [1]
console.log(Object.getOwnPropertyDescriptor(arr, 0))
{
configurable: true
enumerable: true
value: 1
writable: true
__proto__: Object
}
console.log(Object.getOwnPropertyDescriptor(arr, 'length'))
{
configurable: false
enumerable: false
value: 1
writable: true
__proto__: Object
}
//发现enumerable为true,所以属性a是可枚举的
//我们发现数组的length的描述对象的enumerable属性是false,所以他是不可枚举,在for-in遍历的时候,遍历不到,类似的还有对象原型的toSring方法
不能枚举的属性:
- js基本数据类型自带的原型属性不可枚举
- 通过
Object.defineProperty()方法指定的enumerable为false的属性不可枚举
总的来说,操作中引入继承的属性会让问题复杂化,大多数时候,我们只关心对象自身的属性。所以,尽量不要用for...in循环,而用Object.keys()代替