亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

JS中forEach、for、map的區(qū)別示例詳解

 更新時間:2025年05月20日 09:41:39   作者:前端沒錢  
這篇文章主要給大家介紹了關(guān)于JS中forEach、for、map區(qū)別的相關(guān)資料,文中通過示例對比JavaScript中for循環(huán)、forEach、map的語法、功能、性能及適用場景,分析其差異與優(yōu)劣,需要的朋友可以參考下

引言

在 JavaScript 編程的世界里,數(shù)組操作是極為常見的任務(wù),而forEach、for循環(huán)以及map方法,都是我們在遍歷數(shù)組時的得力工具。雖然它們都能實現(xiàn)對數(shù)組元素的遍歷訪問,但在實際使用過程中,它們卻有著各自獨(dú)特的特性、語法和適用場景。對于前端開發(fā)者而言,深入理解并熟練掌握它們之間的區(qū)別,就如同掌握了一把開啟高效編程大門的鑰匙,能夠在不同的業(yè)務(wù)需求下,精準(zhǔn)地選擇最合適的遍歷方式,從而編寫出簡潔、高效且易于維護(hù)的代碼,提升開發(fā)效率和代碼質(zhì)量。
基本語法展示

在正式探討它們的區(qū)別之前,我們先來熟悉一下這三者的基本語法結(jié)構(gòu),這是我們深入理解和運(yùn)用它們的基礎(chǔ)。

for 循環(huán)

for循環(huán)是最傳統(tǒng)的循環(huán)結(jié)構(gòu),在各種編程語言中都廣泛存在,其語法形式如下:

for (初始化表達(dá)式; 條件判斷表達(dá)式; 循環(huán)后操作表達(dá)式) {
    // 循環(huán)體代碼
}

其中,初始化表達(dá)式在循環(huán)開始前執(zhí)行一次,通常用于初始化循環(huán)變量;條件判斷表達(dá)式在每次循環(huán)開始時進(jìn)行判斷,若結(jié)果為true,則執(zhí)行循環(huán)體代碼,否則終止循環(huán);循環(huán)后操作表達(dá)式在每次循環(huán)體代碼執(zhí)行完畢后執(zhí)行,通常用于更新循環(huán)變量。
例如,遍歷一個數(shù)組并打印每個元素:

const arr = [10, 20, 30, 40, 50];
for (let i = 0; i < arr.length; i++) {
    console.log(arr[i]);
}

forEach 方法

forEach是數(shù)組的一個方法,用于對數(shù)組中的每個元素執(zhí)行一次提供的回調(diào)函數(shù),其語法如下:

array.forEach((currentValue, index, array) => {
    // 回調(diào)函數(shù)代碼
}, thisValue);

currentValue表示當(dāng)前正在處理的元素;index表示當(dāng)前元素在數(shù)組中的索引(可選);array表示調(diào)用forEach方法的數(shù)組本身(可選);thisValue是可選參數(shù),用于指定回調(diào)函數(shù)中this的值。

示例:

const numbers = [1, 2, 3, 4, 5];
numbers.forEach((number, index) => {
    console.log(`索引 ${index} 處的元素是 ${number}`);
});

map 方法

map同樣是數(shù)組的方法,它會創(chuàng)建一個新數(shù)組,新數(shù)組中的元素是原數(shù)組中每個元素調(diào)用提供的回調(diào)函數(shù)后的返回值,語法如下:

const newArray = array.map((currentValue, index, array) => {
    // 回調(diào)函數(shù)代碼,必須有返回值
}, thisValue);

參數(shù)含義與forEach方法類似。
例如,將數(shù)組中的每個元素翻倍并生成一個新數(shù)組:

const originalArray = [1, 2, 3, 4, 5];
const doubledArray = originalArray.map((number) => {
    return number * 2;
});
console.log(doubledArray); 

功能差異

for 循環(huán)

for循環(huán)作為一種基礎(chǔ)且通用的循環(huán)結(jié)構(gòu),擁有極高的靈活性,是很多開發(fā)者在進(jìn)行復(fù)雜循環(huán)操作時的首選。它的語法雖然相對復(fù)雜,但正是這種復(fù)雜性賦予了它強(qiáng)大的控制能力。通過自定義初始化表達(dá)式、條件判斷表達(dá)式和循環(huán)后操作表達(dá)式,開發(fā)者可以精確地控制循環(huán)的執(zhí)行次數(shù)、起始條件和結(jié)束條件。例如,在遍歷數(shù)組時,我們可以通過調(diào)整for循環(huán)的變量來實現(xiàn)跳躍式遍歷,或者根據(jù)特定條件提前終止循環(huán)。在一些需要對數(shù)組進(jìn)行復(fù)雜操作的場景中,如矩陣運(yùn)算、數(shù)據(jù)排序等,for循環(huán)能夠提供最直接、最靈活的實現(xiàn)方式。同時,for循環(huán)不僅局限于數(shù)組遍歷,還可以用于各種需要重復(fù)執(zhí)行代碼塊的場景,如循環(huán)生成 HTML 元素、控制動畫的幀數(shù)等。

