[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--;//但是這種通過操作長度或索引的方式無法被劫持


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM