属性的可枚举性
为什么要先说属性的可枚举性问题,因为一些方法会根据属性的可枚举型进行操作,其中遍历就是一种,遍历的一些方法会忽略掉可枚举属性值为false
的属性,我知道到这里读者可能会有一些绕圈子:什么叫可枚举属性值为false
的属性?下面我带大家来一探究竟
对象中的所有属性都具有一个描述对象,对你没有看错,其实在我们看到的一个普通对象中的每一个属性值都包含一对象,即描述对象,它是用来控制属性的行为
let obj = { name:"猪痞恶霸", age:20 } 复制代码
比如上面声明了一个普通的对象,含有name
与age
属性,这两个属性都具有一个描述对象,那我们怎么能拿到这个描述对象呢?
来看看这个方法:Object.getOwnPropertyDescriptor()
,它可以拿到指定对象的某属性的描述对象,所以参数有两个,一个是指定对象,一共是指定对象的某属性
Object.getOwnPropertyDescriptor(obj,"name") 复制代码
如上图,我们拿到了obj
对象name
属性的描述对象,描述对象内就包含了我们想知道的东西,enumerable
就是描述对象可枚举属性,那么在这个例子中值为true
,所以就能解释上面那句看不懂的话:可枚举属性值为false
的属性,在这里的解释就为:obj
对象内的name
属性的描述对象内的可枚举属性值为true
。
遍历对象
for...in
for...in
可以遍历对象的所有可枚举属性,包括对象本身的和对象继承来的属性
let obj = { name:"ned", like:"man" } Object.defineProperty(obj, 'age', { value: "18", enumerable: false }); for(item in obj) { console.log(item) } 复制代码
看一看上面的例子,我们使用Object.defineProperty
的形式来设置对象的描述对象,将其可枚举属性值设为false
,使用for...in
遍历,其没有被打印出来
其实for...in
的特性会导致一个问题,其继承的属性会被遍历到,所以当我们不想要遍历被继承的属性,那么我们就可以使用Object.keys()
Object.keys()
Object.keys()
方法可以遍历到所有对象本身的可枚举属性,但是其返回值为数组
let obj = { name:"ned", like:"man" } Object.keys(obj) // ['name', 'like'] 复制代码
到这里我们一般是使用Object.keys()
来代替for...in
遍历操作,除此之外,为了代替for...in
,又新增了与Object.keys()
配套的遍历方法,下面我们来看看
Object.values()
Object.values()
与Object.keys()
遍历对象的特性是相同的,但是其返回的结构是以遍历的属性值构成的数组
let obj = { name:"cornd", age:10 } Object.values(obj) // ['cornd', 10] Object.defineProperty(obj, 'like', { value: "coding", enumerable: false }); Object.values(obj) // ['cornd', 10] 复制代码
声明了一个对象,使用Object.values()
返回对象的所有自身可枚举属性的属性值,通过设置新的属性值并将其描述对象内的enumerable
设置为false
,就可以看到Object.values()
的特性
Object.entries()
Object.entries()
的返回值为Object.values()
与Object.keys()
的结合,也就是说它会返回一个嵌套数组,数组内包括了属性名与属性值
let obj = { name:"cornd", age:10 } Object.entries(obj) // [['name', 'cornd'],['age', 10]] 复制代码
其遍历特性与Object.values()
和Object.keys()
相同,不再赘述。