遍历数据时for循环bug DforDream

遍历数据时for循环的小bug及解决

一、for循环基本格式

  1. for(声明变量;判断条件; 自增或自减){代码块}一般的写法为for(var i = 0;i < arr.length; i++){consoel.log(i)}
  2. 因为for循环的执行顺序为先声明 变量 (执行一次,其他的执行次数和循环次数相同),在执行判断条件,执行代码块,最后执行自增或自减
  3. 所以以上代码的书写格式会带来一些不必要的资源消耗,每次循环都要去查找一次arr.length的值,所以一般的改良方案为for(var i = 0,len = arr.length;i < len;i++){console.log(i)}这种写法能改善多次取值的问题,也是大家所推崇的写法。

二、bug问题基本描述

  1. 在写伪小米商城,因为数据的嵌套,需要多次循环来取得数据,而在每次执行完的左后都会报如下的错误:Uncaught TypeError: Cannot read property 'a' of undefined,以上的a即为需要的数据。
  2. 现模拟代码如下: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的错误

三、问题解决及原因描述

  1. 解决上述问题很简单,每个for循环的len取不同的名字即可,如通过leni和lenj来区分
  2. 造成以上问题的原因,从小的方面讲就是声明提升机制,同命名的变量冲突,后声明的变量覆盖 先声明的变量
  3. 也与变量的销毁机制有关,现在主流浏览去的变量销毁机制都为标记清除和引用计数(基本没有使用 这种销毁机制,会造成内存泄漏)
  4. 标记清除:当变量进入执行环境时,将这个变量标记为“进入环境”。当变量离开执行环境时,则将其标记为“离开环境”,就销毁回收内存。
  5. 引用计数:跟踪记录每个值被引用的次数,当引用次数变成0时,就销毁回收内存
  6. 本来 j 循环结束后,len就被销毁了,但是 i 循环又对len进行了引用(len属性在每次循环开始时执行一次),所以 j 循环的len就被 i 循环引用,并运行,而 j 循环每次都会重新赋值len,所以j可以正常运行而i循环报错
  7. 以上就是自己写代码时遇到的一点小问题和大家分享,希望对大家有所帮助