Loading...
墨滴

墨林墨

2022/01/01  阅读:50  主题:绿意

彻底弄懂for、forEach、for...in、for..of的区别

彻底弄懂 for、while、do...while、forEach、map、for...in、for..of 的区别

JS 中常用的循环

for 循环、while 循环、Array.prototype.forEach 可以迭代数组

for of 循环 「扩充:for await of」 for in 循环

性能从高到低:

「for 循环(i 是有的) -> for 循环(i 是全局的) && while 循环」-> forEach 循环(内部封装的方法,肯定做了一些逻辑判断处理,所以要稍微比命令式编程慢一些) -> for/of 循环 -> for/in 循环(它会依次查找私有和原型链上所有可枚举的属性,所以比其他循环慢很多,项目中不建议使用 for/in)

//测试性能
let arr = new Array(9999999).fill(null);

console.time('FOR');
for (var i = 0; i < arr.length; i++) { }
console.timeEnd('FOR');

console.time('FOR2');
let m = 0;
for (; m < arr.length; m++) { }
console.timeEnd('FOR2');

console.time('WHILE');
let k = 0;
while (k < arr.length) { k++; }
console.timeEnd('WHILE');

console.time('FOREACH');
arr.forEach(() => { });
console.timeEnd('FOREACH');

console.time('FOROF');
for (let value of arr) { }
console.timeEnd('FOROF');

console.time('FORIN');
for (let key in arr) { }
console.timeEnd('FORIN');

for

for 有三个表达式:① 声明循环变量;② 判断循环条件;③ 更新循环变量;

三个表达式之间,用";"分割,for 循环三个表达式都可以省略,但是两个";"缺一不可。

for 循环的执行特点:先判断再执行,与 while 相同 for 循环三个表达式都可以有多部分组成,第二部分多个判断条件用&&(并) ||(或)连接,第一三部分用逗号分割; for 循环更适用于循环的开始和结束已知,循环次数固定的场合;

for 循环语法:for(变量=开始值;变量<=结束值;变量=变量+步进值){循环语句}

//for循环 实例:
let arr=[1,2,3,4,5];
for(let i=0;i<arr.length;i++){
    if(i==1){
        continue
    }
    console.log(arr[i]);
}

while

简介:

While 循环会在指定条件为真时循环执行代码块;

使用 break 语句来跳出循环,使用continue 语句用于跳出当前的迭代,并开始下一次迭代。

语法:while(判断条件){执行代码}

//求1+2+···+100的和
var n1=1;
    var sum=0;
    while(n1>=1 && n1<=100){
        sum=sum+n1;
        n1++;
    }
console.log(sum); //输入为5050

//当等于3跳出循环 
var text = "";
    var i = 0;
    while (i < 5) {
        text += "<br>The number is " + i;
        i++;
        if (i == 3) {
            break;
        }
        console.log(i) // 1 2
    }
    console.log(i)  // 3

//当等于3时跳过 该循环
var text = "";
    var i = 0;
    while (i < 5) {
        i++;
        if (i == 3) {
            continue;
        }
        text= i;
        console.log(text)  // 1 2 4 5 
    }

do...while

简介:

do/while 循环是 while 循环的变体。该循环会执行一次代码块,在检查条件是否为真之前,然后如果条件为真的话,就会重复这个循环。

语法:do{需要执行的代码}while (条件);

// 求1到100之间的数字和
    var n1=1;
    var sum=0;
    do{
        sum=sum+n1;
        n1++;
    }
    while (n1>=1 && n1<=100)
    console.log(sum)

forEach

简介:

forEach:用来遍历数组中的每一项;这个方法执行是没有返回值的,对原来数组也没有影响;

无法使用break等语句跳出遍历, 直到所有元素都传递给调用的函数, 但是可以使用抛出异常, 提前终止循环

forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数。

语法: array.forEach(function(currentValue, index, currentArray){ } , thisValue);

  • currentValue为数组当前item的一个副本,因此改变currentValue不会对原数组产生影响 可以通过currentArray与index改变原数组

  • forEach 是声明式(不关心如何实现),没办法使用 break 语句跳出循环,或者使用 return 从函数体内返回。

let sum = 0
var arr = [1,2,3,4];
arr.forEach(function(value,index,array){
    // array[index] == value;    //结果为true
    sum+=value;
    console.log(index,value)
    //输出结果是  0 1
    //           1 2
    //           2 3
    //           3 4
    console.log(array)  // [1,2,3,4]
  });
console.log(sum);    //结果为 10

map

