[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--;//但是这种通过操作长度或索引的方式无法被劫持
posted @ 2019-12-11 15:25  mmaotai  阅读(1850)  评论(0编辑  收藏  举报