- 实现一个完善的响应式
为数据绑定执行函数,当数据发生变动的时候,再次触发函数的执行。
- 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())
}