Object.defineProperty
object.defineproperty()方法俗称属性拦截器,会直接在一个对象上定义一个新的属性,或修改一个对象现有的属性,并返回这个对象。
语法
object.defineproperty(obj, prop, descriptor)
参数
obj:要在其上定义的对象
prop:要定义或修改的属性的名称
descriptor:将被定义或修改的属性描述符
返回值
被传递给函数的对象
var o = { values: 'hello' } object.defineproperty(o, 'key', { value: 9, writable: true, enumerable: true, configurable: true }); console.log(o.key) // 输出结果:9 console.log(o.values) // 输出结果:hello object.defineproperty(o, 'values', { value: 'hello world', writable: true, enumerable: true, configurable: true }); console.log(o.values) // 输出结果:hello world
属性描述符
对象里目前存在的属性描述符有两种主要形式:数据描述符和存取描述符
数据描述符:一个具有值得属性,该值可能是可写的,也可能不是可写的。
存取描述符:由getter和setter函数描述的属性。
描述符必须是两者其一,不能同时是两者。
数据描述符
configurable
dang当且仅当该属性的configurable 为true时,该属性描述符才能够被改变,同时该属性也能从对应的对象上删除。默认为false。
enumerable
当且仅当该属性为true时,该属性才能够出现在对象的枚举属性中。默认为false。
value
该属性对应的值可以使任何有效的javascript值。默认为undefined
writable
当该属性为true时,value才能被赋值运算符改变。默认为false。
var o = { values: 'hello' } object.defineproperty(o, 'values', { writable: false, // writable: false 赋值运算无法改变属性的值 enumerable: false, configurable: true }); console.log(o.values) // 结果:hello o.values = 10; console.log(o.values) // 结果:hello // enumerable: true 输出结果:values // enumerable: false 无输出 for(let key of object.keys(o)){ console.log(key) }
var o = { values: 'hello' } object.defineproperty(o, 'values', { writable: true, enumerable: true, configurable: false }); o.a = 1; console.log(o) // { values: 'hello', a: 1 } delete o.a console.log(o) // { values: 'hello' } delete o.values console.log(o) // { values: 'hello' }
存取描述符
存取描述符除了含有以上enumerable和configurable之外还有以下可选键值。
get
给一个属性提供getter的方法,如果没有getter则为undefined。当该属性被访问时,该方法会被执行,该方法执行时没有参数传入,但是会传入this对象(由于继承关系,这里的this并不一定是该属性的对象)。默认为undefined。
set
一个给属性提供 setter 的方法,如果没有 setter 则为 undefined
。当属性值修改时,触发执行该方法。该方法将接受唯一参数,即该属性新的参数值。默认为undefined。
描述符可同时具有的属性
configurable | enumerable | value | writable | get | set | |
数据描述符 | yes | yes | yes | yes | no | no |
存取描述符 | yes | yes | no | no | yes | yes |
如果一个描述符不具有value、writable、get和set任意一个关键字,那么它将被认为是一个数据描述符。如果同时具有value或writable和get或set关键字,将会产生异常
var o = { values: 'hello' } object.defineproperty(o, 'values', { writable: true, enumerable: true, configurable: true, set(newval){ o = newval } }); o.values = 100; console.log(o)
mdn文档
https://developer.mozilla.org/zh-cn/docs/web/javascript/reference/global_objects/object/defineproperty#parameters
推荐阅读
-
vue.js利用Object.defineProperty实现双向绑定
-
vue.js的双向数据绑定Object.defineProperty方法的神奇之处
-
js中Object.defineProperty()方法的不详解
-
JavaScript的Object.defineProperty详解
-
使用Object.defineProperty如何巧妙找到修改某个变量的准确代码位置
-
vue源码学习之Object.defineProperty 对数组监听
-
vue源码学习之Object.defineProperty对象属性监听
-
ES6 Proxy 与 Object.defineProperty 的优劣对比?
-
Proxy 与 Object.defineProperty对比
-
ES6之Object.defineProperty 和 Proxy 区别