likes
comments
collection
share

前端常见循环小结

作者站长头像
站长
· 阅读数 37

说来也是惭愧,用了很多中循环,从forwhileforEachforoffor in等,笔者比较菜,数据处理能力比较薄弱,在看leetcode算法解题的时候,时常会看到while循环,要和莎老板领小本本啦,嘻嘻嘻...

1.for循环:

没错,就是那个最原始的for循环-for ([initialization]初始化; [condition]循环条件; [final-expression]每次循环最后要执行的表达式)

下面通过几个常见的例子来介绍下,便于理解

a) 常规循环:

let Arr = [1,2,3,4,5,6,7,8];

for(let i = 0;i<Arr.length;i++){
  // if(i=== 1)break;
  // if(i === 1)continue;
  console.log(i);
}
//打印结果 1,2,3,4,5,6,7,8
// break 0
// continue 2,3,4,5,6,7,8
  • break:跳出整个循环
  • continue:跳出当前循环

b) 缓存length

这种做的优势在于,通过将Arr.length缓存到len中,从而在每次循环的时候,节约了每次访问Arr.length的时间。

let Arr = [1,2,3,4,5,6,7,8];
for(let i = 0,len = Arr.length;i<len;i++){
  // console.log(i);
}
//打印结果 1,2,3,4,5,6,7,8

c) es5中没有let的话,需要结合闭包去使用

可以理解为通过声明匿名函数的方式去创建块级作用域

for(var i=0;i<Arr.length;i++) {
  ;(function (index) {
    console.log('for和闭包的结合',index)
  })(i);
};
//打印结果 1,2,3,4,5,6,7,8

2.while循环

可能是笔者孤陋寡闻了的原因,感觉代码中见到的for循环会多于while循环,在leetcode中对于链表的遍历等见到循环通常都是while

MDN中定义:while 语句可以在某个条件表达式为真的前提下,循环执行指定的一段代码,直到那个表达式不为真时结束循环。

while循环跳出循环的方式和for循环一致

var n = 0;
var x = 0;

while (n < 3) {
  n++;
  x += n;
}
// 最后得到x的值为6

3.forEach

forEach() 方法对数组的每个元素执行一次给定的函数。

forEach() 为每个数组元素执行一次 callbackFn 函数;与 map() 或者 reduce() 不同的是,它总是返回 undefined 值,并且不可链式调用。

另外对于forEach一个比较有意思的讨论就是forEach是否可以跳出循环?

使用breakcontinue是不行滴,会报错的哈

  • forEach跳过本次循环--return
let Arr = [1,2,3,4,5,6,7,8];
Arr.forEach((item, index, arr) => {
  if (item === 5) return;
  console.log('forEach循环',item); // 1 2 3 4 6 7 8
});
  • forEach跳出整个循环--"抛出异常"
let target = 3;
let Arr = [1,2,3,4,5,6,7,8];
try {
  Arr.forEach( item => {
      console.log('我是通过抛出异常来结束foreach整个循环',item)
      if(item === target) {
          throw Error('抛出异常了') // 跳出循环
      }
  })
} catch (e) {
  console.log('抛出异常的',e)
}
  • 对于undefined组成的数组遍历

另外一个比较有趣的现象是,forEach对于undefined组成的数组,并不会执行遍历操作,但是使用for

循环,如下面例子:

let nullArr = [,,,,,,,,];
for(let i = 0; i<nullArr.length;i++){
  console.log('循环空数组',nullArr[i]);
}
// undefined...

nullArr.forEach(function(item){
  console.log('我是foreach遍历空数组',item);
})
// 不执行

4.for...of

for...of语句可迭代对象(包括 ArrayMapSetStringTypedArrayarguments 对象等等)上创建一个迭代循环,调用自定义迭代钩子,并为每个不同属性的值执行语句

简单的来说,如果不确定是否想要遍历的对象是否是可迭代对象,主要可以在控制台打印,看看是否有[Symbol.iterator],或者说,一个数据结构只要具有 Symbol.iterator 属性,就认为是"可遍历的"(iterable

下面以遍历Map为例,其他可迭代对象也一样的

let iterable = new Map([["a", 1], ["b", 2], ["c", 3]]);

for (let entry of iterable) {
  console.log(entry);
}
// ["a", 1]
// ["b", 2]
// ["c", 3]

普通对象想要使用for...of进行遍历:

  • 类数组被需具备和数组类试的结果属性名从0, 1, 2...开始,且必须具备length 属性
  • 需要给类数组对象添加Symbol.iterator接口规范。

例子如下:

let comObj = {
  0:'yss',
  1:'manager',
  length:2,
};
comObj[Symbol.iterator] = Array.prototype[Symbol.iterator];
for (const value of comObj) {
  console.log(value)   
};
//打印结果 yss manmager

5.for in

for...in 语句任意顺序迭代一个对象的除Symbol以外的可枚举属性,包括**继承的可枚举属性**。

对于这个for...in,更多的需要知道的是边界,也就是它能遍历的范围。

var obj = {a:1, b:2, c:3};

for (var prop in obj) {
  console.log("obj." + prop + " = " + obj[prop]);
}

最后的最后,感谢观看啦~希望莎老板今天工作顺利😆

转载自:https://juejin.cn/post/7176915184861069368
评论
请登录