一个是vue3的呼应式原理,一个是vue2的,那两者的实质性差异究竟是什么?

看看proxyMDN 上是怎样说的哈。

根底-proxy与defineProperty的差异?
来咯,分析一下这个 which引导的主语从句。这个proxy目标能让你为另一个目标创建署理,能够阻拦和从头界说那个目标的根本操作 。大致就这样了啊。

好了回到js来,那什么又是目标的根本操作呢?赋值?读取特点?删除特点?遍历?啊这些都是在语法层面上的操作。这其实是js这门语言为了让开发者使用起来愈加便利或者是让程序的可读性更好,搞出来的一种共同的语法(其实能够这样理解啊),那实际上,咱们在使用语法的时分,在真实履行这些代码的时分,会转换为一个函数。

obj.a; // 【GET】
obj.b = 3; //【SET】
delete obj.a;//【DELETE】

例如在读取目标特点的时分,运转的函数是GET。这些内部运转的办法便是它的根本操作

翻开 ecma 262文档看看目标的内部办法。

根底-proxy与defineProperty的差异?
有一个办法Object.defineProperty,其实在便是这个函数,也是便是目标的特点了,那其实内部履行的便是DefineOwnProperty这个办法,你看接纳的参数都一样。

来看看proxy,它有一堆的内部办法,每一个办法都对应一个捕获器也能够叫做圈套,这就对上了啊,用这个圈套去阻拦,然后你就掉进去了。一切的圈套都是可选的,如果没有界说对应的圈套,那就会保留源目标的默认行为。

根底-proxy与defineProperty的差异?

 const obj = {
    b: 40,
  };
  const handler = {
    get: function (target, prop) {
      console.log("prop", prop);
      return target[prop];
    },
  };
  const p = new Proxy(obj, handler);
  console.log("p.b", p.b);// 40

这种状况,让proxy署理obj,那proxy就阻拦了ojb的内部办法[[GET]],进而掉进了圈套函数里了。

proxy便是阻拦一切的根本操作defineProperty啥也没阻拦,而是在调用defineOwnProperty这个根本操作。

所以许多现象便是来源于这个这个状况,嗯便是上面这种。

比方说vue2,调用数组push办法,这一进程怎样阻拦?比方设置length,用Object.defineProperty进行处理,直接就报错了(length特点无法被从头界说)。所以说,直接用经过数组目标去调原型里的push是没办法监听到的,是vue在中心刺进一个目标,这个目标重写了数组的办法。这样实际上咱们的数组目标去调的时分,调的其实是vue的那个目标,里边重写原型了。

vue3就不用这么麻烦了,proxy能够直接阻拦到目标的根本操作,所以在圈套函数里,就能够阻拦到arr.push(1)的操作了,包含是这个push特点、length特点、里边的改变的值等。

  const arr = [1, 2, 3];
  const p = new Proxy(arr, {
    get(target, prop) {
      console.log("get", prop);
      return target[prop];
    },
    set(target, prop, value) {
      console.log("set", prop, value);
      target[prop] = value;
      return true;
    },
  });
  p.push(1);
// get push
// get length
// set 3 1
// set length 4