27 Nov 2020 1167字 4分 遍历数据时for循环的小bug及解决
一、for循环基本格式
for(声明变量;判断条件; 自增或自减){代码块}
一般的写法为for(var i = 0;i < arr.length; i++){consoel.log(i)}
- 因为for循环的执行顺序为先声明 变量 (执行一次,其他的执行次数和循环次数相同),在执行判断条件,执行代码块,最后执行自增或自减
- 所以以上代码的书写格式会带来一些不必要的资源消耗,每次循环都要去查找一次arr.length的值,所以一般的改良方案为
for(var i = 0,len = arr.length;i < len;i++){console.log(i)}
这种写法能改善多次取值的问题,也是大家所推崇的写法。
二、bug问题基本描述
- 在写伪小米商城,因为数据的嵌套,需要多次循环来取得数据,而在每次执行完的左后都会报如下的错误:
Uncaught TypeError: Cannot read property 'a' of undefined
,以上的a即为需要的数据。 - 现模拟代码如下:
var arr = [{a:1,b:[1,2]},{a:2,b:[3,4,5,6]},{a:3,b:[7,8,9,10,11,12,13]}]; for(var i=0,len=arr.length;i<len;i++){ console.log(arr[i].a) var newArr =arr[i].b; for(var j = 0,len = newArr.length;j<len;j++){ console.log(newArr[j]); } }
我们需要的数据为arr数组对象中的a和 b里的所有数据,而在执行完之后就会报Uncaught TypeError,通过打断点分析在每个j循环结束后,len的值就变成了newArr的length值,造成a undefined的错误
三、问题解决及原因描述
- 解决上述问题很简单,每个for循环的len取不同的名字即可,如通过leni和lenj来区分
- 造成以上问题的原因,从小的方面讲就是声明提升机制,同命名的变量冲突,后声明的变量覆盖 先声明的变量
- 也与变量的销毁机制有关,现在主流浏览去的变量销毁机制都为标记清除和引用计数(基本没有使用 这种销毁机制,会造成内存泄漏)
- 标记清除:当变量进入执行环境时,将这个变量标记为“进入环境”。当变量离开执行环境时,则将其标记为“离开环境”,就销毁回收内存。
- 引用计数:跟踪记录每个值被引用的次数,当引用次数变成0时,就销毁回收内存
- 本来 j 循环结束后,len就被销毁了,但是 i 循环又对len进行了引用(len属性在每次循环开始时执行一次),所以 j 循环的len就被 i 循环引用,并运行,而 j 循环每次都会重新赋值len,所以j可以正常运行而i循环报错
- 以上就是自己写代码时遇到的一点小问题和大家分享,希望对大家有所帮助