前端開發(fā)當(dāng)中,我們通常要對(duì)后端返回的數(shù)據(jù)進(jìn)行一些處理再渲染到頁面,而其中常用的就是數(shù)組的不同遍歷方法,因此熟練掌握這些方法是非常有必要的,而對(duì)于初學(xué)者來說,這些方法不太容易理解也容易被混淆,今天我們就通過本篇教會(huì)大家區(qū)別數(shù)組的forEach,map,filter,reduce,some,every這6種遍歷方法。
一、這些方法的共同語法
除了reduce方法語法略有不同(后面單獨(dú)講解),其他五個(gè)方法forEach,map,filter,some,every傳入的第一個(gè)參數(shù)語法相同:
(1)第一個(gè)參數(shù)為回調(diào)函數(shù):callbackFn(item,index,arr),該函數(shù)接收三個(gè)參數(shù)item,index,arr。
(2)三個(gè)參數(shù)分別表示:
①item:當(dāng)下遍歷的數(shù)組元素的值;當(dāng)數(shù)組的元素為基本數(shù)據(jù)類時(shí),item是直接賦值為元素的值;當(dāng)數(shù)組的元素為引用數(shù)據(jù)類型時(shí),此時(shí)item是引用賦值,即該地址值會(huì)指向原數(shù)組的元素(在map方法里會(huì)舉例說明)。
②index:當(dāng)下遍歷的數(shù)組元素的索引;
③arr:表示原數(shù)組。
下面我們通過具體講解這些方法,來說明這些方法的不同之處以及使用場(chǎng)景。
二、forEach和map方法
forEach方法和map方法比較相似,所以我們這里一同講解。首先我們了解一下這2種方法的基本概念:
(1)forEach方法:沒有返回結(jié)果,返回值為undefined,本質(zhì)上等同于 for 循環(huán);
(2)map方法:會(huì)返回一個(gè)新數(shù)組,新數(shù)組的元素為原始數(shù)組元素調(diào)用函數(shù)處理的后return返回的值。
在大部分使用場(chǎng)景中,這2種方法都可以獲得相同的結(jié)果,只是具體操作步驟有所不同,下面我們就以數(shù)組的數(shù)據(jù)類型為基本數(shù)據(jù)類型和引用數(shù)據(jù)類型2種情況舉例。
2.1 數(shù)組數(shù)據(jù)類型:基本數(shù)據(jù)類型
假設(shè)我們有個(gè)數(shù)組[1,2,3,4,5],現(xiàn)在我們需要讓數(shù)組的每個(gè)元素乘以2。
(1)使用forEach方法:
let arr=[1,2,3,4,5]
arr.forEach(function(item,index,arr){
arr[index]=item*2
})
console.log(arr) // [2,4,6,8,10]
// 用forEach方法改動(dòng)原數(shù)組的元素,我們讓原數(shù)組的每個(gè)元素變成了之前的2倍
這里我們使用forEach方法直接修改原數(shù)組,讓原數(shù)組的每個(gè)元素直接替換為item*2,原數(shù)組就改成了我們需要的結(jié)果。
(2)使用map方法:
let arr=[1,2,3,4,5]
let newArr=arr.map(function(item,index,arr){
return item*2
})
console.log(newArr) // [2,4,6,8,10]
這里我們用map方法return出的item*2就是最終新數(shù)組的每個(gè)元素值,此時(shí)map方法不會(huì)改動(dòng)原數(shù)組。如果不能改動(dòng)原數(shù)組,此時(shí)就用map方法。
2.2 數(shù)組數(shù)據(jù)類型:引用數(shù)據(jù)類型
假設(shè)我們有個(gè)對(duì)象數(shù)組,現(xiàn)在需要改動(dòng)每個(gè)對(duì)象元素的屬性。
(1)使用forEach方法:
let arr=[
{ id: '01001', title: '考研成績(jī)' },
{ id: '01002', title: '中國(guó)經(jīng)濟(jì)復(fù)蘇進(jìn)度條' },
]
arr.forEach(function(item,index,arr){
item.date="2023-1-1"
})
console.log(arr)
打印結(jié)果為:
這里我們使用forEach方法直接修改原數(shù)組,為原數(shù)組的每個(gè)元素都添加了date屬性。
(2)使用map方法:
let arr=[
{ id: '01001', title: '考研成績(jī)' },
{ id: '01002', title: '中國(guó)經(jīng)濟(jì)復(fù)蘇進(jìn)度條' },
]
let newArr=arr.map(function(item,index,arr){
item.date="2023-1-1"
return item
})
console.log("arr",arr)
console.log("newArr",newArr)
打印結(jié)果為:
開頭我們介紹這些方法的語法時(shí)有講到,item如果是對(duì)象是引用數(shù)據(jù)類型就是引用賦值,所以直接改動(dòng)item屬性也會(huì)改動(dòng)原數(shù)組。此時(shí)用map返回新數(shù)組的意義就不大,直接用forEach就可以實(shí)現(xiàn)這種效果。
而當(dāng)我們需要不改動(dòng)原數(shù)組時(shí),我們先要對(duì)數(shù)據(jù)進(jìn)行拷貝處理。舉例如下:
let arr=[
{ id: '01001', title: '考研成績(jī)' },
{ id: '01002', title: '中國(guó)經(jīng)濟(jì)復(fù)蘇進(jìn)度條' },
]
let newArr=arr.map(function(item,index,arr){
item={...item} // 這里我們多了一步拷貝處理
item.date="2023-1-1"
return item
})
console.log("arr",arr)
console.log("newArr",newArr)
打印結(jié)果如下:
此時(shí)我們可以看到原數(shù)組并沒有被改動(dòng),新數(shù)組的是我們想要的結(jié)果。
另外,map方法因?yàn)闀?huì)返回新數(shù)組,所以可以與reduce、filter等方法組合使用,以便在一條語句中執(zhí)行多個(gè)操作,如下例所示:
let arr=[
{ id: '01001', title: '考研成績(jī)', isHot: true },
{ id: '01002', title: '中國(guó)經(jīng)濟(jì)復(fù)蘇進(jìn)度條', isHot: false },
]
// 用map方法給數(shù)據(jù)加上日期屬性
let result=arr.map((item)=> {
item={...item}
item.date='2023-01-01'
return item
// map方法后緊接著使用filter方法過濾數(shù)據(jù)
}).filter((item)=> {
return item.isHot===true
})
console.log(result)
上面代碼的打印結(jié)果如下,此時(shí)數(shù)據(jù)既添加了date屬性,又過濾出了isHot為true的數(shù)據(jù)。
三、filter方法
3.1 概念
定義:遍歷數(shù)組并返回一個(gè)新的數(shù)組,新數(shù)組中的元素是通過檢查指定數(shù)組中滿足條件的所有元素。(即過濾數(shù)組并返回新數(shù)組,不會(huì)改變?cè)瓟?shù)組)
3.2 舉例
注意:傳入的函數(shù)里必填return,因?yàn)闀?huì)根據(jù)return的值為false或true來過濾數(shù)據(jù)。
(1)直接return布爾值,為true則元素值放入數(shù)組中,為false的就被過濾掉。
let arr=[
{ id: '01001', title: '考研成績(jī)', isHot: true },
{ id: '01002', title: '中國(guó)經(jīng)濟(jì)復(fù)蘇進(jìn)度條', isHot: false },
]
let result=arr.filter((item)=> {
return item.isHot
})
console.log(result) // [{ id: '01001', title: '考研成績(jī)', isHot: true }]
// 看打印結(jié)果可以發(fā)現(xiàn)isHot為false的對(duì)象數(shù)據(jù)就被過濾掉了
(2)return非布爾值時(shí),也會(huì)通過將數(shù)據(jù)隱式轉(zhuǎn)化為布爾值來過濾數(shù)組。
let arr=[1,undefined,null,3,0,"",NaN]
let result=arr.filter((item)=> {
return item
})
console.log(result) // [1,3]
// 將item的值轉(zhuǎn)化為布爾值后,為false的元素就被過濾掉了,留下的為true的
(3)與其他方法結(jié)合使用:
這里先用一個(gè)小例子幫大家回憶一下數(shù)組的indexOf()方法的用法:用于返回某個(gè)指定的值在數(shù)組中首次出現(xiàn)的索引值,如果沒有找到匹配的元素則返回 -1。
let arr=[1, 2, 3, 4, 5];
let index=arr.indexOf(2);
// 在數(shù)組中查找是否有2這個(gè)元素
console.log(index) //打印結(jié)果是1,表示2和數(shù)組中索引為1的元素的值匹配
①與indexOf()方法組合使用進(jìn)行數(shù)組去重:
let arr=[1,1,2,4,5,6,5,5,6]
let newArr=arr.filter((item,index)=>{
return arr.indexOf(item)===index
// 因?yàn)閕ndexOf始終返回第一個(gè)符合條件的元素的索引
// 數(shù)組中重復(fù)出現(xiàn)的數(shù)值就不可能滿足全等判斷,就會(huì)被過濾掉
})
console.log(newArr) // [1,2,4,5,6]
②還有與map方法一起使用的例子,map方法介紹中已舉例,這里就不重復(fù)說明了。
四、reduce方法
4.1 概念
(1)定義:遍歷數(shù)組,并構(gòu)建返回一個(gè)最終的值。
(2)語法:
array.reduce(function(previous,current,index,arr),initValue);
(3)參數(shù)說明:
①不傳第二參數(shù)initValue時(shí),我們以一個(gè)計(jì)算數(shù)組元素相加之和的例子說明:
let arr=[1,3,5,7]
let result=arr.reduce((previous,current)=>{
console.log('previous:',previous, ' current:',current)
return previous + current
})
console.log('result:',result)
打印結(jié)果為:
我們可以看到:
(a)傳入的箭頭函數(shù)執(zhí)行了數(shù)組長(zhǎng)度-1次,也就是3次;
(b)回調(diào)函數(shù)多次調(diào)用:
第一次調(diào)用時(shí),previous表示就是數(shù)組的第一個(gè)元素的值1,current是數(shù)組第二個(gè)元素的值3;
第二次調(diào)用時(shí),previous表示的是上次調(diào)用時(shí)return出來的值也就是1+3為4,current是數(shù)組第三個(gè)元素的值5;
第三次調(diào)用時(shí),previous同樣表示的是上次調(diào)用返回的值也就是4+5為9,current表示數(shù)組第四個(gè)元素的值7。
(c)result的值就是最后一次計(jì)算9+7的結(jié)果值16。
②傳入第二參數(shù)initValue時(shí),我們以一個(gè)獲得新數(shù)組的每個(gè)元素是原數(shù)組每個(gè)元素累計(jì)相加之和的例子說明:
let arr=[1,3,5,7]
let sum=0
let result=arr.reduce((previous,current)=>{
console.log(previous, 'current:', current)
previous.push(sum + current)
sum +=current
return previous
}, [])
console.log('result:', result)
打印結(jié)果為:
我們可以看到:
(a)傳入的箭頭函數(shù)執(zhí)行了arr數(shù)組長(zhǎng)度一樣的次數(shù),也就是4次;
(b)previous:箭頭函數(shù)第一次調(diào)用時(shí),表示的是傳入的初始值initValue,也就是空數(shù)組,后面表示的是上次return出來的值;current:始終表示的是數(shù)組arr的每個(gè)元素的值;
(c)result同樣表示最后一次箭頭函數(shù)調(diào)用return返回的結(jié)果。
4.2 舉例
上面我們舉了2個(gè)簡(jiǎn)單例子區(qū)分reduce方法傳入1個(gè)參數(shù)和2個(gè)參數(shù)的區(qū)別,下面我以一個(gè)計(jì)算購物車選中產(chǎn)品數(shù)量的例子來說明項(xiàng)目中reduce的具體應(yīng)用場(chǎng)景。
目前購物車一共有3個(gè)產(chǎn)品,其中選中了2種產(chǎn)品,并計(jì)算選中的總價(jià)為22393,我們可以通過reduce方法計(jì)算①②這個(gè)2個(gè)值。
// arr表示購物車?yán)锼挟a(chǎn)品數(shù)組,其中用不到的數(shù)據(jù)就省略了
let arr=[
{
id:12334,
isChecked:1, // 1表示購物車選中了這個(gè)產(chǎn)品
cartPrice:5999, // 表示產(chǎn)品單價(jià)5999
skuNum:1, // 表示購物車產(chǎn)品數(shù)量為1
skuName:"小米10 至尊紀(jì)念版 雙模5G 驍龍865 120W快充 8GB+128GB 陶瓷黑 游戲手機(jī)",
},
{
id:12375,
isChecked:0, // 0表示購物車沒有選中這個(gè)產(chǎn)品
cartPrice:2323, // 表示產(chǎn)品單價(jià)為2323
skuNum:1, // 表示購物車產(chǎn)品數(shù)量為1
skuName:"華為P40 5G全網(wǎng)通智能手機(jī) 支持鴻蒙HarmonyOS 零度白 8G+128G",
},
{
id:12376,
isChecked:1, // 1表示購物車選中了這個(gè)產(chǎn)品
cartPrice:8197, // 表示產(chǎn)品單價(jià)為8197
skuNum:1, // 表示購物車產(chǎn)品數(shù)量為1
skuName:"Apple iPhone 12 (A2404) 64GB 黑色 支持移動(dòng)聯(lián)通電信5G 雙卡雙待手機(jī)",
},
]
因?yàn)槊總€(gè)產(chǎn)品對(duì)象的isChecked屬性1就表示選中了,0表示沒有選中,因此我們可以通過累計(jì)相加這個(gè)值來計(jì)算購物車選擇的產(chǎn)品數(shù):
// 計(jì)算購物車選中產(chǎn)品數(shù)
let num=arr.reduce((previous,current)=>{
return previous + current.isChecked
// previous初始值是傳入的第二個(gè)參數(shù)0,current表示數(shù)組的當(dāng)前遍歷到的對(duì)象
},0)
// 通過累計(jì)相加所有產(chǎn)品的isChecked的屬性值,獲得選中的產(chǎn)品數(shù)量num為2
計(jì)算選中產(chǎn)品總價(jià)格,我們也是通過reduce方法累計(jì)計(jì)算:
// 計(jì)算購物車選中產(chǎn)品總價(jià)格
let price=arr.reduce((previous,current)=>{
return previous + current.isChecked * current.cartPrice * current.skuNum
// 選中的產(chǎn)品的數(shù)量和價(jià)格的乘積累計(jì)相加
},0)
// 最終的price的值就是選中產(chǎn)品總價(jià)
通過上面的例子我們可以看到這種要累計(jì)計(jì)算處理數(shù)據(jù)的情況,使用reduce方法是比較方便的操作。
五、some和every方法
因?yàn)閟ome()方法和every()方法比較簡(jiǎn)單,因?yàn)楸容^相似所以這里也是一起講解。
概念及舉例
(1)some()方法用于檢測(cè)數(shù)組中的元素是否滿足return的判斷條件,如果有一個(gè)元素滿足條件,則表達(dá)式返回true , 剩余的元素不會(huì)再執(zhí)行檢測(cè);如果沒有滿足條件的元素,則返回false。
// some方法只要有一個(gè)元素符合return的條件就返回true,后面元素就不會(huì)再執(zhí)行判斷
let arr=[2,3,4,6]
let result=arr.some((item)=>{
return item % 2===1 // 判斷數(shù)組的每個(gè)元素是否除以2能余1
})
console.log(result) // 因?yàn)榈诙€(gè)元素3符合,所以結(jié)果為true
(2)every()方法用于檢測(cè)數(shù)組中的元素是否都滿足return的判斷條件,只要有一個(gè)不符合就會(huì)返回false,都符合才返回true。
// every方法要求所有元素符合return的判斷條件才返回true,不然就返回false
let arr=[2,3,4,6]
let result=arr.every((item)=>{
return item % 2===0 // 判斷數(shù)組的每個(gè)元素是否都能被2整除
})
console.log(result) // 因?yàn)榈诙€(gè)元素3不符合條件,所以結(jié)果為false
總結(jié)
(1)forEach方法沒有返回值,一般用于直接修改原數(shù)組;
(2)map方法會(huì)返回新的數(shù)組,在處理元素為引用數(shù)據(jù)類型的數(shù)組時(shí)可以通過數(shù)據(jù)的拷貝不修改原數(shù)組(拷貝的方法我們會(huì)在下回和大家做專門的講解),并且可以結(jié)合其他方法執(zhí)行更多層的操作;
(3)filter()方法用于過濾數(shù)組,返回的結(jié)果就是過濾后的新數(shù)組;
(4)reduce()方法在一般需要對(duì)數(shù)組元素的數(shù)據(jù)進(jìn)行一些運(yùn)算處理時(shí)使用,返回的值就是最終的結(jié)果;
(5)some()方法用于判斷數(shù)組中是否有滿足條件的元素,返回結(jié)果是布爾值,只要有一個(gè)符合就是true;
(6)every()方法用于判斷數(shù)組中的元素是否都符合判斷條件,返回結(jié)果是布爾值,都符合才會(huì)返回true。
融界2024年1月26日消息,據(jù)國(guó)家知識(shí)產(chǎn)權(quán)局公告,騰訊科技(深圳)有限公司申請(qǐng)一項(xiàng)名為“一種動(dòng)態(tài)頁面渲染方法、裝置、設(shè)備及存儲(chǔ)介質(zhì)“,公開號(hào)CN117453207A,申請(qǐng)日期為2022年7月。
專利摘要顯示,該申請(qǐng)涉及云技術(shù)領(lǐng)域,提供了一種動(dòng)態(tài)頁面渲染方法、裝置、設(shè)備及存儲(chǔ)介質(zhì)。該方法包括:遍歷初始頁面樹包含的各第一節(jié)點(diǎn),生成相應(yīng)節(jié)點(diǎn)的目標(biāo)擴(kuò)展組件,并基于獲得的各目標(biāo)擴(kuò)展組件,構(gòu)建待渲染頁面的目標(biāo)頁面樹;遍歷目標(biāo)頁面樹包含的各第二節(jié)點(diǎn),每遍歷一個(gè)第二節(jié)點(diǎn),通過相應(yīng)目標(biāo)擴(kuò)展組件的增強(qiáng)組件,解析第二節(jié)點(diǎn)的綜合配置信息,獲得用于觸發(fā)第二節(jié)點(diǎn)發(fā)生數(shù)據(jù)變化的其他第二節(jié)點(diǎn)的目標(biāo)屬性信息,并基于獲得的目標(biāo)屬性信息,渲染相應(yīng)目標(biāo)擴(kuò)展組件中具備相同頁面功能的通用組件,得到相應(yīng)的視圖內(nèi)容。將處理節(jié)點(diǎn)間依賴關(guān)系與渲染屬性數(shù)據(jù)的操作分離,使組件更加通用,且不會(huì)發(fā)生父組件阻塞頁面渲染進(jìn)程的情況,降低渲染出錯(cuò)率。
本文源自金融界
query是繼Prototype之后之后又一個(gè)優(yōu)秀的javascript庫,是一個(gè)由John Resig創(chuàng)建于2006年1月的開源項(xiàng)目。
jquery
John Resig
jquery簡(jiǎn)潔的語法和跨平臺(tái)的兼容性,極大地簡(jiǎn)化了javascript開發(fā)人員遍歷HTML文檔、操作DOM、處理事件、執(zhí)行動(dòng)畫和開發(fā)Ajax的操作。其獨(dú)特而又優(yōu)雅的代碼風(fēng)格改變了javascript程序員的設(shè)計(jì)思路和編寫程序的方式。
jquery的理念是寫得少,做得多(write less,do more).jquery獨(dú)特的選擇器、鏈?zhǔn)讲僮?/strong>、事件處理機(jī)制和封裝完善的Ajax都是其他javascript庫望塵莫及的。概括起來,jquery有以下優(yōu)勢(shì):
ztree
echarts
總之,jquery是一個(gè)優(yōu)秀的開源框架,值得開發(fā)者學(xué)習(xí)和使用。
*請(qǐng)認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。