最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JS面試題之forEach能否跳出循環(huán)詳解

 更新時(shí)間:2021年06月11日 14:39:26   作者:茶無味的一天  
js中經(jīng)常會使用foreach這個(gè)方法來遍歷數(shù)組,這篇文章主要給大家介紹了關(guān)于JS面試題之forEach能否跳出循環(huán)的相關(guān)資料,需要的朋友可以參考下

當(dāng)年懵懂無知的我被問到這個(gè)問題時(shí),腦袋一片空白,當(dāng)然也沒答對,一直以來我對forEach都有一種錯(cuò)誤的理解,由于它比原始的for循環(huán)簡潔許多,導(dǎo)致我一度認(rèn)為那是為了方便書寫所創(chuàng)造出來的語法糖,在業(yè)務(wù)中也經(jīng)常使用,但從沒考慮過這種方式存在的問題。

forEach使用說明

參考:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach?v=example

arr.forEach(function callback(currentValue, index, array) {
    //your iterator
}[, thisArg]);
  • currentValue --- 當(dāng)前處理的元素
  • index --- 當(dāng)前處理元素的索引
  • array ---forEach應(yīng)用的數(shù)組

有一段提示寫到了在forEach中break和return的用法。原文如下:

There is no way to stop or break a forEach()loop other than by throwing an exception. If you need such behavior, theforEach()method is the wrong tool. Use a plain loop instead. If you are testing the array elements for a predicate and need a Boolean return value, you can useevery() or
some() instead. If available, the new methodsfind() or findIndex() can be used for early termination upon true predicates as well.

意思就是說在forEach中使用break和return是錯(cuò)誤的,如果希望使用break或者return請使用every或者some函數(shù)。

那么回到標(biāo)題,首先forEach是不能使用任何手段跳出循環(huán)的,為什么呢?我們知道forEach接收一個(gè)函數(shù),它一般有兩個(gè)參數(shù),第一個(gè)是循環(huán)的當(dāng)前元素,第二個(gè)是該元素對應(yīng)的下標(biāo),我們手動(dòng)實(shí)現(xiàn)一下:

Array.prototype.myForEach = function (fn) {
    for (let i = 0; i < this.length; i++) {
        fn(this[i], i, this);
    }
}

forEach是不是真的這么實(shí)現(xiàn)我無從考究,但是以上這個(gè)簡單的偽代碼確實(shí)滿足forEach的特性,而且也很明顯就是不能跳出循環(huán),因?yàn)槟愀緵]有辦法操作到真正的for循環(huán)體。

后來經(jīng)過查閱文檔,發(fā)現(xiàn)官方對forEach的定義根本不是我認(rèn)為的語法糖,它的標(biāo)準(zhǔn)說法是forEach為每個(gè)數(shù)組元素執(zhí)行一次你所提供的函數(shù)。到這里我的思路逐漸明朗,官方文檔也有這么一段話:

除拋出異常之外,沒有其他方法可以停止或中斷循環(huán)。如果您需要這種行為,則該forEach()方法是錯(cuò)誤的工具。

使用拋出異常來跳出foreach循環(huán)

let arr = [0, 1, "stop", 3, 4];
try {
    arr.forEach(element => {
        if (element === "stop") {
            throw new Error("forEachBreak");
        }
        console.log(element); // 輸出 0 1 后面不輸出
    });
} catch (e) {
    console.log(e.message); // forEachBreak
};

當(dāng)然,使用try-catch包裹時(shí),當(dāng)循環(huán)體過大性能會隨之下降,這是無法避免的,所以拋出異常并不是解決forEach問題的銀彈,我們回歸到開頭寫的那段偽代碼,我們對它進(jìn)行一些優(yōu)化,在真正的for循環(huán)中加入對傳入函數(shù)的判斷:

Array.prototype.forEach = function (fn) {
    for (let i = 0; i < this.length; i++) {
        let ret = fn(this[i], i, this);
        if (typeof ret !== "undefined" && (ret == null || ret == false)) break;
    }
}

這樣的話自然就能根據(jù)return值來進(jìn)行循環(huán)跳出啦:

let arr = [0, 1, "stop", 3, 4];

arr.forEach(element => {
    if (element === 'stop') return false
    console.log(element); // 輸出 0 1 后面不輸出
});

console.log('return即為continue:');
arr.forEach(element => {
    if (element === 'stop') return
    console.log(element); // 0 1 3 4
});

文檔中還提到forEach需要一個(gè)同步函數(shù),也就是說在使用異步函數(shù)或Promise作為回調(diào)時(shí)會發(fā)生預(yù)期以外的結(jié)果,所以forEach還是需要慎用或者不要使用,當(dāng)然這并不意味著項(xiàng)目開發(fā)中要一直用簡單的for循環(huán)去完成一切事情,我們可以在遍歷數(shù)組時(shí)使用for..of..,在遍歷對象時(shí)使用for..in..,而官方也在forEach文檔下列舉了其它一些工具函數(shù):

Array.prototype.find()
Array.prototype.findIndex()
Array.prototype.map()
Array.prototype.filter()
Array.prototype.every()
Array.prototype.some()

根據(jù)不同的業(yè)務(wù)場景,選擇使用對應(yīng)的工具函數(shù)來更有效地處理業(yè)務(wù)邏輯,至于forEach,我想就從此相忘于江湖吧。

總結(jié)

到此這篇關(guān)于JS面試題之forEach能否跳出循環(huán)的文章就介紹到這了,更多相關(guān)JS forEach跳出循環(huán)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

华容县| 六盘水市| 东莞市| 威信县| 福鼎市| 噶尔县| 韶山市| 当雄县| 裕民县| 白山市| 峡江县| 常山县| 广丰县| 溆浦县| 蒙城县| 乌拉特前旗| 长泰县| 保靖县| 静乐县| 临洮县| 安宁市| 来安县| 上高县| 灵寿县| 渑池县| 大同市| 简阳市| 翁牛特旗| 锡林郭勒盟| 深圳市| 南安市| 克什克腾旗| 太湖县| 宁乡县| 鸡东县| 河西区| 乌拉特后旗| 项城市| 大荔县| 盐津县| 清镇市|