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