JavaScript中的循环

129 阅读3分钟

几种循环的方式

// 一个普通的数组        
var arr =[3,5,2,6];
// 普通的for 循环遍历
for(var i = 0 ; i < arr.length; i++){
    console.log(i,"类型:"+typeof i,arr[i]);
}
// 用for in 遍历数组
for(var k in arr){
    console.log(k,"类型:"+typeof k,arr[k]);
}

标准的for循环中的i是number类型,表示的是数组的下标,但是foreach循环中的i表示的是数组的key是string类型。


// 一个普通的数组        
var arr =[3,5,2,6];
// 在数组原型上扩展一个方法
Array.prototype.extend = function(){
    console.log("在数组原型扩展一个方法");
}
// 普通的for 循环遍历
for(var i = 0 ; i < arr.length; i++){
    console.log(i,"类型:"+typeof i,arr[i]);
}
// 用for in 遍历数组
for(var k in arr){
    console.log(k,"类型:"+typeof k,arr[k]);
}

输出的结果中,多出了一行,这一行就是我们扩展的一个函数,不是我们定义在数组中的值。到此这个问题就出来了。

综上所述,用for...in...在通常情况下确实可以正确运行。

但是如果我们在项目采用的是用foreach遍历数组,假设有一天谁不小心自己为了扩展js原生的Array类,或者引入一个外部的js框架也扩展了原生Array。那问题就来了。

  • for ... of只能用在可迭代对象上,获取的是迭代器返回的value值,for ... in 可以获取所有对象的键名
  • for ... in会遍历对象的整个原型链,性能非常差不推荐使用,而for ... of只遍历当前对象不会遍历它的原型链
let arr64 = [2,,43,533,56]
for( let i in arr64){
    console.log(i) // 0 2 3 4
}
Array.prototype.aaa = 'fadfsa'
for( let iii in arr64) {
    console.log(iii) // 0 2 3 4 aaa
}
​
  • 对于数组的遍历,for ... in会返回数组中所有可枚举的属性(包括原型链上可枚举的属性),for ... of只返回数组的下标对应的属性值

循环和中断

  • for
// break退出当前循环,这里就是第二层循环
var arr = [1,2,3];
var len = arr.length;
​
// for break
for(var i = 0; i < len; i += 1){
  for(var j = 0; j < 3; j++){
      if(j === 1){
          break;
      }
      console.log(arr[i]+'-'+j);
  }
}
// 1-0
// 2-0
// 3-0
​
​
// continue停止当前循环的执行,继续下一次循环(都是针对第二层)
var arr = [1,2,3];
var len = arr.length;
​
// for continue
for(var i = 0; i < len; i += 1){
    for(var j = 0; j < 3; j++){
        if(j === 1){
            continue;
        }
        console.log(arr[i]+'-'+j);
    }
}
// 1-0
// 1-2
// 2-0
// 2-2
// 3-0
// 3-2

tip: for循环中不能有return,中止循环的方式是break或者continue

  • forEach
var arr = [1,2,3];
​
arr.forEach(function(value,index) {
    if(index === 1){
        return false;
    }
    console.log(arr[index])
});
// 1
// 3
​
var arr = [1,2,3];
​
arr.forEach(function(value,index) {
    if(index === 1){
        return true;
    }
    console.log(arr[index])
});
// 1
// 3

tips: 在forEach中用return不会返回,函数会继续执行(有种continue的感觉)。 forEach循环里不能有break||continue, 使用return true/false跳过本次循环

中断方法:

  1. 使用try监视代码块,在需要中断的地方抛出异常。
  2. 官方推荐方法(替换方法):用every和some替代forEach函数。every在碰到return false的时候,中止循环。some在碰到return true的时候,中止循环
  • Array.map

map和forEach差不多,区别是map的返回值是一个数组

  • for...in
// break跳出当前循环,注意这里的i是索引,不是数组元素
var arr = [1,2,3];
​
for(var i in arr){
    if(i == 1){
        break
    }
    console.log(i)
}
// 0// continue结束本次循环,开始下一次循环
var arr = [1,2,3];
​
for(var i in arr){
    if(i == 1){
        continue
    }
    console.log(i)
}
// 0
// 2

tip: 终止循环的方式是break/continue,当有return的时候会报错

  • for ...of
// 注意这里的i是数组元素
var arr = [1,2,3];
​
for(var i of arr){
    if(i === 2){
        break
    }
    console.log(i)
}
// 1var arr = [1,2,3];
​
for(var i of arr){
    if(i === 2){
        continue
    }
    console.log(i)
}
// 1
// 3

for...of 跳出当前循环,和for类似, for...of循环里不能有return!第一个参数是数组的值不是索引