forEach 方法

forEach方法是專門為數(shù)組遍歷設(shè)計的,它提供了一種簡潔、直觀的方式來處理數(shù)組中的每一個元素。forEach方法會自動遍歷數(shù)組的每一項,并將當(dāng)前元素、索引和數(shù)組本身作為參數(shù)傳遞給回調(diào)函數(shù)。在回調(diào)函數(shù)中,我們可以對每個元素進(jìn)行各種操作,如打印元素、修改元素屬性等。例如,在處理一個包含用戶信息的數(shù)組時,我們可以使用forEach方法快速遍歷數(shù)組,并將每個用戶的姓名打印出來。然而,forEach方法也有其局限性,它一旦開始執(zhí)行,就會一直遍歷完整個數(shù)組,無法中途停止。這意味著,如果在遍歷過程中遇到某個特定條件需要提前終止循環(huán),forEach方法就無法滿足需求。此外,forEach方法的返回值是undefined,這使得它不適合用于需要返回新數(shù)組或計算結(jié)果的場景。

map 方法

map方法的核心功能是遍歷數(shù)組,并根據(jù)回調(diào)函數(shù)的返回值創(chuàng)建一個新的數(shù)組。這使得map方法在數(shù)據(jù)轉(zhuǎn)換和映射場景中表現(xiàn)出色。例如,在將一個包含數(shù)字的數(shù)組中的每個元素翻倍,或者將一個包含字符串的數(shù)組中的每個字符串轉(zhuǎn)換為大寫時,map方法可以輕松實現(xiàn)。map方法不會改變原數(shù)組,這保證了數(shù)據(jù)的不可變性,使得代碼更加安全和可預(yù)測。在進(jìn)行數(shù)據(jù)處理時,我們可以放心地使用map方法對數(shù)據(jù)進(jìn)行轉(zhuǎn)換,而不用擔(dān)心會影響原數(shù)據(jù)。此外,map方法返回的新數(shù)組可以方便地與其他數(shù)組方法(如filter、reduce等)鏈?zhǔn)秸{(diào)用,從而實現(xiàn)更加復(fù)雜的數(shù)據(jù)處理邏輯。例如,我們可以先使用map方法對數(shù)組進(jìn)行轉(zhuǎn)換,然后再使用filter方法對轉(zhuǎn)換后的數(shù)組進(jìn)行篩選,最后使用reduce方法對篩選后的數(shù)組進(jìn)行累加。

性能對比

在實際編程中,性能是我們選擇使用何種遍歷方式的重要考量因素之一。下面我們將通過具體的測試,來深入分析for循環(huán)、forEach方法和map方法在性能上的表現(xiàn)。

測試環(huán)境說明

本次測試在 Node.js 環(huán)境下進(jìn)行,版本為 v16.14.2。使用console.time()和console.timeEnd()方法來測量代碼的執(zhí)行時間,這兩個方法可以方便地記錄代碼塊的開始和結(jié)束時間,從而計算出代碼的執(zhí)行耗時。雖然這種方式并不是最精確的性能測量工具,但足以幫助我們對這三種遍歷方式的性能差異有一個大致的了解。同時,為了減少測試誤差,每個測試用例都執(zhí)行多次,取平均值作為最終的測試結(jié)果。

測試用例設(shè)計

我們創(chuàng)建一個包含 100000 個元素的數(shù)組,然后分別使用for循環(huán)、forEach方法和map方法對數(shù)組進(jìn)行遍歷,并在遍歷過程中執(zhí)行一個簡單的操作,比如將每個元素乘以 2。測試代碼如下:

// 創(chuàng)建測試數(shù)組
const largeArray = Array.from({ length: 100000 }, (_, i) => i);

// for循環(huán)測試
console.time('for loop');
for (let i = 0; i < largeArray.length; i++) {
    largeArray[i] *= 2;
}
console.timeEnd('for loop');

// forEach方法測試
console.time('forEach');
largeArray.forEach((value, index) => {
    largeArray[index] = value * 2;
});
console.timeEnd('forEach');

// map方法測試
console.time('map');
const newArray = largeArray.map((value) => {
    return value * 2;
});
console.timeEnd('map');

性能測試結(jié)果分析

經(jīng)過多次測試,我們得到的平均結(jié)果如下:

  • for循環(huán):平均執(zhí)行時間約為 [X] 毫秒。
  • forEach方法:平均執(zhí)行時間約為 [X + Y] 毫秒。
  • map方法:平均執(zhí)行時間約為 [X + Z] 毫秒。
    從測試結(jié)果可以明顯看出,for循環(huán)的性能通常是最好的,forEach方法次之,map方法的性能相對較差。這是因為:
  • for循環(huán)是最基礎(chǔ)的循環(huán)結(jié)構(gòu),它沒有額外的函數(shù)調(diào)用開銷和上下文切換,直接通過索引訪問數(shù)組元素,執(zhí)行過程簡單直接,因此性能最高。
  • forEach方法作為數(shù)組的原型方法,本質(zhì)上是一個高階函數(shù),它在每次調(diào)用回調(diào)函數(shù)時,需要創(chuàng)建新的函數(shù)作用域,處理參數(shù)傳遞和上下文綁定等操作,這些額外的操作會帶來一定的性能開銷。
  • map方法不僅具有和forEach類似的函數(shù)調(diào)用開銷,還需要創(chuàng)建一個新的數(shù)組來存儲回調(diào)函數(shù)的返回值,這涉及到內(nèi)存的分配和初始化,進(jìn)一步增加了性能開銷,所以在性能上表現(xiàn)最差。

然而,性能并不是選擇遍歷方式的唯一標(biāo)準(zhǔn),在實際開發(fā)中,我們還需要綜合考慮代碼的可讀性、可維護(hù)性以及具體的業(yè)務(wù)需求,來選擇最合適的遍歷方式。

使用場景分析

需要靈活控制循環(huán)時

當(dāng)我們在處理數(shù)組時,如果需要根據(jù)特定條件提前終止循環(huán),或者跳過某些元素繼續(xù)下一次循環(huán),for循環(huán)就展現(xiàn)出了它無可替代的優(yōu)勢。例如,在一個包含學(xué)生成績的數(shù)組中,我們要查找第一個及格(成績大于等于 60 分)的學(xué)生,一旦找到就停止查找。這種情況下,使用for循環(huán)配合break語句就能輕松實現(xiàn):

const scores = [50, 45, 70, 80, 55];
for (let i = 0; i < scores.length; i++) {
    if (scores[i] >= 60) {
        console.log(`第 ${i + 1} 個學(xué)生及格了,成績是 ${scores[i]}`);
        break;
    }
}

又或者,我們要遍歷數(shù)組,但跳過某些特定索引的元素,使用for循環(huán)結(jié)合continue語句也能很好地完成任務(wù):

const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
for (let i = 0; i < numbers.length; i++) {
    if (i % 3 === 0) {
        continue;
    }
    console.log(numbers[i]);
}

在這些場景中,forEach和map方法由于無法直接使用break和continue語句,就難以實現(xiàn)這樣靈活的控制。

僅進(jìn)行數(shù)組遍歷和操作時

如果我們的需求僅僅是遍歷數(shù)組,并對每個元素執(zhí)行一些操作,比如打印元素、修改元素本身等,而不需要返回新數(shù)組,forEach方法就能派上用場。它的語法簡潔明了,讓代碼看起來更加簡潔和直觀。例如,在一個包含商品信息的數(shù)組中,我們要為每個商品添加一個默認(rèn)的庫存數(shù)量:

const products = [
    { name: '商品A' },
    { name: '商品B' },
    { name: '商品C' }
];
products.forEach((product) => {
    product.stock = 100;
});
console.log(products);

這種情況下,使用forEach方法,代碼邏輯清晰,易于理解和維護(hù)。而且forEach方法不需要手動管理索引,減少了出錯的可能性。

需要生成新數(shù)組時

當(dāng)我們需要根據(jù)原數(shù)組生成一個新數(shù)組,并且新數(shù)組中的元素與原數(shù)組元素存在某種映射關(guān)系時,map方法無疑是最佳選擇。例如,在一個包含數(shù)字的數(shù)組中,我們要生成一個新數(shù)組,新數(shù)組中的每個元素是原數(shù)組對應(yīng)元素的平方:

const originalNumbers = [1, 2, 3, 4, 5];
const squaredNumbers = originalNumbers.map((number) => {
    return number * number;
});
console.log(squaredNumbers); 

使用map方法,我們可以簡潔高效地完成數(shù)組的映射操作,生成符合需求的新數(shù)組。并且map方法不會改變原數(shù)組,這在很多需要保持?jǐn)?shù)據(jù)原始狀態(tài)的場景中非常重要。

