副作用函数:指的是会产生副作用的函数;

JavaScriptlet 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会设置bodyinnerText属性,其值为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);


目前的实现数据响应式还存在很多缺点,比方副作用函数的名字是写死的,下一章将欠缺响应式零碎。