[js]数据劫持Object.defineProperty
修改了属性值希望能感知到
- 直接修改
- 通过方法修改
obj = {};
Object.defineProperty(obj, 'name', {
get(){
return value
},
set(val){
console.log("111111");
value = val
}
});
obj.name = "maomao";
console.log(obj.name);
function observer(obj) {
if (typeof obj == "object") {
for (let key in obj) {//重新对对象中属性定义
defineReactive(obj, key, obj[key])
}
}
}
function defineReactive(obj, key, value) {
observer(value); //针对value是对象,递归检测
Object.defineProperty(obj, key, {
get() {
return value;
},
set(val) {
observer(val);//针对所设置的val是对象
console.log("数据改变了");
value = val
}
})
}
let obj = {
name: "maoatai",
age: {
age: 22
}
};
observer(obj);
// - 改变属性测试
// obj.age.age = 23;
// obj.age = {
// name: 1
// };
// obj.age.name = 2;
// obj.x = 111; //新增的属性不会被劫持
obj.age = [1, 2, 3, 4];
// -使用方法测试
// obj.age.push(11);//无法触发
// let oldPush = Array.prototype.push;
// Array.prototype.push = function (value) {
// console.log('数组中数据更新了');
// oldPush.call(this, value)
// };
// obj.age.push(11);//可以触发
let arr = ['push', 'pop', 'shift', 'unshift'];
arr.forEach(method => {
let oldPush = Array.prototype[method];
Array.prototype[method] = function (value) {
console.log('数组中数据更新了');
oldPush.call(this, value)
};
});
obj.age.push(11);
obj.age.length--;//但是这种通过操作长度或索引的方式无法被劫持