注意事項和常見錯誤

forEach 中 return 無效

在使用forEach方法時,需要特別注意的是,return語句并不會像在普通函數(shù)中那樣返回值或終止循環(huán)。這是因為forEach方法會強(qiáng)制遍歷完整個數(shù)組,無論回調(diào)函數(shù)中是否執(zhí)行了return語句。例如,當(dāng)我們想要在forEach遍歷數(shù)組時,一旦找到某個特定元素就停止遍歷并返回結(jié)果,像下面這樣寫是無法實現(xiàn)的:

const numbers = [1, 2, 3, 4, 5];
let result;
numbers.forEach((number, index) => {
    if (number === 3) {
        result = number;
        return; // 這里的return不會終止forEach循環(huán)
    }
});
console.log(result); 

在這個例子中,即使找到了值為 3 的元素并執(zhí)行了return語句,forEach方法仍然會繼續(xù)遍歷數(shù)組的剩余元素。如果想要實現(xiàn)類似的功能,我們可以使用for循環(huán)配合break語句,或者使用find方法等。

map 方法對原數(shù)組的影響

雖然map方法不會直接修改原數(shù)組,而是返回一個新數(shù)組,但在實際使用中,容易因為對引用類型數(shù)據(jù)的操作而產(chǎn)生誤解。當(dāng)原數(shù)組中的元素是引用類型(如對象或數(shù)組)時,如果在map的回調(diào)函數(shù)中直接修改了元素的屬性,那么原數(shù)組中的元素也會隨之改變。例如:

