// 重写数组方法
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()内数据层级