SOURCE

const bucket = new WeakMap();

let activeEffect = null;
const effectStack = [];

//封装收集副作用函数
function track(target,key){
    if(!activeEffect){
        return target[key]
    }
    //取出与target绑定的map
    let depsMap = bucket.get(target);
    if(!depsMap){
        bucket.set(target, (depsMap = new Map()));
    }
    //取出与key对应的副作用函数
    let depsEffets = depsMap.get(key);
    if(!depsEffets){
        depsMap.set(key, (depsEffets = new Set()));
    }
    depsEffets.add(activeEffect);
    activeEffect.deps.push(depsEffets)
}
//封装触发副作用函数
function trigger(target, key){
    const depsMap = bucket.get(target);
    if(!depsMap){
        return
    }
    const depsEffets = depsMap.get(key);
    const effectsToRun = new Set();
    depsEffets.forEach(effectfn=>{
        if(effectfn!==activeEffect){
            effectsToRun.add(effectfn)
        }
    })
    effectsToRun&&effectsToRun.forEach(fn=>{
        if(fn.option.scheduler){
            fn.option.scheduler(fn)
        }else{
            fn()
        }
    });
}

function reactive(data){
    const obj = new Proxy(data, {
        get(target, key){
            track(target, key);
            return target[key];
        },
        set(target, key, value){
            target[key] = value;
            trigger(target,key,value);
            return true;
        }
    })
    return obj;
}

const cleanup = (effectFn) => {
    for(let i=0;i<effectFn.deps.length; i++){
        const deps = effectFn.deps[i];
        deps.delete(effectFn)
    }
    effectFn.deps.length = 0;
}

const effect = (fn, option={})=>{
    const effectFn = () => {
        cleanup(effectFn)
        activeEffect = effectFn;
        effectStack.push(activeEffect);
        const res = fn();
        effectStack.pop();
        activeEffect = effectStack[effectStack.length-1];
        return res;
    }
    effectFn.option = option;
    effectFn.deps = []
    if(!option.lazy){
        effectFn();
    }
    return effectFn;
};


const obj1 = reactive({name: "李翔", ok:true, age: 18, height: 180})

const computed = (getter)=>{
    let dirty=true;
    let cache = '';
    const effectFn = effect(getter,{
            lazy:true,
            scheduler(){
                dirty=true;
            }
        }
    )
    const obj = {
        get value(){
            if(dirty){
                console.log('执行副作用函数')
                value = effectFn();
                dirty=false;
            }
            return value;
        }
    }
    return obj;
}

const data = computed(()=>obj1.age+obj1.height)

console.log(data.value)
console.log(data.value)
obj1.age = 20;
effect(()=>{
    console.log(data.value)
})



console 命令行工具 X clear

                    
>
console