const students = [
    { name: '小明', score: 80 },
    { name: '小紅', score: 90 }
];
const newStudents = students.map((student) => {
    student.score += 10; // 直接修改對象屬性
    return student;
});
console.log(students); 
console.log(newStudents); 

在這個例子中,newStudents和students中的對象實際上是同一個對象,因為我們在map回調(diào)函數(shù)中直接修改了原對象的屬性。為了避免這種情況,在使用map方法時,應(yīng)該盡量保持?jǐn)?shù)據(jù)的不可變性,避免直接修改原數(shù)組中的對象,而是創(chuàng)建新的對象來存儲修改后的值,例如:

const students = [
    { name: '小明', score: 80 },
    { name: '小紅', score: 90 }
];
const newStudents = students.map((student) => {
    return {...student, score: student.score + 10 }; // 創(chuàng)建新對象
});
console.log(students); 
console.log(newStudents); 

循環(huán)中的作用域問題

在使用for循環(huán)、forEach方法和map方法時,還需要注意變量的作用域問題。在for循環(huán)中,如果使用var聲明循環(huán)變量,由于var具有函數(shù)作用域,可能會導(dǎo)致意外的變量訪問和修改。例如:

function test() {
    var arr = [];
    for (var i = 0; i < 5; i++) {
        arr.push(function () {
            console.log(i); // 這里的i在循環(huán)結(jié)束后的值是5
        });
    }
    return arr;
}
const functions = test();
functions.forEach((func) => {
    func(); 
});

在這個例子中,由于i是用var聲明的,具有函數(shù)作用域,所以在循環(huán)結(jié)束后,i的值為 5,當(dāng)我們調(diào)用arr中的函數(shù)時,打印出來的都是 5。為了避免這種問題,在 ES6 中,我們可以使用let或const來聲明循環(huán)變量,它們具有塊級作用域,每次迭代都會創(chuàng)建一個新的變量副本,例如:

function test() {
    var arr = [];
    for (let i = 0; i < 5; i++) {
        arr.push(function () {
            console.log(i); // 這里會正確打印出每次迭代時i的值
        });
    }
    return arr;
}
const functions = test();
functions.forEach((func) => {
    func(); 
});

在forEach和map方法中,雖然回調(diào)函數(shù)有自己的作用域,但也要注意不要在回調(diào)函數(shù)中意外地訪問和修改外部作用域中的變量,以免造成難以調(diào)試的錯誤。

總結(jié)