简介:

  • map()方法返回一个新数组,数组中的元素为原始数组元素调用函数处理的后值。
  • map()方法按照原始数组元素顺序依次处理元素。
  • size() 获取Map元素个数
  • isEmpty() 判断Map是否为空
  • clear() 删除Map所有元素
  • put(key, value) 向Map中增加元素(key, value)
  • remove(key) 删除指定key的元素,成功返回true,失败返回false
  • get(key) 获取指定key的元素值value,失败返回null
  • element(index) 获取指定索引的元素(使用element.key,element.value获取key和value),失败返回null
  • containsKey(key) 判断Map中是否含有指定key的元素
  • containsValue(value) 判断Map中是否含有指定value的元素
  • keys() 获取Map中所有key的数组(array)
  • values() 获取Map中所有value的数组(array)
  • 语法:array.map(function(当前元素的值,索引,数组), 执行函数)
 var users = [
       {name: "熊大""email""zhang@email.com"},
       {name: "熊二",   "email""jiang@email.com"},
       {name: "光头强",  "email""jiang@email.com"}
   ];
   // emails => email的数组
   var emails = users.map(function (user) { return user.email; });
   console.log(emails) // [zhang@email.com,jiang@email.com,jiang@email.com]

for...in

for-in 循环用于遍历一个集合里面的所有元素,例如由数字表示的区间、数组中的元素、字符串中的字符。

for in这种循环i是string类型的

作用于数组的for-in循环体除了遍历数组元素外,还会自身可枚举属性

如果给对象的原型加上方法,for in这种循环会把数组原型链上的属性都能被访问到。

在某些情况下,这段代码可能按照随机顺序遍历数组元素。 简而言之,for-in是为普通对象设计的,你可以遍历得到字符串类型的键,因此不适用于数组遍历。

注:json只能用for in循环,因为json的下标是没有规律的字符串,没有length。

for...in语法:for(变量 in 对象){执行语句}

//循环数组
let arr=[1,2,3,4,5];
for(let key in arr){
    console.log(key);
}

//循环对象
 
var obj = {
    w: "wen",
    j: "jian",
    b: "bao"
}
for(var v in obj){
   console.log(obj[v]) //输出为 wen jian bao
   console.log(v)      // 输出为 w j b
 
  }

for..of

简介:

推荐在循环对象属性的时候,使用for...in,在遍历数组的时候的时候使用for...of。

for...in循环出的是key,for...of循环出的是value

注意,for...of是ES6新引入的特性。修复了ES5引入的for...in的不足

for...of不能循环普通的对象,需要通过和Object.keys(),Object.values,Object.entries配使用 for..of 语法:for( 自定义一个值 of 数组 ){执行语句}

//循环数组
let arr=[1,2,3,4,5];
for(let val of arr){
    console.log(val);
}

//循环对象
var arr = [
   { name:'nick', age:18 },
   { name:'freddy', age:24 },
   { name:'mike', age:26 },];
  for(var x of arr) {
    console.log(x.name, item.age);
    //输出为 nick,18
    //      freddy,24
    //      mike, 26
    }
    //for in
    for(var x of arr) {
        console.log(x.name, x.age);//报错 x在这里指的是key值 name
        
let obj={name:"lili",age:28};
   //缺点: 原型上的属性,也给循环了
   for(key in obj){
   console.log(obj[key]);
   }
   
   for(value of Object.keys(obj)){
   console.log(value);
   }
   
   for(value of Object.values(obj)){
   console.log(value);
   }
   
   for(let [key,value] of Object.entries(obj)){
   console.log(key,value);
   }
}

支持 return,并且是值 of 数组(不能遍历对象)

  1. 可以避免所有 for-in 循环的陷阱
  2. 不同于 forEach(),可以使用 break, continue 和 return
  3. for-of 循环不仅仅支持数组的遍历。同样适用于很多类似数组的对象
  4. 它也支持字符串的遍历
  5. for-of 并不适用于处理原有的原生对象

把 Symbol.iterator 方法执行,会返回一个具备迭代器规范的 itor 对象,基于 itor.next()依次执行,就可以获取到数据集合中的每一项!! ES6 中新提供的“for...of”循环,就是按照这套机制去迭代的!

Object.prototype 上不具备 Symbol.iterator,一个普通对象默认不能基于迭代器规范循环,也就是不能使用 for...of

Iterator 迭代器:只是一种机制,可以为各种不同的数据结构提供统一的循环和迭代规范,而 for of 循环本身就是基于这种进制进行迭代的!

  • 拥有 Iterator 机制的对象,必须具备 next 方法:执行这个方法可以依次访问对象中的每个成员
  • 执行 next 返回值是一个对象:
  • value:当前迭代的这一项
  • done:记录是否迭代完成

虽然不具备 Iterator 内置类,但是对于某些数据结构,它提供了 Symbol.iterator 属性方法,这个方法具备迭代器规范,基于这个方法可以依次迭代数据中的每一项

  • 数组 Array.prototype[Symbol.iterator]=function...
  • Set.prototype / Map.prototype
  • String.prototype
  • NodeList.prototype
  • arguments[Symbol.iterator]
  • generator object

墨林墨

2022/01/01  阅读:50  主题:绿意

作者介绍

墨林墨