前端常见循环小结
说来也是惭愧,用了很多中循环,从for
、while
、forEach
、forof
、for 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
循环跳出循环的方式和fo
r循环一致
var n = 0;
var x = 0;
while (n < 3) {
n++;
x += n;
}
// 最后得到x的值为6
3.forEach
forEach()
方法对数组的每个元素执行一次给定的函数。
forEach()
为每个数组元素执行一次 callbackFn
函数;与 map()
或者 reduce()
不同的是,它总是返回 undefined
值,并且不可链式调用。
另外对于forEach
一个比较有意思的讨论就是forEach
是否可以跳出循环?
使用break
和continue
是不行滴,会报错的哈
- 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
语句在可迭代对象(包括 Array
,Map
,Set
,String
,TypedArray
,arguments 对象等等)上创建一个迭代循环,调用自定义迭代钩子,并为每个不同属性的值执行语句
简单的来说,如果不确定是否想要遍历的对象是否是可迭代对象
,主要可以在控制台打印,看看是否有[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