携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第12天,点击查看活动详情
前文中讲了对于数组赋值和length如何响应,看完上一章之后,就可以对数组完成基本的响应,但其实日常使用的时候,我认为数组的遍历使用的最多的,就我日常开发而言forEach、map、for await of绝对是日常开发前三。
for...in
在前面代理对象中,我们通过查询ECMA文档,找到了如何去追踪for...in。数组作为一个特殊的对象,自然也可以用for...in去遍历,但是我十分不建议,因为ES6有专门遍历数组的for...of方法。
既然能用for...in,那么自然也就可以使用ownKeys去拦截。但是又和对象的ownKeys略有不同。在对象的拦截中,我们通过symbol创建了一个ITERATE_KEY,但是在数组中,却是length。
//ownKeys
track(target,Array.isArray(target) ? 'length' : ITERATE_KEY)
for...of
for...of会比for...in复杂一些,在ECMA文档中有这样的描述
其实就是说,for ... of是用来遍历可迭代对象的,书中举了一个例子
const obj = {
a:0,
[Symbol.iterator](){
return {
next(){
a:obj.a++,
done:obj.a > 10
}
}
}
}
从这个流程上看,就是调用了数组内部的迭代器,通过length判断元素是否存在,当元素存在时在next方法中返回元素本身。因此,只需要在副作用函数与数组长度和索引之间建立响应式联系,就是能够响应for...of。
而这一点,在上一章中已经做到了,因此我们无需再修改代码就可以实现响应。
需要注意的是,由于[Symbol.iterator]这个其实是一个数组自带的方法,它不应该被改变,所有也不用去响应,我们应该在get的时候再判断一些,如果碰到这种,就无需追踪了
get(target,key,receiver){
/*省略其他逻辑*/
if(!onlyRead && typeof key!=='symbol'){
track(target,key)
}
}
下一章我们讲一下数组原型上的一些查找方法,本质上这里面的大部分方法还是遍历数组,但是又有所不同。