1. 实现一个完善的响应式

为数据绑定执行函数,当数据发生变动的时候,再次触发函数的执行。 

  1. Object.defineProperty()

Object.defineProperty()方法直接在一个对象上定义一个新属性,或者修改一个已经存在的属性, 并返回这个对象。

   Object.defineProperty(obj, prop, descriptor)

参数

obj 需要定义属性的对象。prop 需被定义或修改的属性名。descriptor (描述符) 需被定义或修改的属性的描述符。

其中descriptor接受一个对象,对象中可以定义以下的属性描述符,使用属性描述符对一个对象进行拦截和控制:

  • value——当试图获取属性时所返回的值。
  • writable——该属性是否可写。
  • enumerable——该属性在for in循环中是否会被枚举。
  • configurable——该属性是否可被删除。
  • set()——该属性的更新操作所调用的函数。
  • get()——获取属性值时所调用的函数。
let store = new WeakMap;
let activeEffect
function effect(fn) {
  const effectFn = () =>{
    activeEffect = effectFn()
    fn()
  }
  effectFn()
}

function  reactive(obj) {
  return new Proxy(obj,{
    get(target,key,reaceiver){
      track(target,key)
      return Reflect.get(target,key,receiver)
    },
    set(){
      trigger(targer, key)
      Reflect.set(target,key,newVal,receiver)
    }
  })
}
function track(target,key){
  if(!activeEffect) return
  let depsMap = store.get(target)
  if(!depsMap){
    store.set(target,(depsMap = new Map()))
  }
  let deps = depsMap.get(key)
  if(!deps){
    depsMap.set(key,(deps = new Set()))
  }
  deps.add(activeEffect)
}
function trigger(){
  let depsMap = store.get(target)
  if(!depsMap) return
  const effects = depsMap.get(key)
  let effectsToRun = new Set()
  effects && effects.forEach(effectFn=>{
    effectsToRun.add(effectFn)
  })
  effectsToRun.forEach(effect=>effect())
}