Web前端入門第 62 問(wèn):JavaScript 循環(huán)結(jié)構(gòu)注意事項(xiàng)
HELLO,這里是大熊的前端開發(fā)筆記。
循環(huán)作為 算法與數(shù)據(jù)結(jié)構(gòu) 中的基石,JS 與其他編程語(yǔ)言一樣,都提供了多種循環(huán)結(jié)構(gòu)用于處理數(shù)據(jù)。
for 循環(huán)
事物的開端往往都是從最常用的開始,循環(huán)結(jié)構(gòu)咱們從 for 循環(huán)說(shuō)起。
語(yǔ)法:
for (初始化; 條件; 增量) {
// ...
}
示例:
// 增量每次 +1
for (let i = 0; i < 10; i++) {
console.log(i);
}
// 增量每次 +2
for (let i = 0; i < 10; i += 2) {
console.log(i);
}
性能優(yōu)化:
在使用 for 循環(huán)遍歷數(shù)組的時(shí)候,可以提前緩存數(shù)組長(zhǎng)度,減少 length 的訪問(wèn)次數(shù)。
const arr = ['前', '端', '路', '引'];
// 提前使用 len 緩存數(shù)組長(zhǎng)度
for (let i = 0, len = arr.length; i < len; i++) {
console.log(arr[i]);
}
此示例中使用了 let 同時(shí)聲明了多個(gè)變量,在常規(guī)的代碼編寫中,不建議這么使用,但在循環(huán)體這種特殊情況下,這么寫也能接受。
// 同時(shí)聲明多個(gè)變量
let a = '前端路引', b = 2, c = true;
增量不一定要使用 i++ 自增,也可以使用 i-- 遞減,或者使用 i += 2 步進(jìn),甚至可以是 i += 10。
for in 循環(huán)
ES6 規(guī)范出現(xiàn)之前,只能使用 for in 循環(huán)遍歷對(duì)象,但這哥們有個(gè)坑,不止會(huì)遍歷對(duì)象自身屬性,還能遍歷原型鏈上可枚舉屬性。
const obj1 = {
name: '前端路引',
age: 1,
'favorite-color': 'red',
}
for (let key in obj1) {
console.log(key, obj1[key]);
}
/*
// 輸出結(jié)果
name 前端路引
age 1
favorite-color red
*/
看個(gè)遍歷原型鏈例子:
// 如果有兄弟不小心給對(duì)象的原型鏈上填了一筆
Object.prototype.test = '我是原型鏈上的測(cè)試屬性';
const obj1 = {
name: '前端路引',
age: 1,
'favorite-color': 'red',
}
for (let key in obj1) {
console.log(key, obj1[key]);
}
/*
// 輸出結(jié)果
name 前端路引
age 1
favorite-color red
test 我是原型鏈上的測(cè)試屬性
*/
for (const key in obj1) {
if (obj.hasOwnProperty(key)) { // 過(guò)濾掉原型鏈屬性
console.log(key, obj1[key]);
}
}
/*
// 輸出結(jié)果
name 前端路引
age 1
favorite-color red
*/
如上所示,代碼編寫規(guī)范建議不要對(duì) JS 自身的原型鏈做修改,擴(kuò)展原型鏈雖然方便了一些對(duì)象操作,但實(shí)際上這是埋了雷的,不知道啥時(shí)候就會(huì)引爆!!
在使用 for in 循環(huán)也需要注意原型鏈的屬性,必須使用 hasOwnProperty 方法來(lái)過(guò)濾掉原型鏈上的屬性。
for of 循環(huán)
由于 for in 的各種弊端,后來(lái)定規(guī)范的大佬們,就新增了一個(gè) for of 循環(huán)用于遍歷可迭代對(duì)象,比如:數(shù)組、字符串、Set、Map 等等。
const obj1 = {
name: '前端路引',
age: 1,
'favorite-color': 'red',
}
// for of 循環(huán)
for (let [key, value] of Object.entries(obj1)) {
console.log(key, value);
}
/* // 以上 let [key, value] 使用了 解構(gòu)賦值,其代碼等于
for (let item of Object.entries(obj1)) {
const [key, value] = item;
console.log(key, value);
}
// 又等于
for (let item of Object.entries(obj1)) {
const key = item[0];
const value = item[1];
console.log(key, value);
}
*/
for of 無(wú)法直接遍歷對(duì)象,需要遍歷對(duì)象時(shí),需使用內(nèi)置方法 Object.entries 將對(duì)象轉(zhuǎn)為數(shù)組,再使用 for of 遍歷,或者使用 Object.keys/Object.values 將對(duì)象轉(zhuǎn)為鍵/值數(shù)組再遍歷。
相比于 for in 循環(huán),for of 循環(huán)性能更好,也不用考慮原型鏈問(wèn)題。
while 循環(huán)
while 循環(huán)多用于不確定循環(huán)次數(shù)的應(yīng)用場(chǎng)景,比如讀取文件數(shù)據(jù)流,并不知道需要循環(huán)多少次才能讀取完。
let i = 0;
while (i < 3) {
console.log(i);
i++;
}
一般能用 for 循環(huán)的場(chǎng)景,都能使用 while 循環(huán)替代。
do while 循環(huán)
這個(gè)循環(huán)可有意思了,不管條件是否滿足,都會(huì)先跑一次循環(huán)體,再判斷條件。
應(yīng)用場(chǎng)景例子:必須讓用戶先輸入,再判斷條件,直到輸入正確才繼續(xù)。
let userInput;
do {
userInput = prompt("請(qǐng)輸入一個(gè)大于 10 的數(shù)字:");
} while (isNaN(userInput) || Number(userInput) <= 10);
console.log("有效輸入:", userInput);
死循環(huán)
在使用循環(huán)遍歷時(shí)候,需特別注意 死循環(huán) 問(wèn)題,條件處理不好,就進(jìn)入死循環(huán),導(dǎo)致程序崩潰。
比如:
let i = 0;
while (i < 3) {
console.log(i);
// i++; // 忘記修改 i 的值,導(dǎo)致進(jìn)入死循環(huán)
}
善用退出循環(huán)
continue / break / return 三個(gè)關(guān)鍵字都可以用來(lái)處理循環(huán)邏輯,不同的是:
continue:跳過(guò)當(dāng)前循環(huán),繼續(xù)下一次循環(huán)。break:跳出當(dāng)前循環(huán),不再繼續(xù)循環(huán)。return:跳出當(dāng)前函數(shù),不再繼續(xù)執(zhí)行。
continue 示例:
function loop1 () {
for (let i = 0; i < 10; i++) {
if (i % 2 === 0) {
continue; // 跳過(guò)偶數(shù)次循環(huán),只輸出奇數(shù)次循環(huán)
}
console.log(i); // 輸出 1 3 5 7 9
}
console.log('循環(huán)結(jié)束'); // 會(huì)執(zhí)行
}
loop1()
break 示例:
function loop2 () {
for (let i = 0; i < 10; i++) {
if (i === 5) {
break; // 在第 6 次循環(huán)退出
}
console.log(i); // 輸出 0 1 2 3 4
}
console.log('循環(huán)結(jié)束'); // 會(huì)執(zhí)行
}
loop2()
return 示例:
function loop3 () {
for (let i = 0; i < 10; i++) {
if (i === 5) {
return; // 在第 6 次循環(huán)退出函數(shù),不會(huì)執(zhí)行循環(huán)體后面的代碼
}
console.log(i); // 輸出 0 1 2 3 4
}
console.log('循環(huán)結(jié)束'); // 此行代碼不會(huì)執(zhí)行
}
loop3()
三個(gè)退出循環(huán)關(guān)鍵字都可以用于所有的循環(huán)語(yǔ)句,不要局限于 for 循環(huán)~~
寫在最后
如果說(shuō)算法是程序的靈魂,那么循環(huán)可以算是算法的基石,很多常見的算法都需要使用循環(huán)實(shí)現(xiàn),比如各種數(shù)組排序算法、查找算法、最短路徑算法等等。
循環(huán)是程序中的必修課,任何編程語(yǔ)言都有它的身影。
文章首發(fā)于微信公眾號(hào)【前端路引】,歡迎 微信掃一掃 查看更多文章。
本文來(lái)自博客園,作者:前端路引,轉(zhuǎn)載請(qǐng)注明原文鏈接:http://www.rzrgm.cn/linx/p/18908725

浙公網(wǎng)安備 33010602011771號(hào)