// 重寫數組方法 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()內數據層級