vue2与vue3响应式原理总结

vue2响应式原理

Object.defineProperty()

 // Object.defineProperty();
 // 有三个属性 (obj,prop,descriptor)  (对象,属性,描述项集合)
      function defineProperty() {
        var _obj = {};
        //1.声明一个属性a
        // Object.defineProperty(_obj, "a", {
        //   value: 1, //设置默认值
        // });

        //2.声明多个属性
        Object.defineProperties(_obj, {
          a: {
            value: 1,
          },
          b: {
            value: 2,
          },
        });
        return _obj;
      }
      var obj = defineProperty();
	  obj.a = 5
      console.log(obj);  //{a: 1, b: 2}   //属性值不可以修改
	  for (let k in obj){
		console.log(k + ':' + obj[k]);   //属性值不可枚举
	  }
	  delete obj.a   //属性值不可以删除
	  //总结:使用Object.defineProperties定义的属性不可以修改 删除 枚举
	

?? 如何可以进行修改

      function defineProperty() {
        var _obj = {};
        Object.defineProperties(_obj, {
          a: {
            value: 1,
            writable: true, //a属性可以进行修改
            enumerable: true, //a属性变为可枚举
            configurable: true, //a属性可以进行操作(删除)
          },
          b: {
            value: 2,
          },
        });
        return _obj;
      }
      var obj = defineProperty();
      obj.a = 5;
      console.log(obj); //{a: 5, b: 2}
      for (let k in obj) {
        console.log(k + ":" + obj[k]); //{a:5}
      }
      delete obj.a;
      console.log(obj); //{b:2}
      function defineProperty() {
        var _obj = {};
        var a = 1;
        //每一个属性定义的时候 getter 和 setter都是存在的
        Object.defineProperties(_obj, {
          a: {
            get() {},
            set(newVal) {
              a = newVal;
              var P = document.getElementsByTagName("p")[0];
              P.innerHTML = a;
            },
          },
          b: {},
        });
        return _obj;
      }
      var obj = defineProperty();
	  obj.a = 2  //会触发setter方法

触发getter setter 方法 -->每一个属性定义的时候 getter 和 setter都是存在的

      function defineProperty() {
        var _obj = {};
        var a = 1;
        //每一个属性定义的时候 getter 和 setter都是存在的
        Object.defineProperties(_obj, {
          a: {
            get() {
              return '"a" value is ' + a + ".";
            },
            set(newVal) {
              console.log(
                'The value "a" has been designed a new value ' + newVal + ""
              );
            },
          },
          b: {},
        });
        return _obj;
      }
      var obj = defineProperty();
      console.log(obj.a); //触发get方法   "a" value is 1.
      obj.a = 2; //会触发setter方法     The value "a" has been designed a new value 2

以上触发getter setter方法的过程就是 数据劫持,数据劫持其实就是将对象中属性变成可配置

vue3响应式原理

Proxy

      // Proxy ES6 中的构造函数
     function Proxy() {}
     var proxy = new Proxy();
      // defineProperty  劫持数据 -> 给对象进行扩展 -> 对对象中的属性进行设置
      var obj = new Proxy(target, handler);
      //target 目标对象  你要进行处理的对象
      //handler 容器   里面放无数可以处理对象属性的方法
     //自定义对象属性的获取,赋值,枚举,函数调用等功能
      var target = {
        a: 1,
        b: 2,
      };
      var proxy = new Proxy(target, {
        get(target, prop) {
          return "this is property value" + target[prop];
        },
        set(target, prop, value) {
          target[prop] = value;
		  console.log(target[prop]);  //3
        },
      });
      console.log(proxy.a); //此时触发get方法   this is property value 1
	  proxy.b = 3  //此时触发set方法
      let arr = [
        { name: "小王", age: 18 },
        { name: "小红", age: 20 },
        { name: "小刘", age: 14 },
      ];

      let persons = new Proxy(arr, {
        get(arr, prop) {
          return arr[prop];
        },
        set(arr, prop, value) {
          arr[prop] = value;
        },
      });

      console.log(persons[0]); // { name: "小王", age: 18 },
      persons[1] = { name: "小黑", age: 30 };
      console.log(persons); //{0: {name: "小王", age: 18 }, 1: {name: "小黑", age: 30}, 2: {name: "小刘", age: 14}}
      var obj = { a: 1, b: 2 };
      // 1.获取原型 [[GetPrototypeOf]]
      var proto = Object.getPrototypeOf(obj);
      console.log(proto);
      console.log(obj.__proto__);
      console.log(Object.prototype); //以上三种输出结果是一样的

      //设置原型 [[SetPrototypeOf]]
      Object.setPrototypeOf(obj, { c: 3, d: 4 });
	  console.log(obj); //输出见下图

在这里插入图片描述

      //3.获取对象的可扩展性 [[IsExtensible]]
      var extensible = Object.isExtensible(obj);
      console.log(extensible); //true
      Object.freeze(obj); //将对象进行冻结,使对象不具有可扩展性(不可删除,不可修改,不可写,可读)
      var extensible2 = Object.isExtensible(obj);
      console.log(extensible2); //false

      //4.获取自有属性 [[GetOwnProperty]]
      //5.禁止扩展对象 [[PreventExtensions]]
      //6.拦截对象操作 [[DefineOwnProperty]]
      //7.判断是否是自身属性 [[hasOwnProperty]]
      //8. [[Get]]
      console.log("a" in obj); //true
      console.log(obj.a); //1
      //9.[[set]]
      obj.a = 3;
      obj["b"] = 4;
      //10.[[Delete]]
      delete obj.a;
      //11.[[Enumerate]]
      for (var k in obj) {
        console.log(obj[k]);
      }
      //12.获取键集合 [[OwnPropertyKeys]]
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BoZai_ya

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值