JavaScript 内部属性
前言
之前在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材可以改变这个描述符类型,比如本来是数据描述符,然后改成存取描述符,同时也决定这个属性是否允许被删除。默认falseenumerable
当为true才是枚举属性。默认false- 数据描述符特有属性
value
对应具体值。默认underfinedwritable
决定是否可以改变值。默认false
- 存取描述符特有属性
get
一个getter方法,当访问属性的时候被调用。默认underfinedwritable
一个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指向。
总结
这方面总括而言基本平时用不上,最多也就可能面试能用上…更何况我搜寻了一下网上的面试题,基本也没有提到……了解即可我认为。