一、介绍
Object.defineProperty() 在vue3以前的版本用于数据的双向绑定。
参数:
-
obj: 定于属性的对象
-
prop: 定义或修改的属性的名称或
Symbol。 -
descriptor: 要定义或修改的属性描述符。 descriptor的属性
-
value:该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为
undefined。 -
writable:当且仅当该属性的
writable键值为true时,属性的值,也就是上面的value,才能被赋值运算符(en-US)改变。默认为false。 -
configurable:当且仅当该属性的
configurable键值为true时,该属性的描述符才能够被改变,同时该属性也能从对应的对象上被删除。默认为false。 -
enumerable:当且仅当该属性的
enumerable键值为true时,该属性才会出现在对象的枚举属性中。默认为false。 -
get: 属性的 getter 函数,如果没有 getter,则为
undefined。当访问该属性时,会调用此函数。执行时不传入任何参数,但是会传入this对象(由于继承关系,这里的this并不一定是定义该属性的对象)。该函数的返回值会被用作属性的值。默认为undefined。 -
set: 属性的 setter 函数,如果没有 setter,则为
undefined。当属性值被修改时,会调用此函数。该方法接受一个参数(也就是被赋予的新值),会传入赋值时的this对象。默认为undefined。
二、例子
writable属性:
常规使用
const obj = {}
Object.defineProperty(obj, 'name', {
})
obj.name = 'name'
console.log(obj)
这里修改了obj对象下的name值,但是输出中并未显示,name为undefined
如图
这里开始改变它的值
const obj = {}
Object.defineProperty(obj, 'name', {
writable: true
})
obj.name = '积雷山摩云洞'
console.log(obj)
set与get
修改obj的属性,为obj添加一个name
const obj = {}
let name = null
Object.defineProperty(obj, 'name', {
set: function(newVal) {
console.log('set '+newVal)
name = newVal
// return oldVal = newVal
},
get: function() {
console.log('get '+ name)
return name
}
})
obj.name
obj.name = '积雷山摩云洞1'
console.log(obj)
可以看到obj.name 触发了get事件, 而重新设置属性,则触发了set属性
这里有个过程,第一次obj.name时触发了get,第二次赋值时触发了set,这时执行了console输出,当点击name之后,再次触发了get属性
数据劫持的流程
未完待续!!!