前言
之前在JavaScript 原型链机制的Object.getOwnPropertyNames
-> Object.keys
的时候提到枚举属性
1 | const arr = [1, 2, 3]; |
当时并没有写明白是怎么做到的,实际上每个对象里面的属性,都有几个不同的属性,可以讲成属性的属性(property.attributes),在例子里面发现了,Array.length
是不可枚举的,实际上 JavaScript 的基本包装类型原型属性都是不可枚举的,比如Object
,Array
,String
等等,都不可枚举。
创建枚举属性
在 javaScript 里面,如果直接赋值或者属性初始化的属性,enumerable
默认为true
,但是如果通过Object.defineProperty
,定义的属性就可以设置不同的内部属性,enumerable
默认为false
1 | function Foo() { |
基本设置就是用法就是这样,如果不要枚举,那就不写就好了。
enumerable
坑点
如果不了解一些方法操作符的运作,可以会变成一个坑点,下面这三个就是比较常用而且之前没提到的坑
1 | // hasOwnProperty 只要是自身的我全都要 |
其实实际应用最常会碰到的就是Array.length
的问题,剩下的比较少机会碰到吧,关于这一块其实是个大坑,相关 api 十分之多,但是应用场景十分之少,所以我不建议记住太多其他的,如果感兴趣偶尔去MDN 属性的可枚举性和所有权就好了
Object.defineProperty
既然提到了Object.defineProperty
也介绍一下,这个方法顾名思义是可以精确添加或者修改对象的属性,其实不仅仅可以定义enumerable
,还能定义是否可以配置或者删除(configurable
),什么类型的描述符。
在对象里面目前存在两种属性描述符,数据描述符和存取描述符。
- 数据描述符就是平常我们在用的有具体值的,可以写或者不可以写的。
- 存取描述符有点类似一个属性方法,由
getter-setter
组成。
可选属性
configurable
当为true
材可以改变这个描述符类型,比如本来是数据描述符,然后改成存取描述符,同时也决定这个属性是否允许被删除。默认false
enumerable
当为true
才是枚举属性。默认false
- 数据描述符特有属性
value
对应具体值。默认underfined
writable
决定是否可以改变值。默认false
- 存取描述符特有属性
get
一个getter
方法,当访问属性的时候被调用。默认underfined
writable
一个setter
方法,当改变属性的时候被调用。默认underfined
特有属性之间互斥,如果都没有默认是数据描述符。假如出现互斥同时有value
或writable
和get
或set
就会报错。
configurable
例子
1 | const foo = {}; |
只要配置了false
,无法做任何更改,也无法删除
writable
例子
1 | const foo = {}; |
writable
决定了是否可以修改属性,如果false
报错
存取描述符例子
1 | const foo = {}; |
其实存取描述符就就是getter
,setter
,当作两个方法,里面不一定要绑定this
的属性,也可以绑定别的,如果要绑定this
要考虑继承问题this
指向。
总结
这方面总括而言基本平时用不上,最多也就可能面试能用上…更何况我搜寻了一下网上的面试题,基本也没有提到……了解即可我认为。