循环是每天都会使用的东西,回头看看在写循环时,发现有不同的方式去实现:它们之间还有显著的差异。
while and do...while
首先是while循环。它是最基本的循环类型,在许多情况下可能是最容易阅读和最快的。它通常用于执行某项操作直到满足某个条件。它也是创建无限循环或永不停止的循环的最简单方法。
do...while唯一的区别是条件是在每次迭代结束时而不是开始时检查
let queue1 = ["a", "b", "c"];
while (queue1.length) {
let item = queue1.shift();
console.log(item);
}
let queue2 = [];
do {
let item = queue2.shift() ?? "empty";
console.log(item);
} while (queue2.length);
for循环
它是执行一定次数操作的首选方法。如果需要重复某个操作(例如 10 次),则可以使用for循环
但while 循环重写相同的循环可以帮助说明语法,更容易记住
// log the numbers 1 to 5
for (let i = 1; i <= 5; i++) {
console.log(i);
}
// same thing but as a while loop
let i = 1; // the first part of a for loop
// the second
while (i <= 5) {
console.log(i);
i++; // the third
}
for...of 和 for await...of 循环
for...of是循环数组的最简单方法。
let myList = ["a", "b", "c"];
for (let item of myList) {
console.log(item);
}
但它们并不局限于数组,它可以迭代任何实现了所谓可迭代协议的东西。比如:数组、映射、集合和字符串
let myList = {
*[Symbol.iterator]() {
yield "a";
yield "b";
yield "c";
},
};
for (let item of myList) {
console.log(item);
}
await...of可以将它与非异步可迭代对象一起使用
async function delay(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
// this time we're not making an iterable, but a generator
async function* aNumberAMinute() {
let i = 0;
while (true) {
// an infinite loop
yield i++;
// pause a minute
await delay(60_000);
}
}
// it's a generator, so we need to call it ourselves
for await (let i of aNumberAMinute()) {
console.log(i);
// stop after one hour
if (i >= 59) {
break;
}
}
forEach和map循环
forEach从性能上看它比使用for循环要慢得多,个人会避免使用它
let myList = ["a", "b", "c"];
for (let item of myList) {
console.log(item);
}
// but maybe if I need the index use forEach
["a", "b", "c"].forEach((item, index) => {
console.log(`${index}: ${item}`);
});
map本质上将一个数组转换为另一个数组,它和forEach在性能上差不多,但是可读性更高一点,当然这是主观上的看法
function MyList({items}) {
return (
<ul>
{items.map((item) => {
return <li>{item}</li>;
})}
</ul>
);
}
for...in循环
for...in它可以循环遍历对象的字段,它也会访问通过对象的原型链继承的字段
let myObject = {
a: 1,
b: 2,
c: 3,
};
for (let k in myObject) {
console.log(myObject[k]);
}