数组没有使用defineProperty,主要是性能考虑,采用的是函数劫持,通过aop编程重写了原型的7个方法,用户在调用的时候采用这七个方法,增加如果是新增的数据就会再次被劫持,最终调用数组的原型方法(数组的长度以及数组的索引不观测(只有新增的复杂数据才会检测))

const oldArrayPrototype = Array.prototype;

const arrayPrototype = Object.create(oldArrayPrototype);

let methods = ["push", "pop", "shift", "unshift", "reverse", "sort", "splice"];

methods.forEach(method => {
  //用户调用push方法会先通过自己重写的方法,然后再调用数组原来的方法
  arrayPrototype[method] = function (...args) {
    //改写方法
    let inserted;
    switch (method) {
      case "push":
      case "unshift":
        inserted = args;
        break;
      case "splice":
        inserted = args.slice(2);
      default:
        break;
    }
    if (inserted) {
      //对新增的数据再进行观测
      console.log("有插入的数据,继续观测新增的数据");
    }
    return oldArrayPrototype[method].call(this, ...args);
  };
});


const data = [1, 2, 3]

Object.setPrototypeOf(data, arrayPrototype)

data.push("3")
Last modification:October 12, 2021
If you think my article is useful to you, please feel free to appreciate