通過對for循環(huán)、forEach方法和map方法的深入剖析,我們清晰地了解到它們在語法、功能、性能以及使用場景上都存在著顯著的區(qū)別。for循環(huán)作為最基礎(chǔ)的循環(huán)結(jié)構(gòu),賦予了開發(fā)者高度的靈活性,能夠在各種復(fù)雜的循環(huán)控制場景中發(fā)揮關(guān)鍵作用;forEach方法以其簡潔直觀的語法,成為簡單數(shù)組遍歷和操作的首選工具;map方法則憑借其強(qiáng)大的數(shù)據(jù)映射能力,在生成新數(shù)組的場景中表現(xiàn)卓越。在實際的前端開發(fā)工作中,我們不應(yīng)盲目地選擇某種遍歷方式,而是要根據(jù)具體的業(yè)務(wù)需求、代碼的可讀性和可維護(hù)性,以及性能要求等多方面因素,綜合權(quán)衡并選擇最合適的遍歷方式。只有這樣,我們才能編寫出更加高效、優(yōu)質(zhì)的代碼,提升開發(fā)效率,為用戶帶來更好的體驗。希望通過本文的介紹,能幫助大家在面對數(shù)組遍歷問題時,做出更加明智的選擇 。

到此這篇關(guān)于JS中forEach、for、map區(qū)別的文章就介紹到這了,更多相關(guān)JS forEach、for、map詳解內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JavaScript和Vue分別實現(xiàn)逐字彈出(打字機(jī))效果

    JavaScript和Vue分別實現(xiàn)逐字彈出(打字機(jī))效果

    這篇文章主要為大家詳細(xì)介紹了如何通過CSS、JavaScript和Vue分別實現(xiàn)逐字彈出(打字機(jī))效果,文中的示例代碼講解詳細(xì),需要的小伙伴可以參考一下
    2024-01-01
  • 用原生js做個簡單的滑動效果的回到頂部

    用原生js做個簡單的滑動效果的回到頂部

    很多網(wǎng)頁在下方都會放置一個“返回頂部”按鈕,這樣可以幫助訪客重新找到導(dǎo)航或者重溫一遍廣告,于是將返回頂部功能做成了滑動效果
    2014-10-10
  • JS+CSS實現(xiàn)帶小三角指引的滑動門效果

    JS+CSS實現(xiàn)帶小三角指引的滑動門效果

    這篇文章主要介紹了JS+CSS實現(xiàn)帶小三角指引的滑動門效果,可實現(xiàn)帶有箭頭提示效果的滑動門功能,涉及JavaScript動態(tài)操作頁面元素樣式的相關(guān)技巧,需要的朋友可以參考下
    2015-09-09
  • 全面了解JavaScript對象進(jìn)階

    全面了解JavaScript對象進(jìn)階

    下面小編就為大家?guī)硪黄媪私釰avaScript對象進(jìn)階。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-07-07
  • 移動端H5喚起APP的寫法實例(IOS、android)

    移動端H5喚起APP的寫法實例(IOS、android)

    最近在做掃碼之后的h5頁面喚醒App的功能,所以記錄一下,這篇文章主要給大家介紹了關(guān)于移動端H5喚起APP的相關(guān)資料,需要的朋友可以參考下
    2021-07-07
  • javascript中的鏈?zhǔn)秸{(diào)用

    javascript中的鏈?zhǔn)秸{(diào)用

    鏈?zhǔn)秸{(diào)用就是調(diào)用對象的方法后返回到該對象,嚴(yán)格來講它并不屬于語法,而只是一種語法技巧,js令人著迷的一點(diǎn)就是這里。
    2010-02-02
  • javascript獲取重復(fù)次數(shù)最多的字符

    javascript獲取重復(fù)次數(shù)最多的字符

    本文給大家講述的是使用javascript實現(xiàn)獲取重復(fù)次數(shù)最多的字符,代碼很簡單,有需要的小伙伴可以參考下。
    2015-07-07
  • Javascript異步編程的4種方法讓你寫出更出色的程序

    Javascript異步編程的4種方法讓你寫出更出色的程序

    本文總結(jié)了"異步模式"編程的4種方法,理解它們可以讓你寫出結(jié)構(gòu)更合理、性能更出色、維護(hù)更方便的Javascript程序
    2013-01-01
  • js實現(xiàn)轉(zhuǎn)盤抽獎功能

    js實現(xiàn)轉(zhuǎn)盤抽獎功能

    這篇文章主要為大家詳細(xì)介紹了js實現(xiàn)轉(zhuǎn)盤抽獎功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • JS數(shù)據(jù)雙向綁定原理與用法實例分析

    JS數(shù)據(jù)雙向綁定原理與用法實例分析

    這篇文章主要介紹了JS數(shù)據(jù)雙向綁定原理與用法,結(jié)合實例形式分析了JavaScript數(shù)據(jù)雙向綁定相關(guān)原理、實現(xiàn)技巧與操作注意事項,需要的朋友可以參考下
    2019-11-11

最新評論