共计 1104 个字符,预计需要花费 3 分钟才能阅读完成。
副作用函数:指的是会产生副作用的函数;
JavaScript | |
let val = 1;// 全局变量 | |
function effect() {val = 2; // 批改全局变量,产生副作用} |
当 effect
函数执行时,对全局变量 val
产生了副作用,扭转了其值。
响应式数据:
const obj = {text:"hello world"}; | |
function effect(){ | |
//effect 函数的执行读取 obj.text | |
document.body.innerHTML = obj.text; | |
} | |
obj.text = "hello Vue.js"; |
下面的副作用函数 effect
会设置 body
的innerText
属性,其值为 obj.text
, 第 6 行代码又批改了text
的值,冀望副作用函数从新执行,如果能实现这个指标,那么对于 obj
就是响应式数据。
如何能力让 obj
变成响应式数据呢?通过观察咱们发现了两点线索:
▪当副作用函数 effect
执行时,会触发字段 obj.text
的读取 操作;
▪当批改 obj.text
的值时,会触发字段 obj.text
的设置 操作;
如果可能拦挡 obj
对象的 读取 和设置 操作,事件就迎刃而解了。当读取字段 obj.text
时,咱们能够把 副作用 函数存储到一个“桶”中。
当设置 obj.text 时,再把副作用函数 effect 从“桶”里取出并执行。
依照下面的思路,应用 Proxy 来实现:
// 创立一个副作用函数的桶 | |
const bucket = new Set(); | |
// 原始数据 | |
const data = {text: "hello world"}; | |
// 对原始数据的代理 | |
const obj = new Proxy(data, { | |
// 拦挡读取操作 | |
get(traget, key) { | |
// 将副作用函数 effect 增加到副作用函数的桶中 | |
bucket.add(effect); | |
// 返回属性值 | |
return traget[key]; | |
}, | |
// 拦挡设置操作 | |
set(traget, key, newValue) { | |
// 设置属性值 | |
traget[key] = newValue; | |
// 把副作用函数从桶中取出来并执行 | |
bucket.forEach((fn) => fn()); | |
// 返回 true 代表设置操作胜利 | |
return true; | |
}, | |
}); |
测试用例:
function effect() {document.body.innerHTML = obj.text;} | |
effect(); | |
setTimeout(() => {obj.text = "hello vue3";}, 1000); |
目前的实现数据响应式还存在很多缺点,比方副作用函数的名字是写死的,下一章将欠缺响应式零碎。
正文完