SOURCE

let data = {
    a:1,
    b:2,
    c:[1,3,5]
}

// 更新视图
function updateView(){
    console.log("视图更新...")
}

// 重新定义数组原型
const oldArrayProperty = Array.prototype;
// 创建新的对象,原型指向 oldArrProperty,再扩展新的方法不会影响原型
const arrProto = Object.create(oldArrayProperty); 

['push','pop','shift','unshift','splice'].forEach(methodName=>{

    arrProto[methodName] = function (){
        updateView();
        oldArrayProperty[methodName].call(this,...arguments);
    }
})
// 重新定义属性,监听
function defineReactive(target,key,value){
    // 深度监听
    observer(value)
    // 监听
    Object.defineProperty(target,key,{
        get(){
            return value;
        },
        set(newValue){
            // 重新设置新值
            if(newValue !== value){
                //深度监听
                observer(newValue);
                value = newValue;

                // 更新视图
                updateView();
            }
        }
    })
}

//监听对象属性
function observer(target){
    // 如果不是对象或者数组
    if(typeof target !== 'object' || target === null) return target;

    if(Array.isArray(target)){
        target.__proto__ = arrProto;
    }
    // 遍历target对象
    for(let key in target){
        defineReactive(target,key,target[key])
    }
}


observer(data);

data.a = 3;
data.b = 5;
data.c.push(5)
data.c.push(5)
data.c.push(5)
console 命令行工具 X clear

                    
>
console