VUE计算属性原理

先温习下Object.defineProperty

var obj = {};
function defineReactive(obj,key,val){
    //obj.a读写,deps和val闭包储存。
    //defineProperty只能定义一次。
    Object.defineProperty(obj,key,{
        //观察者模式
        get:function(){
            return val;
        }
    });
}
defineReactive(obj,'a',0);
console.log("obj",obj);
obj.a = 10;
console.log("obj.a",obj.a);  // 0,定义无效,貌似只能赋值一次
defineReactive(obj,'a',8);
console.log("obj.a",obj.a);  //Cannot redefine property: a

代码:

var obj = {};
var Dep = null;
function defineReactive(obj,key,val){
    var deps = [];
    //obj.a读写,deps和val闭包储存。
    Object.defineProperty(obj,key,{
        //观察者模式
        get:function(){
            if(Dep){
                //console.log("Dep is:",Dep);
                deps.push(Dep);
            }
            console.log("valx is:",val);
            return val;
        },
        set: function(newVal){
            val = newVal;
//给a赋值的时候,func也执行了,同时b的值也出来了,难点就是两个函数中的变量都闭包了,deps,value。
//通过deps保存另外一个函数的func。同时defineReactive能执行defineComputed的func,这个是很少见的, deps.forEach(func
=> func()); } }); } //obj.b只读 function defineComputed(obj,key,func){ func = func.bind(obj); var value; //闭包起来,全局私有变量 Dep = function(){ value = func(); }; value = func(); //执行了 this.a-->get-->打印val = 0; Dep = null; // console.log("Dep isx:",Dep); // 大量闭包,直接给b赋值没有效果,只能读取obj.b了。 Object.defineProperty(obj,key,{ get:function(){ return value } }); } defineReactive(obj,'a',0); defineComputed(obj,'b',function(){ var a = this.a; // 这里只执行一次就执行了deps.push(Dep)。 return a+1; }); console.log(obj.b); // console.log("obj.a=",obj.a); console.log("obj.a=",obj.a); obj.a +=1; //obj.a = obj.a + 1; console.log(obj.b); obj.a +=1; console.log(obj.b); obj.a +=1; console.log(obj.b);

 很绕,难点是下面代码会执行两次a的get函数。第二次在set函数中的执行value = func(); func函数有this.a中执行了get。并+1赋值给闭包变量value。set函数结束之后。obj.a + 1;而

obj.a +=1;  //obj.a = obj.a + 1;

下来看看源码的Dep类(observer/dep.js)

模块代码结构很清晰、二个全局数组、类的定义和定义一个全局属性。对外提供两个接口
pushTarget、popTarget
Dep.target = null   //
let uid = 0
const targetStack = [] // 全局数组

 

转载于:https://www.cnblogs.com/liuyinlei/p/9367164.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值