vue中当我们对数组进行push,pop等操作的时候,vue也能感知到变化,那么vue是如何监听这种变化呢?

结构原理

vue中对数组的push,pop,shift,unshift,splice,reverse,sort这7种方法实现了感知。首先我们不能直接在Array.prototype上对方法进行监听,因为这样会影响到正常方法的调用。vue中利用Object.create实现一个Array.prototype的继承者:

Object.create的用法在 Object.create vs new中有讲解,内部实现大致如下:

也就是说arrayMethods继承了Array.prototype上的方法,此时arrayMethods访问到的方法和Array.prototype上的是一样的:

background Layer 1 Array prototype Function arrayMethods prototype

第二步我们要将7种数组操作方法用defineObject直接写入到arrayMethods对象上:

通过arrayProto[method].apply(this, args)可以访问到Array.prototype上的原来方法:

background Layer 1 Array prototype Function arrayMethods prototype push pop shift unshift sort reverse splice push pop shift unshift sort reverse splice slice from ... arrayProto[method].apply(this, args);

此时,如果直接访问arrayMethods上的那7种方法,会直接访问到arrayMethods对象上的,可以在里面写一些需要监听的方法,内部通过arrayProto[method].apply(this, args)访问数组上真正的方法。

到这里并没有完,因为arrayMethods是我们构造出来的一个结构,它本身并不是数组,我们要对需要操作的数组使用这些方法:

此时分两种情况,第一种如果支持__proto__,那么可以让需要使用的数组用__proto__指向arrayMethods。因为方法的查找都是沿着原型链(__proto__)的,正常情况下数组实例的__proto__是Array.prototype。

background Layer 1 Array prototype Function arrayMethods prototype push pop shift unshift sort reverse splice push pop shift unshift sort reverse splice slice from ... arrayProto[method].apply(this, args); arr __proto__

如果没有__proto__,那么直接将arrayMethods的方法拷贝到数组实例中去。这两者的效果都是一样的,除了可以访问被改造的7种方法,还可以访问Array.prototype上的其他方法。

background Layer 1 Array prototype Function arrayMethods prototype push pop shift unshift sort reverse splice push pop shift unshift sort reverse splice slice from ... arrayProto[method].apply(this, args); arr push pop shift unshift sort reverse splice

方法分类

上面的7个方法,其中push,unshift,splice是可以增加的;pop,shift,splice是可以减少的。其中splice方法最特殊,既可以增加又可以减少:

例如splice(1,2,10,11,12);那么表示数组从1到3(1+2)要删除,同时增加了10,11,12。也就是splice的第1,2个参数表示删除,第3个参数开始就是增加的了。

下面是完整代码:

其他文章

0
我要评论

评论

返回
×

我要评论

回复:

昵称:(昵称不超过20个字)

图片:

提交
还可以输入500个字