• Vue3.0 响应式reactive的原理实现


    代码如下

    index.js

    // 这里定义一个Symbol 是为了 当我们的新建的Proxy相应, result2又从新执行这个响应,
    就返回之前的响应 九月渲染性能
    //const result1 = reactive(value);
    //const result2 = reactive(result1);
    const IS_REACTIVE = Symbol("is_reactive");
    
    // 判断 是否是一个对象
    function isObject(target) {
        const result = Object.prototype.toString.call(target);
        if(result == '[object Object]'|| result == '[object Array]') {
            return true;
        }
        return false;
    }
    
    // 这个 创建一个WeakMap 来存放 以前如果创建过 proxy的话, 就那它的之前的缓存值
    // key 只能为对象, WeakMap 跟Map是差不多的,区别是WeakMap 是弱引用,就是值没用的时候 会自动进行垃圾回收机制,节约性能 Map则续收手动的清除
    const reactMap = new WeakMap();
    
    function reactive(target) {
      // 首先 判断 target 是不是对象
      if(!isObject(target)) {
        return;
      }
    
      // 这里的作用是 如果已经是一个 reactive了, 那么再reactive 就没必要了,就从新返回之前的目标值
      if(target[IS_REACTIVE]) {
        return target;
      }
    // 这个是 把之前已经创建好的 Proxy 放在这里,如果再创建的话 就先去找,找到了就返回之前的响应
      if(reactMap.get(target)) {
        return reactMap.get(target);
      }
    
      // 通过
      const proxy = new Proxy(target, {
        get(target, key, receiver) {
            if(key == IS_REACTIVE) {
                return true;
            }
            // return target[key] 跟 Reflect.get(target, key, receiver)的区别
            // receiver 就是相当于代理对象就是这个时候的Proxy, Reflect 中的receiver 相当于把他的this指向 receiver
            return Reflect.get(target, key, receiver);
        },
        set(target, key, value, receiver) {
            return Reflect.set(target, key, value, receiver);
        }
      });
    
      reactMap.set(target, proxy);
      return proxy;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    index.html

    
    
    
        
        
        
        Document
    
    
        
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    Reflect对象是一个全局的普通的对象。Reflect的原型就是Object.

    Reflect是ES6为了操作对象而新增的API, 为什么要添加Reflect对象呢?它这样设计的目的是为了什么?

    1)将Object对象的一些明显属于语言内部的方法(比如Object.defineProperty),放到Reflect对象上,那么以后我们就可以从Reflect对象上可以拿到语言内部的方法。

    2)在使用对象的 Object.defineProperty(obj, name, {})时,如果出现异常的话,会抛出一个错误,需要使用try catch去捕获,但是使用 Reflect.defineProperty(obj, name, desc) 则会返回false

    // 可以参考一下这篇文章 就知道了,为什么要这个样子写
    return target[key] 跟 Reflect.get(target, key, receiver)的区别
    Reflect的用法

  • 相关阅读:
    node+vue前后端分离实现登录时使用图片验证码
    Codeforces Round 953 (Div. 2)(A~D题解)
    KITTI数据集leaderboard上单目SLAM方法
    手撕代码——任意奇数分频
    linux查询进程号,出现两个进程
    商标变更的流程介绍有哪些
    互联网摸鱼日报(2022-11-12)
    想干程序员这行的,真的很需要这个,T0 级别的《面试资料全集》--Java 问题收录及答案详解,持续更新中...
    【从零开始学微服务】02.初识微服务
    jenkins本地打包远程部署项目
  • 原文地址:https://blog.csdn.net/hl971115/article/details/126896779