Vue2.0响应式原理以及重写数组方法

// 重写数组方法
let oldArrayPrototype = Array.prototype;
let proto = Object.create(oldArrayPrototype);
['push', 'shift', 'unshift'].forEach((met) => {
    proto[met] = function () { // 函数劫持 (重写函数 继续调用旧方法)
        upDataView(); // 切片编程
        oldArrayPrototype[met].call(this, ...arguments)
    }
});

function observer (target) {
    if (typeof target !== 'object' || target === null) {
        return target
    }
    if (Array.isArray(target)) {
        target.__proto__ = proto
        // Object.setPrototypeOf(target, proto)
    }
    for (let key in target) {
        defineReactive(target, key, target[key])
    }
}

function defineReactive(target, key, value) {
    observer(value); // 递归调用
    Object.defineProperty(target, key, {
        get() {
            return value
        },
        set(newValue) {
            if (newValue !== value) {
                observer(newValue); // 新属性添加get set
                upDataView();
                value = newValue
            }
        }
    })
}

function upDataView () {
    console.log('视图更新')
}

// 使用 Object.defineProperty 添加 getter setter
let data = {name: 'wyq', age: 18};
observer(data);
data.name = '王瘦瘦';

// 1.如果数据不存在 新增属性不会是响应式
// 2.默认递归
// 3.数组length无效

  尽量减少data()内数据层级

原文地址:https://www.cnblogs.com/QQPrincekin/p/11970960.html