JavaScript中Array.map()的使用與技巧分享(附實(shí)際應(yīng)用代碼)
一、什么時(shí)候該使用Array.map(),與forEach()的區(qū)別是什么?
1、什么時(shí)候該用Array.map()
一般滿(mǎn)足下列三種情況之一就可以使用Array.map()了:
- 需要返回一個(gè)新數(shù)組,新數(shù)組的長(zhǎng)度與原數(shù)組相同
- 需要進(jìn)行鏈?zhǔn)秸{(diào)用,方便進(jìn)行多步數(shù)據(jù)轉(zhuǎn)換。
- 需要修改數(shù)組且不修改原數(shù)組內(nèi)容
2、Array.map()與Array.forEach()的區(qū)別
最大的區(qū)別就是Array.map()有返回值,Array.forEach()沒(méi)有返回值。以上三種情況也都是基于Array.map()有返回值所以才適用的。
二、Array.map()的使用與技巧
1、基本語(yǔ)法
array.map(callback(currentValue, index, array), thisArg)
- callback:一個(gè)函數(shù),用于處理每個(gè)元素,并返回處理后的值。
- currentValue:正在處理的當(dāng)前元素。
- index(可選):正在處理的當(dāng)前元素的索引。
- array(可選):調(diào)用 map() 的數(shù)組。
- thisArg(可選):執(zhí)行 callback 函數(shù)時(shí),用作 this 的值。
2、返回值
返回一個(gè)新數(shù)組,結(jié)果為原始數(shù)組元素依次調(diào)用 callback 后的值(往往為一個(gè)新的數(shù)組)。
3、使用技巧
array.map()創(chuàng)建一個(gè)新數(shù)組,其結(jié)果是該數(shù)組中的每個(gè)元素(調(diào)用一個(gè)提供的函數(shù))調(diào)用一個(gè)提供的函數(shù)后的返回值。這個(gè)方法對(duì)原數(shù)組不進(jìn)行任何修改。
應(yīng)用場(chǎng)景:數(shù)據(jù)轉(zhuǎn)換、創(chuàng)建派生數(shù)組、應(yīng)用函數(shù)、鏈?zhǔn)秸{(diào)用、異步數(shù)據(jù)流處理、復(fù)雜API請(qǐng)求、DOM操作、搜索和過(guò)濾等。其中應(yīng)用函數(shù)常作為map操作中的其中一步,更多指一種封裝和復(fù)用的思想而不是一種具體的需求。
三、Array.map()的應(yīng)用領(lǐng)域與實(shí)際案例
1、數(shù)據(jù)轉(zhuǎn)換與應(yīng)用函數(shù)
假設(shè)我們有一個(gè)電子商務(wù)網(wǎng)站的訂單數(shù)組,每個(gè)訂單是一個(gè)對(duì)象,包含 id、date、items 和 shipping。每個(gè) items 是一個(gè)對(duì)象數(shù)組,包含 name、price 和 quantity。
我們的目標(biāo)是創(chuàng)建一個(gè)新的數(shù)組,其中每個(gè)元素是一個(gè)對(duì)象,包含訂單的 id、訂單總金額(所有商品價(jià)格和數(shù)量的總和)、訂單日期以及基于總金額計(jì)算的稅費(fèi)(稅費(fèi)計(jì)算函數(shù)為 calculateTax(totalAmount),其中如果總金額小于1000,則稅費(fèi)為總金額的10%,否則為100)。
// 創(chuàng)建一個(gè)新的數(shù)組,其中每個(gè)元素是一個(gè)對(duì)象,包含訂單的 id、訂單總金額、訂單日期以及基于總金額計(jì)算的稅費(fèi) // 其中如果總金額小于1000,則稅費(fèi)為總金額的10%,否則為100 // 示例訂單數(shù)組 const orders = [ { id: 1, date: '2023-04-01', items: [{ name: 'Item1', price: 100, quantity: 2 }], shipping: 50 }, { id: 2, date: '2023-04-02', items: [{ name: 'Item2', price: 200, quantity: 1 }], shipping: 30 }, // ... 更多訂單 ]; // 稅費(fèi)計(jì)算函數(shù) function calculateTax(totalAmount) { return totalAmount < 1000 ? totalAmount * 0.1 : 100; } // 創(chuàng)建新數(shù)組,包含每個(gè)訂單的id, 總金額, 訂單日期和稅費(fèi) const orderDetails = orders.map(order => { const totalAmount = order.items.reduce((sum, item) => sum + item.price * item.quantity, 0); const tax = calculateTax(totalAmount); return { id: order.id, totalAmount: totalAmount + order.shipping + tax, // 包括運(yùn)費(fèi)和稅費(fèi)的最終總金額 date: order.date, tax: tax }; }); console.log(orderDetails); // 輸出: [ { id: 1, totalAmount: 300, // 100 * 2 (items) + 50 (shipping) + 20 (tax) date: '2023-04-01', tax: 20 }, { id: 2, totalAmount: 330, // 200 * 1 (item) + 30 (shipping) + 30 (tax) date: '2023-04-02', tax: 30 }, // ... 更多訂單詳情 ]
2、創(chuàng)建派生數(shù)組
要?jiǎng)?chuàng)建派生數(shù)組,相比于直接通過(guò)for循環(huán)來(lái)“以舊換新”,array.map()比f(wàn)or、foreach還有非常不常用的while、do...while高級(jí),代碼清晰,可讀性強(qiáng),代碼就看起來(lái)很優(yōu)雅,如果都是嵌套循環(huán)和嵌套回調(diào),看起來(lái)就是一團(tuán)亂麻,可讀性差,很不優(yōu)雅。
舉個(gè)例子:有一個(gè)員工信息的數(shù)組,每個(gè)員工對(duì)象包含 name、age 和 salary。我們想要?jiǎng)?chuàng)建一個(gè)新的數(shù)組,其中只包含年齡超過(guò)30歲的員工的姓名和工資。
// 有一個(gè)員工信息的數(shù)組,每個(gè)員工對(duì)象包含 name、age 和 salary。我們想要?jiǎng)?chuàng)建一個(gè)新的數(shù)組,其中只包含年齡超過(guò)30歲的員工的姓名和工資。 const employees = [ { name: 'Alice', age: 25, salary: 70000 }, { name: 'Bob', age: 32, salary: 80000 }, { name: 'Charlie', age: 35, salary: 90000 }, { name: 'David', age: 22, salary: 60000 } ]; const olderEmployees = employees .filter(employee => employee.age > 30) // 篩選年齡超過(guò)30歲的員工 .map(employee => ({ name: employee.name, salary: employee.salary })); // 創(chuàng)建新數(shù)組,只包含姓名和工資 console.log(olderEmployees); // 輸出: [ { name: 'Bob', salary: 80000 }, { name: 'Charlie', salary: 90000 } ]
3、鏈?zhǔn)秸{(diào)用
有一個(gè)用戶(hù)信息的數(shù)組,每個(gè)用戶(hù)對(duì)象包含 id、name 和 isActive。我們想要獲取所有活躍用戶(hù)的姓名,并按照字母順序排序。
//有一個(gè)用戶(hù)信息的數(shù)組,每個(gè)用戶(hù)對(duì)象包含 id、name 和 isActive。我們想要獲取所有活躍用戶(hù)的姓名,并按照字母順序排序 const users = [ { id: 1, name: 'Alice', isActive: true }, { id: 2, name: 'Bob', isActive: false }, { id: 3, name: 'Charlie', isActive: true }, { id: 4, name: 'David', isActive: true } ]; const activeUserNames = users .filter(user => user.isActive) // 篩選活躍用戶(hù) .map(user => user.name) // 獲取用戶(hù)名 .sort(); // 按照字母順序排序 console.log(activeUserNames); // 輸出: // ['Alice', 'Charlie', 'David']
4、異步數(shù)據(jù)流處理
有一個(gè)用戶(hù)列表,每個(gè)用戶(hù)都有一個(gè)異步函數(shù) fetchUserData 來(lái)獲取用戶(hù)的詳細(xì)信息。我們想要獲取所有用戶(hù)的詳細(xì)信息,并對(duì)結(jié)果進(jìn)行處理。
// 有一個(gè)用戶(hù)列表,每個(gè)用戶(hù)都有一個(gè)異步函數(shù) fetchUserData 來(lái)獲取用戶(hù)的詳細(xì)信息。我們想要獲取所有用戶(hù)的詳細(xì)信息,并對(duì)結(jié)果進(jìn)行處理。 const users = [ { id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }, // ... 更多用戶(hù) ]; // 模擬異步獲取用戶(hù)詳細(xì)信息的函數(shù) const fetchUserData = userId => new Promise(resolve => setTimeout(() => resolve(`Data for user ${userId}`), 1000)); // 使用 map() 和 Promise.all() 處理異步數(shù)據(jù)流 const fetchAllUserData = users.map(user => fetchUserData(user.id).then(data => ({ ...user, details: data })) ); Promise.all(fetchAllUserData).then(usersWithData => { console.log(usersWithData); // 輸出處理后包含每個(gè)用戶(hù)詳細(xì)信息的數(shù)組 });
5、復(fù)雜API請(qǐng)求梳理
有時(shí)候需要從不同的API端點(diǎn)獲取數(shù)據(jù),并將這些數(shù)據(jù)匯總到一個(gè)數(shù)組中。
// 需要從不同的API端點(diǎn)獲取數(shù)據(jù),并將這些數(shù)據(jù)匯總到一個(gè)數(shù)組中。 const apiEndpoints = [ 'https://api.example.com/data1', 'https://api.example.com/data2', // ... 更多API端點(diǎn) ]; // 模擬異步API請(qǐng)求 const fetchDataFromApi = url => new Promise(resolve => setTimeout(() => resolve(`Data from ${url}`), 500)); // 使用 map() 來(lái)對(duì)每個(gè)API端點(diǎn)發(fā)起請(qǐng)求 const fetchAllData = apiEndpoints.map(endpoint => fetchDataFromApi(endpoint) ); Promise.all(fetchAllData).then(allData => { console.log(allData); // 輸出包含所有API請(qǐng)求結(jié)果的數(shù)組 });
6、提供DOM操作
假設(shè)我們有一個(gè)用戶(hù)列表,我們想要為每個(gè)用戶(hù)創(chuàng)建一個(gè)列表項(xiàng)并將其添加到頁(yè)面上的一個(gè)列表中。
// 假設(shè)我們有一個(gè)用戶(hù)列表,我們想要為每個(gè)用戶(hù)創(chuàng)建一個(gè)列表項(xiàng)并將其添加到頁(yè)面上的一個(gè)列表中。 const users = [ { id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }, // ... 更多用戶(hù) ]; // 選擇頁(yè)面上的列表元素 const userList = document.getElementById('user-list'); // 使用 map() 生成每個(gè)用戶(hù)的列表項(xiàng) const listItems = users.map(user => { const li = document.createElement('li'); li.textContent = `User ${user.name}`; return li; }); // 將所有列表項(xiàng)添加到列表中 listItems.forEach(item => userList.appendChild(item));
7、用來(lái)搜索和過(guò)濾
假設(shè)我們有一個(gè)商品列表,我們想要根據(jù)用戶(hù)的搜索輸入來(lái)過(guò)濾商品。
// 假設(shè)我們有一個(gè)商品列表,我們想要根據(jù)用戶(hù)的搜索輸入來(lái)過(guò)濾商品。 const products = [ { id: 1, name: 'Apple', category: 'Fruits' }, { id: 2, name: 'Banana', category: 'Fruits' }, // ... 更多商品 ]; // 用戶(hù)輸入的搜索關(guān)鍵詞 const searchQuery = 'Apple'; // 使用 map() 和 filter() 進(jìn)行搜索和過(guò)濾 const filteredProducts = products .filter(product => product.name.includes(searchQuery)) .map(product => ({ id: product.id, name: product.name, // 其他需要展示的信息 })); console.log(filteredProducts); // 輸出匹配搜索關(guān)鍵詞的商品列表
四、總結(jié)
array.map()可以用來(lái)數(shù)據(jù)轉(zhuǎn)換、創(chuàng)建派生數(shù)組、應(yīng)用函數(shù)、鏈?zhǔn)秸{(diào)用、異步數(shù)據(jù)流處理、復(fù)雜API請(qǐng)求梳理、提供DOM操作、用來(lái)搜索和過(guò)濾等,比f(wàn)or好用太多了,主要是寫(xiě)法簡(jiǎn)單,并且非常直觀,并且能提升代碼的可讀性,也就提升了Long Term代碼的可維護(hù)性。
以上就是JavaScript中Array.map()的使用與技巧分享(附實(shí)際應(yīng)用代碼)的詳細(xì)內(nèi)容,更多關(guān)于JavaScript Array.map()用法的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
javascript 制作坦克大戰(zhàn)游戲初步 圖片與代碼
javascript 制作坦克大戰(zhàn)游戲初步 圖片與代碼...2007-11-11javascript 框架小結(jié) 個(gè)人工作經(jīng)驗(yàn)
javascript 框架小結(jié) 個(gè)人工作經(jīng)驗(yàn),對(duì)于新手來(lái)說(shuō)還是值得學(xué)習(xí)的。2009-06-06javascript中BOM基礎(chǔ)知識(shí)總結(jié)
本文主要對(duì)javascript中BOM基礎(chǔ)知識(shí)進(jìn)行總結(jié)。具有很好的參考價(jià)值,下面跟著小編一起來(lái)看下吧2017-02-02iframe窗口高度自適應(yīng)的實(shí)現(xiàn)方法
這篇文章主要介紹了iframe窗口高度自適應(yīng)的實(shí)現(xiàn)方法,有需要的朋友可以參考一下2014-01-01js實(shí)現(xiàn)局部頁(yè)面打印預(yù)覽原理及示例代碼
js 如何打印預(yù)覽,實(shí)局部打印頁(yè)面很簡(jiǎn)單。就是把你需要打印的部分做一個(gè)起始標(biāo)記,下面有個(gè)示例大大家不妨參考下2014-07-07document.all與getElementById、getElementsByName、getElementsByT
Document.all[]是文檔中所有標(biāo)簽組成的一個(gè)數(shù)組變量,包括了文檔對(duì)象中所有元素2008-12-12js復(fù)制網(wǎng)頁(yè)內(nèi)容并兼容各主流瀏覽器的代碼
js 復(fù)制網(wǎng)頁(yè)內(nèi)容的方法代碼有很多不過(guò)要兼容各瀏覽器就不多了,下面有個(gè)不錯(cuò)的方法,大家可以嘗試操作下2013-12-12JS關(guān)閉窗口或JS關(guān)閉頁(yè)面的幾種代碼分享
這篇文章介紹了JS關(guān)閉窗口或JS關(guān)閉頁(yè)面的幾種代碼,有需要的朋友可以參考一下2013-10-10基于JS實(shí)現(xiàn)省市聯(lián)動(dòng)效果代碼分享
這篇文章主要介紹了基于JS實(shí)現(xiàn)省市聯(lián)動(dòng)效果代碼的相關(guān)資料,非常實(shí)用,在日常項(xiàng)目開(kāi)發(fā)過(guò)程中經(jīng)常遇到此需求,下面小編給大家分享實(shí)現(xiàn)代碼,需要的朋友可以參考下2016-06-06Javascript中判斷變量是數(shù)組還是對(duì)象(array還是object)
怎樣判斷一個(gè)JavaScript變量是array還是obiect,或許有很多初學(xué)者對(duì)此不是很清楚吧,下面為大家詳細(xì)解答下,希望對(duì)大家有所幫助2013-08-08