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

这篇博客探讨了Vue3.0响应式原理,重点在于使用Symbol和WeakMap实现响应式数据的优化,避免重复创建Proxy。同时,解释了Reflect API的作用,它是如何将一些Object对象的方法转移到Reflect上,以及在处理对象属性时的优势,如更安全的异常处理。通过示例代码展示了reactive函数的工作流程。
摘要由CSDN通过智能技术生成

代码如下

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;
}

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    
</body>
<script src="./Vue3.0响应式原理.js"></script>
<script type="module">
// const value = {name: "111", age: 13};
// const result1 = reactive(value);
// const result2 = reactive(value);
// console.log(result1, "result1");
// console.log(result1, "result2");
// console.log(result1 == result2, "结果");


const value = {name: "111", age: 13};
const result1 = reactive(value);
const result2 = reactive(result1);
console.log(result1, "result1");
console.log(result1, "result2");
console.log(result1 == result2, "结果");
</script>
</html>

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的用法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值