代码如下
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的用法