js中挺重要的一个api,vue2的数据劫持也是基于此。
Object.defineProperty 会直接在对象上定义一个新的属性,或者修改一个现有属性。语法如下:
1 | Object.defineProperty(obj, key, descriptor) |
- obj:将要被修改的对象
- key:将要被修改对象的名称或者symbol
- descriptor:对象的描述符。此函数的核心点
下面是为对象foo添加一个新的属性b的例子:1
2
3
4
5
6
7const foo = {a: 1}
console.log(foo.a) // 1
console.log(foo.b) // undefined
Object.defineProperty(foo, 'b', {
value: 2
})
console.log(foo.b) // 2
描述符
对象一共存在 6种
描述符,configurable
、enumerable
、value
、writeable
、get
、set
。
这6种描述符,并不是可以随意组合使用。 value
或writeable
不能够和get
或set
同时使用,编译会报错。
描述符可以分为两类:数据描述符
和存取描述
符,如下展示不同描述符可以使用的键值:
configurable | enumerate | value | writable | get | set | |
---|---|---|---|---|---|---|
数据描述符 | yes | yes | yes | yes | no | no |
存取描述符 | yes | yes | no | no | yes | yes |
configurable
default:false
决定属性是否可以被修改
如果旧值设置为false,只能够单向改变writable
为false
enumerable
default:false
决定是否可以被Object.keys
和for..in
枚举
value
default:undefined
可以是任何有效地js值(数值,对象,函数等)
writable
default:false
只有设置为true
时,上面的value值才可以被改变
get
default:undefined
属性的 getter 函数,如果没有 getter,则为 undefined。当访问该属性时,会调用此函数。执行时不传入任何参数,但是会传入 this 对象(由于继承关系,这里的this并不一定是定义该属性的对象)。该函数的返回值会被用作属性的值。
set
default:undefined
属性的 setter 函数,如果没有 setter,则为 undefined。当属性值被修改时,会调用此函数。该方法接受一个参数(也就是被赋予的新值),会传入赋值时的 this 对象。