1.Object.defineProperty()的作用就是直接在一個(gè)對(duì)象上定義一個(gè)新屬性熔恢,或者修改一個(gè)已經(jīng)存在的屬性 (getter setter)
let obj = {
_a:'',
get a(){
// todo ...
return this._a
},
set a(value){
this._a = value
}
}
obj.a = 100;// 需要借用一個(gè)第三方變量來(lái)中轉(zhuǎn)
console.log(obj.a);
2.Object.defineProperty(obj, prop, descriptor)
- obj:必需。目標(biāo)對(duì)象
2 .prop:必需。需定義或修改的屬性的名字
- descriptor:必需。目標(biāo)屬性所擁有的特性
let obj2 ={a:1};
let val = '';
Object.defineProperty(obj2,'a',{
configurable:true,//是否可刪除
//writable:false,//是否可重寫
enumerable:true,//是否可 for in 原型上的方法
get(){
return val
},
set(value){
val = value;
}
})
obj2.a=999
console.log(obj2.a)
3.vue中數(shù)據(jù)劫持 給每個(gè)對(duì)象都添加一個(gè) getter和setter 當(dāng)值變化可以 可以實(shí)現(xiàn)更新視圖的功能
// vue源碼
function observer(obj) {
// 缺陷就是無(wú)法監(jiān)控?cái)?shù)組的變化
if (typeof obj !== "object" || obj == null) {
return;
}
for (let key in obj) {
// 因?yàn)閐efineProperty 需要一個(gè)公共的值去修改
defineReactive(obj, key, obj[key]);
}
}
let updateView = () => {
// 更新方法
console.log("更新");
};
// obj => {a:1,b:2} key=> a / b value = 1/2
function defineReactive(obj, key, value) {
// Object.defineProperty
observer(value); // 遞歸增加getter和setter
Object.defineProperty(obj, key, {
get() {
return value;
},
set(val) {
updateView();
value = val;
}
});
}
observer(obj);
obj.a = 100;
console.log(obj.a);