JavaScript中map和forEach的區(qū)別示例詳解
一、本質(zhì)區(qū)別
1. 返回值不同
map返回回調(diào)函數(shù)對(duì)每個(gè)元素處理后的新數(shù)組。forEach返回undefined。
const arr = [1, 2, 3]; // [3, 6, 9] const arr_1= arr.map(item => item * 3); // undefined const arr_2= arr.forEach(item => item * 2);
2. 是否可??鏈?zhǔn)秸{(diào)用
- 因
map返回新數(shù)組,可鏈?zhǔn)秸{(diào)用,可用其他數(shù)組方法(如filter、reduce)。- 因
forEach返回undefined,不可鏈?zhǔn)秸{(diào)用?????。
const arr = [1, 2, 3];
// 可鏈?zhǔn)秸{(diào)用
[6, 9]
arr.map(item => item * 3).filter(x => x > 3);
// Cannot read property 'filter' of undefined
arr.forEach(item => item * 3).filter(x => x > 3);二、是否修改原數(shù)組
1. map
1. 當(dāng)原數(shù)組元素是?基本數(shù)據(jù)類型??(如數(shù)字、字符串、布爾值),會(huì)生成新數(shù)組,不改變?cè)瓟?shù)組。
const arr = [1, 2, 3]; const arr_1 = arr .map(item => item * 2); // [1, 2, 3] console.log(arr); // [2, 4, 6] console.log(arr_1);
2. 當(dāng)原數(shù)組元素是引用數(shù)據(jù)類型??(如對(duì)象、數(shù)組)時(shí),會(huì)生成新數(shù)組,若回調(diào)函數(shù)中直接修改其元素屬性??,可改變?cè)瓟?shù)組(因其元素是引用的)。
const names= [{ name: 'zhangsan' }, { name: 'lisi' }];
const names_1 = names.map(item=> {
// 直接修改原對(duì)象屬性
item.name = 'wangwu';
return item;
});
// [{ name: 'wangwu' }, { name: 'wangwu' }]
console.log(names);
// [{ name: 'wangwu' }, { name: 'wangwu' }]
console.log(names_1); 3. 當(dāng)原數(shù)組元素是引用數(shù)據(jù)類型??(如對(duì)象、數(shù)組)時(shí),會(huì)生成新數(shù)組,若回調(diào)函數(shù)中創(chuàng)建新對(duì)象/數(shù)組,不改變?cè)瓟?shù)組。
const names= [{ name: 'zhangsan' }, { name: 'lisi' }];
const names_1 = names.map(item=> ({ ...item, age: 21 }));
// [{ name: 'wangwu' }, { name: 'lisi' }]
console.log(names);
//[{ name: 'zhangsan', age: 21 }, { name: 'lisi', age: 21 }]
console.log(names_1);
4. 總結(jié):??map本身不改變?cè)瓟?shù)組??,若回調(diào)函數(shù)中對(duì)引用數(shù)據(jù)類型修改,可改變?cè)瓟?shù)組。
2. forEach
1. 當(dāng)原數(shù)組元素是??基本數(shù)據(jù)類型??(如數(shù)字、字符串、布爾值),不改變?cè)瓟?shù)組。
const arr = [1, 2, 3]; arr.forEach(item => item *= 2); // [1, 2, 3] console.log(arr);
2. 當(dāng)原數(shù)組元素是引用數(shù)據(jù)類型??(如對(duì)象、數(shù)組)時(shí),修改其元素屬性??,可改變?cè)瓟?shù)組(因其元素是引用的)。
let names= [{ name: 'zhangsan' }, { name: 'lisi' }];
names.forEach((item, index, array) => {
array[index] = 'wangwu';
// 或
item.name = 'wangwu'
});
// [{ name: 'wangwu' }, { name: 'wangwu' }]
console.log(names);
3. 當(dāng)原數(shù)組元素是引用數(shù)據(jù)類型??(如對(duì)象、數(shù)組)時(shí),??直接替換整個(gè)元素對(duì)象,不改變?cè)瓟?shù)組(形參是原元素的副本)。
let names= [{ name: 'zhangsan' }, { name: 'lisi' }];
names.forEach(item => item = { name: 'xiaohong' });
// [{ name: 'zhangsan' }, { name: 'lisi' }];
console.log(names);
4. 總結(jié):??forEach,修改?基本數(shù)據(jù)類型??元素的值,或直接替換引用數(shù)據(jù)類型元素??,不改變?cè)瓟?shù)組。修改引用數(shù)據(jù)類型??元素的屬性,??可改變?cè)瓟?shù)組。
三、使用場(chǎng)景
??map??使用場(chǎng)景??:需生成新數(shù)組(如數(shù)據(jù)轉(zhuǎn)換、提取屬性)或需鏈?zhǔn)秸{(diào)用其他方法時(shí)。
// [2, 4, 6] const arr = [1, 2, 3].map(x => x * 2);
??forEach??使用場(chǎng)景??:無(wú)需新數(shù)組,需如打印、修改外部變量時(shí)。
let sum = 0; // 6 [1, 2, 3].forEach(item => sum += item);
四、forEach使用限制
1. 無(wú)法中斷或跳過(guò)循環(huán)
不支持使用break或continue語(yǔ)句來(lái)中斷或跳過(guò)循環(huán),可通過(guò)for、for...of解決?;?strong>拋出異常解決。
// 拋出異常解決
let arr = [1, 2, 3];
try {
arr.forEach(item => {
if (item === 2) {
throw('error');
}
console.log(item);
});
} catch(e) {
console.log(e);
}
// 1
// error2.不支持處理異步函數(shù)
forEach是同步方法,在其中執(zhí)行異步函數(shù),不會(huì)等待異步函數(shù)完成,會(huì)立即處理下一個(gè)元素,無(wú)法保證執(zhí)行順序,可通過(guò)for...of解決。
async function handleArr(arr) {
arr.forEach(async item => {
const res = await asyncData(item);
console.log(res);
});
console.log('end');
}
function asyncData(x) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(x);
}, 1000 * x);
});
}
handleArr([1, 2, 3]);
// 預(yù)期
1
2
3
end
// 實(shí)際
end
3
2
13.無(wú)法捕獲異步函數(shù)中錯(cuò)誤
即使異步函數(shù)在執(zhí)行過(guò)程中拋出錯(cuò)誤,forEach仍繼續(xù)處理下一個(gè)元素,不會(huì)處理錯(cuò)誤。
4. 遍歷過(guò)程中更改索引無(wú)效
forEach中索引是自動(dòng)管理的,每次遍歷時(shí)自動(dòng)遞增,可通過(guò)for解決。
// 1. 試圖直接更改索引
let arr = [1, 2, 3, 4];
arr.forEach((item, index) => {
// 1 2 3 4
console.log(item);
index++;
});
// 2. 試圖刪除元素更改索引
let arr_1 = [1, 2, 3, 4];
arr_1.forEach((item, index) => {
if (item === 2) {
// 刪除元素2
arr.splice(index, 1);
}
// [0, 1] [1, 2] [2, 4]
console.log([index, item]);
});
// [1, 3, 4]
console.log(arr_1);
// 3. for解決
let arr_2 = [1, 2, 3, 4];
for (let i = 0; i < arr_2.length; i++) {
if (arr_2 [i] === 2) {
// 刪除元素2
arr_2.splice(i, 1);
i--;
} else {
// 1 3 4
console.log(arr_2[i]);
}
}
// [1, 3, 4]
console.log(arr_2); 總結(jié)
到此這篇關(guān)于JavaScript中map和forEach的區(qū)別詳解的文章就介紹到這了,更多相關(guān)JS中map和forEach區(qū)別內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- JS中Map和ForEach的區(qū)別
- JavaScript中的數(shù)組遍歷forEach()與map()方法以及兼容寫(xiě)法介紹
- js遍歷詳解(forEach, map, for, for...in, for...of)
- JavaScript遍歷數(shù)組的三種方法map、forEach與filter實(shí)例詳解
- JS forEach和map方法的用法與區(qū)別分析
- JS中forEach()和map()的區(qū)別講解
- JavaScript中forEach和map詳細(xì)講解
- 詳解JavaScript中map()和forEach()的異同
- JavaScript中forEach和map的使用場(chǎng)景
相關(guān)文章
參考:關(guān)于Javascript中實(shí)現(xiàn)暫停的幾篇文章
參考:關(guān)于Javascript中實(shí)現(xiàn)暫停的幾篇文章...2007-03-03
js 打開(kāi)新頁(yè)面在屏幕中間的實(shí)現(xiàn)方法
下面小編就為大家?guī)?lái)一篇js 打開(kāi)新頁(yè)面在屏幕中間的實(shí)現(xiàn)方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-11-11
javascript 獲取radio的value的函數(shù) [已測(cè)]
javascript 獲取radio的value的函數(shù) 如果與asp,php等后臺(tái)語(yǔ)言結(jié)合時(shí),一般用不到,但在純js環(huán)境下是必須的。2009-06-06
JS動(dòng)態(tài)添加的div點(diǎn)擊跳轉(zhuǎn)到另一頁(yè)面實(shí)現(xiàn)代碼
這篇文章主要介紹了JS動(dòng)態(tài)添加的div點(diǎn)擊跳轉(zhuǎn)到另一頁(yè)面實(shí)現(xiàn)代碼,需要的朋友可以參考下2017-09-09
js插件YprogressBar實(shí)現(xiàn)漂亮的進(jìn)度條效果
ProgressBar.js 是一個(gè)借助動(dòng)態(tài) SVG 路徑的漂亮的,響應(yīng)式的進(jìn)度條效果。使用 ProgressBar.js 可以很容易地創(chuàng)建任意形狀的進(jìn)度條。這個(gè) JavaScript 庫(kù)提供線條,圓形和方形等幾個(gè)內(nèi)置的形狀,但你可使用 Illustrator 或任何其它的矢量圖形編輯器創(chuàng)建自己的進(jìn)度條效果。2015-04-04
JS 進(jìn)度條效果實(shí)現(xiàn)代碼整理
進(jìn)度條效果實(shí)現(xiàn)代碼,有助于緩解頁(yè)面顯示慢的頁(yè)面,給用戶一個(gè)等待時(shí)間的效果2011-05-05
簡(jiǎn)單了解微信小程序 e.target與e.currentTarget的不同
這篇文章主要介紹了微信小程序 e.target與e.currentTarget的區(qū)別詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-09-09

