一、 for循環(huán)
for循環(huán)是最基礎(chǔ)的循環(huán)方式,適用于遍歷數(shù)組、對象和其他可迭代對象。通過控制循環(huán)條件和步進(jìn)來靈活控制循環(huán)過程。
const array = [1, 2, 3, 4, 5];
for (let i = 0; i < array.length; i++) {
console.log(array[i]);
}
for循環(huán)常見的四種寫法
const persons = ['鄭昊川', '鐘忠', '高曉波', '韋貴鐵', '楊俊', '宋燦']
// 方法一:最常見的方式
for (let i = 0; i < persons.length; i++) {
console.log(persons[i])
}
// 方法二:將persons.length緩存到變量len中,這樣每次循環(huán)時(shí)就不會再讀取數(shù)組的長度,性能略好與方法一
for (let i = 0, len = persons.length; i < len; i++) {
console.log(persons[i])
}
// 方法三:將取值與判斷合并,通過不停的枚舉每一項(xiàng)來循環(huán),直到枚舉到空值則循環(huán)結(jié)束
for (let i = 0, person; person = persons[i]; i++) {
console.log(person)
}
// 方法四:倒序循環(huán)
for (let i = persons.length; i--;) {
console.log(persons[i])
}
推薦:考慮到在不同環(huán)境或?yàn)g覽器下的性能和效率。第四種i–倒序循環(huán)的方式最優(yōu)
不推薦:第三種方式,因?yàn)楫?dāng)數(shù)組里存在非Truthy的值時(shí),比如0和”,會導(dǎo)致循環(huán)直接結(jié)束
二、for...in
for…in循環(huán)用于遍歷對象的可枚舉屬性和原型鏈上的屬性,包括原型鏈上的屬性
const obj = { a: 1, b: 2, c: 3 };
for (let key in obj) {
console.log(key, obj[key]);
}
三、for...of
for…of循環(huán)用于遍歷可迭代對象的值,如數(shù)組、字符串、Set等。
const array = [1, 2, 3, 4, 5];
for (let item of array) {
console.log(item);
}
四、forEach
forEach方法是數(shù)組的內(nèi)置方法,提供了一種簡潔的方式來遍歷和處理數(shù)組??梢允褂没卣{(diào)函數(shù)對每個(gè)元素進(jìn)行特定操作。無法中斷或跳出循環(huán)。
const array = [1, 2, 3, 4, 5];
array.forEach((item) => {
console.log(item);
});
五、filter
filter方法是數(shù)組的內(nèi)置方法,用于根據(jù)指定條件篩選出符合條件的元素,返回一個(gè)新的數(shù)組。無法中斷或跳出循環(huán)。
const array = [1, 2, 3, 4, 5];
const filteredArray = array.filter((item) => {
return item > 2;
});
console.log(filteredArray); // [3, 4, 5]
六、map
map方法是數(shù)組的內(nèi)置方法,用于根據(jù)指定條件對數(shù)組的每個(gè)元素進(jìn)行操作,返回一個(gè)新的數(shù)組。無法中斷或跳出循環(huán)。
const array = [1, 2, 3, 4, 5];
const mappedArray = array.map((item) => {
return item * 2;
});
console.log(mappedArray); // [2, 4, 6, 8, 10]
七、some
some方法是數(shù)組的內(nèi)置方法,用于判斷數(shù)組中是否存在滿足指定條件的元素,只要有一個(gè)滿足條件即返回true。無法中斷或跳出循環(huán)。
const array = [1, 2, 3, 4, 5];
const hasEvenNumber = array.some((item) => {
return item % 2 === 0;
});
console.log(hasEvenNumber); // true
八、every
every方法是數(shù)組的內(nèi)置方法,用于判斷數(shù)組中的所有元素是否都滿足指定條件,只有全部滿足條件才返回true。無法中斷或跳出循環(huán)。
const array = [1, 2, 3, 4, 5];
const allEvenNumbers = array.every((item) => {
return item % 2 === 0;
});
console.log(allEvenNumbers); // false
九、reduce 與 reduceRight
reduce()方法接收一個(gè)函數(shù)作為累加器,數(shù)組中的每個(gè)值(從左到右)開始縮減,最終計(jì)算為一個(gè)值。(不改變原數(shù)組)
reduceRight()方法,和reduce()功能是一樣的,它是從數(shù)組的末尾處向前開始計(jì)算。(不改變原數(shù)組)
// reduce()
let arr = [1,2,3];
let ad = arr.reduce(function(i,j,arr){
return i+j;
}) // 6
// reduceRight()
let arr = [1,2,3];
let ad = arr.reduceRight(function(i,j){
return i+j;
}) // 6
十、while
while循環(huán)會在指定條件為真時(shí)循環(huán)執(zhí)行代碼塊。
如果忘記增加條件中所用變量的值,該循環(huán)永遠(yuǎn)不會結(jié)束。這可能導(dǎo)致瀏覽器崩潰
while (條件)
{
需要執(zhí)行的代碼
}
cars=["BMW","Volvo","Saab","Ford"];
var i=0;
while (cars[i])
{
console.log(cars[i] + "<br>")
i++;
};
十一、do while
do/while循環(huán)是while循環(huán)的變體。該循環(huán)會在檢查條件是否為真之前執(zhí)行一次代碼塊,然后如果條件為真的話,就會重復(fù)這個(gè)循環(huán)。
別忘記增加條件中所用變量的值,否則循環(huán)永遠(yuǎn)不會結(jié)束!
do
{
需要執(zhí)行的代碼
}
while (條件);
let i = 3;
do{
console.log(i)
i--;
}
while(i>0)
// 3
// 2
// 1
總結(jié)
各循環(huán)適用場景
選擇適當(dāng)?shù)难h(huán)方式和數(shù)組方法取決于具體的需求和數(shù)據(jù)類型。
- 如果需要對數(shù)組進(jìn)行靈活的遍歷和處理,可以使用
for循環(huán)、for…in循環(huán)、for…of循環(huán)或forEach。考慮到性能問題,在數(shù)據(jù)量小的時(shí)候使用函數(shù)式編程forEach,循環(huán)遍歷操作數(shù)據(jù)更方便 ,數(shù)據(jù)量比較大量級時(shí)使用for - 如果需要根據(jù)條件篩選數(shù)組元素,可以使用
filter方法; - 如果需要對數(shù)組元素進(jìn)行操作并返回新數(shù)組,可以使用
map方法; - 如果需要判斷數(shù)組中是否存在滿足條件的元素,可以使用
some方法; - 如果需要判斷數(shù)組中的所有元素是否都滿足條件,可以使用
every方法。
循環(huán)的性能和效率
for > while > forEach > for of > map > for in
- 因?yàn)楦鱾€(gè)方法作用不同,簡單的對所有涉及到循環(huán)的方法進(jìn)行執(zhí)行速度比較,是不公平的,也是毫無意義的。
- 拋開業(yè)務(wù)場景和使用便利性,單純談性能和效率是沒有意義的,在實(shí)際項(xiàng)目中,不能只考慮性能與簡潔,代碼的可讀性有時(shí)比性能更重要