foreach区别对待Array和Set
最后更新于
最后更新于
这一个小伙伴发来的一段Js代码
我们先不用读懂他在干什么
我们先运行一下,大家看 报错对吧
但是如果我把这改成一个数组
然后呢这就得用push了
然后我们再运行一下
大家看,没问题了
后来我发现啊
原因出在这个foreach上面
我们来看这个例子
这是一个简单的数组
我现在呀用foreach把它遍历一下
element
好我们再来执行一下这个
大家看:1、2、3没问题对吧
但是如果我在这每次循环的时候呢
都往array里面push一个新的元素
这个元素呢就是
加
也就是说:我们在array的循环里面
往array添加新的元素
我们来看一下
还是123没问题
但是如果我们在最终打印下结果
大家看101、102、103其实加上来了
但是啊如果我们把这个改成new set
然后呢这用add我们再来试一下
注意看
大家看,无限循环
所以我们就会发现对于数组来说
在 foreach 这个循环里面
新添加的元素没有参与循环
但是对于这个set来说
他就参与了循环
那具体
我们先来看一下
ECMA标准里面的这段解释
翻译过来的大概意思就是说
这个foreach循环的元素的范围
注意是范围
是在第一次调用callback之前设置的
也就说在foreach调用以后
我们再往元素里添加的
这个新元素的范围是不会被访问的
为什么强调范围呢
我们再来看一下这个
还是刚才这个例子我们还是用数组
我们这回不往里添加
100了我们先回到这个打印的效果
我们先来执行一下
打开123没问题对吧
但是啊
我们让这element它等于一的时候
我们往它后面插入一个元素
ARE
点 splice
我们让他在第二个元素的
插入一个100吧
好我们再来打印一下大家看
就变成了一、一百、二了
也就是说他还是循环三遍
但是呢
它里面元素的内容已经变成四个了
大家注意看
我在这最终再打印一下array
他就变成1、100、2、3了
但是呢他还是循环三遍
只是第二个元素变了
所以呢这里强调的是一个处理的范围
那虽然我们看不到foreach的原代码哈
但是我们可以推断出来
他大概是这样写的
比如我们写一个普通的for循环
i < array.length
然后 i++
然后现在在这打印
这是123没有问题是这样的
那基于这个for循环
我们再往里添加一下试试
array.push(element + 100)
我们再来试一下
大家看,无限循环了
跟刚才那个Set一样
他新插入的元素也参与了后续的循环
但是如果我们把这个缓存成一个数组 (口误:缓存成变量)
也就是说length
然后呢
让这小于length
我们再来试一下
大家看,跟刚才是不是一样效果
所以呢其实我们用数的foreach啊
就有点像这样来写
好那至于为什么
我们这块用Set 效果就不一样呢
这块我猜测
是因为它这个循环的机制不一样
因为它不是用下标来循环的
它是内部用的迭代器
所以呢他这块新加的元素呢
会参与到后续的循环里
边去
最后啊我们再回到这个小伙伴
发来的这段代码
为什么他用这个new Set就会报错呢
原因是他这个fn方法里面
不但往这个额瑞添加新元素了
而且由于他这个逻辑哈
他加入了空的元素
那空肯定是没办法调用的
但是对于array来说呢
你添加的元素
素根本就不会参与到循环里边
所以后加的那个空不会在这执行