谈一下JavaScript的几种for循环

谈一下Javascript的几种for循环

文章目录

    • 谈一下Javascript的几种for循环
      • 一.for循环
        • 1.优点
        • 2.缺点
      • 二.forEach循环
        • 1.优点
        • 2.缺点
      • 三.for... in循环
        • 1.优点
        • 2.缺点
      • 四.for...of循环
          • 1.for...of遍历数组
          • 2.for...of遍历字符串
          • 3.for...of遍历Map
          • 4.for...of遍历Set
          • 5.for...of循环遍历DOM集合
          • 6.for...of循环遍历arguments
        • 1.优点
        • 2.缺点
      • 五.提高for循环性能要点

谈一下JavaScript的几种for循环_第1张图片

一.for循环

for循环,我们最常见的循环

var arr = [2, 3, 45, 6];
for (var i = 0; i < arr.length; i++) {
    var a = arr[i];
}

for循环一般形式为:for (表达式1; 表达式2; 表达式3) { 循环体;}

执行顺序: 表达式1,表达式2,循环体,表达式3

1.优点

  • 程序简洁,结构清晰,循环初始化,循环变量化,循环体和循环条件位置突出
  • 可以使用break关键字,终止并跳出循环
  • 可以使用continue关键字,跳过本次循环

2.缺点

  • 只能遍历数组,无法遍历对象(如果想遍历对象,可以使用Object.keys()转化之后再遍历)
  • 需要跟踪计数器退出条件,结构稍显复杂

二.forEach循环

参数是个回调函数,此回调函数三个参数:第一个是value,第二个是index,第三个是数组体

var arr = [2, 3, 45, 6];
arr.forEach((value, index, array) => {
    console.log(value);
    console.log(index);
    console.log(array);
});

1.优点

  • 遍历的时候更加简洁,效率和for循环相同,不用关心下标的问题

2.缺点

  • 不能跳出循环,如break和return
  • 也不能略过循环 ,如使用continue,可以使用return 当做continue使用
  • 只能循环数组

forEach遍历是另一种形式的 JavaScript 循环。但是,forEach()实际上是数组方法,因此只能用在数组中。也无法停止或退出 forEach 循环。如果希望你的循环中出现这种行为,则需要使用基本的 for 循环。

三.for… in循环

for…in循环实际是为循环可枚举对象而设定的

特点:for....in循环返回值是数据结构的 键值,也就是遍历对象时返回该对象的key值,遍历数组返回的数组的下标

一般使用for…in来遍历对象,当然,数组也可以,只不过不推荐遍历数组.

遍历数组时,index遍历出的是数组的下标:

var arr = [2, 3, 45, 6];
for (var index in arr) {    // 不推荐这样
    console.log(index);
    console.log(arr[index]);
}

遍历对象时,index遍历出的是对象的key值

var obj = {
    a: 1,
    b: 3,
    c: 35
}
for (var index in obj) {
    console.log(index);
}

为什么说不推荐使用for…in循环数组呢?因为for…in循环是访问所有可枚举属性,就意味着,如果向Array的prototype中添加某方法,或者其他属性,这些属性或方法都会被循环出来.

Array.prototype.abc = 123;
Array.prototype.decimalfy = function () {
    for (let i = 0; i < this.length; i++) {
        this[i] = this[i].toFixed(2);
    }
};
var arr = [2, 3, 45, 6];
for (var index in arr) {    // 不推荐这样
    console.log(arr[index]);
}
//最后打印结果除了原数组中的值之外,还多了另外2个东西

谈一下JavaScript的几种for循环_第2张图片

这就是为何在循环访问数组时,不建议使用 for…in 循环。

1.优点

  • 非常适合遍历对象
  • 可以遍历数组的键名,遍历对象简洁方便

2.缺点

  • 遍历数组时,会将手动添加到Array.prototype的属性和方法给遍历出来
  • fot in循环里面的index是string类型的,可能会多些隐式转换的开销
  • 通过for-in循环输出的属性名的顺序是不可预测的,所有属性都会被返回一次,但是返回的顺序因浏览器不同。

四.for…of循环

ES6新加的一种循环方法.既比传统的for循环简洁,同时弥补了forEach和for…in循环的短板

for...of 循环用于循环访问任何可迭代的数据类型。

原生具备 Iterator 接口的数据结构如下。

  • Array
  • Map
  • Set
  • String
  • TypedArray
  • 函数的 arguments 对象
  • NodeList 对象
1.for…of遍历数组
 var arr = [2, 3, 45, 6];
 for (var value of arr) {  
     console.log(value);// 2,3,45,6
 }

for...of循环直接读取键值.如果要通过for...of循环,获取数组的索引,可以借助数组实例的entries方法和keys方法

2.for…of遍历字符串
let iterable = "中国人";
 
for (let value of iterable) {
  console.log(value);
}
// "中"
// "国"
// "人"
3.for…of遍历Map
let iterable = new Map([["a", 1], ["b", 2], ["c", 3]]);
 
for (let [key, value] of iterable) {
  console.log(value);
}
// 1
// 2
// 3
 
for (let entry of iterable) {
  console.log(entry);
}
// [a, 1]
// [b, 2]
// [c, 3]
4.for…of遍历Set
let iterable = new Set([1, 1, 2, 2, 3, 3]);
 
for (let value of iterable) {
  console.log(value);
}
// 1
// 2
// 3
5.for…of循环遍历DOM集合

并不是所有类似数组的对象都具有 Iterator 接口,一个简便的解决方法,就是使用Array.from方法将其转为数组。

let nodeList=document.querySelectorAll('ul>li');
for (let node of nodeList) {
  node.classList.add("read");
}
6.for…of循环遍历arguments
// arguments对象
function printArgs() {
  for (let x of arguments) {
    console.log(x);
  }
}
printArgs('a', 'b');
// 'a'
// 'b'

1.优点

  • 避免了for…in的所有缺点,可以使用break,continue和return
  • 支持数组的遍历,还支持类数组(伪数组),和字符串的遍历
  • 支持Map,和Set对象遍历

2.缺点

  • 不适用于处理原有的原生对象
  • for…of 不能循环普通的对象,需要通过和Object.keys()搭配使用
  • 不会遍历出动态添加的属性.也就是在运动过程中动态创建的对象

为什么说for...of不能遍历普通的对象呢?

var obj = {
    a: 1,
    b: 3,
    c: 35
}
for (let value of obj) {
    console.log(value);//obj is not iterable
}

这段代码会报错,obj is not iterable,说对象不是一个可迭代器,那其根本原因就是普通对象上面没有部署Symbol.iterator这个迭代器,而数组之所以能遍历,却是数组已经部署了Symbol.iterator这个迭代器,Symbol(Symbol.iterator)的值为该数组的generator函数

五.提高for循环性能要点

  • 适时加break,不需要遍历全部的就要加跳出条件
  • 不要在for循环体里声明变量(建议一次var,多次赋值),为了防止var会有声明提升,还是尽量还是使用let吧
  • 数组长度缓存,避免每次执行都去计算下length长度

你可能感兴趣的:(JavaScript)