如何使用Object.defineProperty()
1、先看一下Object.defineProperty的使用方法
Object.defineProperty(obj,'属性',{
value:'1', //该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。
configurable: false, //当且仅当该属性的 configurable 键值为 true 时,该属性的描述符才能够被改变,
同时该属性也能从对应的对象上被删除。默认为 false。
enumerable: false, //当且仅当该属性的 enumerable 键值为 true 时,该属性才会出现在对象的枚举属性中。
writable: false, //当且仅当该属性的 writable 键值为 true 时,属性的值,也就是上面的 value,
才能被赋值运算符改变。默认为 false。
get(){ //属性的 getter 函数,当访问该属性时,会调用此函数。执行时不传入任何参数,
但是会传入 this 对象(由于继承关系,这里的this并不一定是定义该属性的对象)
},
set(value){ //属性的 setter 函数,如果没有 setter,则为 undefined。当属性值被修改时,会调用此函数。
该方法接受一个参数(也就是被赋予的新值),会传入赋值时的 this 对象。
},
})
value和get,set,writable不能同时存在.如果一个描述符同时拥有 value 或 writable 和 get 或 set 键,则会产生一个异常。
2、简单的可以理解一下
(1)、我们定义一个对象 var obj = {
text: 'xxx'
};
(2)、为了直观的了解到我们对某个属性的拦截,我们简单的实现一下在输入框中输入,同步输出。
<div>
<input type="text" id="input">
<p id="myInput"></p>
</div>
const obj = {}
Object.defineProperty(obj,'text',{
get() {
return obj
},
set(v) {
document.getElementById('input').value = v
document.getElementById('myInput').innerText = v
}
})
input.addEventListener('keyup',(e)=>{
obj.text = e.target.value
})
3、依次举例说明每个参数的含义。
configurable:表示对象的属性是否可以被删除,以及除 value 和 writable 特性外的其他特性是否可以被修改。
举例:
const obj = {
name: 3
};
const value = 1;
Object.defineProperty(obj,'name',{
configurable: true, // 如果改成false 则删不掉
get() {
return value
}
})
delete obj.name
console.log(obj.name) // undefined
value:对象属性的默认值,默认为undefined
举例:
const obj = {
name: 3
};
Object.defineProperty(obj,'name',{
value: 1
})
console.log(obj.name) // 1
enumerable:对象的属性是否可以枚举,比如 for in Object.keys()
举例:
const obj = {
a:1,
b:2,
c:3
};
for(let i in obj){
console.log(i) // a,b,c
}
如果加上了这个属性呢?
Object.defineProperty(obj,'a',{
enumerable: false
})
for(let i in obj){
console.log(i) // b,c
}
可以看出来 a 这个属性已经打印出来了
console.log(Object.keys(obj)) // ["b","c"]
writable: 对象对应的值能否改变
const obj = {
a:1
};
Object.defineProperty(obj,'a',{
writable: false
})
obj.a = 3
console.log(obj.a) // 1
get(){}:如果有getter,当访问该属性时,会调用此函数。会有this,但是this不一定是定义该属性的对象。 该函数的返回值会被用作属性的值。
举例:
const obj = {
a:1
};
Object.defineProperty(obj,'a',{
get() {
return 2
}
})
console.log(obj.a) // 2
set(value){} : 当属性值被修改时,会调用此函数。该方法接受一个参数(也就是被赋予的新值),会传入赋值时的 this 对象
举例:
const obj = {
a:1
};
Object.defineProperty(obj,'a',{
set(v) {
console.log(v) // 3
}
})
obj.a = 3
vue是 数据劫持,结合发布订阅模式,使用的就是Object.defineProperty()劫持各个属性的setter,getter,当对象发生变化的时候,给订阅者发送消息,触发回调函数处理。