Object.defineProperty 数据监听模拟

发布时间 2023-05-24 14:57:47作者: 浅唱年华1920

通过 Object.defineProperty 监听对象,深度监听通过递归

数组监听通过重写数组原型方法

// 重新定义数组原型
  const oldArrayPrototty = Array.prototype;
  // 创建新对象,原型指向oldArrayPrototty,再扩展新的方法不会影响原型
  const arrProto = Object.create(oldArrayPrototty);
  ['push', 'pop', 'shift', 'unshift', 'splice', 'join'].forEach(methodName => {
    arrProto[methodName] = function() {
      console.log('数组更新');
      return oldArrayPrototty[methodName].call(this, ...arguments);
      // Array.prototype[methodName].call(this, ...arguments); 调用数组的原型方法
    }
  })
 function defineReactive(target, key, value) {
    observer(value);// 深度监听
    Object.defineProperty(target, key, {
      get() { return value },
      set(newValue) {
        if (newValue !== value) {
          value = newValue;
          observer(newValue);// 深度监听
          console.log('数据更新');
        }
      }
    })
 }
 function observer(target) {
  if (typeof target !== 'object' || target == null)  return target;
  // 数组监听处理
  if (Array.isArray(target)) {
    target.__proto__ = arrProto;
  }
  for(let key in target) {
    // 过滤原型属性
    if (target.hasOwnProperty(key)) {
      defineReactive(target, key, target[key]);
    }
  }
 }

let data = { arr: [100, 200, 300], name: '张三'};
observer(data);
data.arr.pop();
data.name = '李四';