摘要:最近手頭上做了一個(gè)很大的后臺(tái)管理項(xiàng)目,前端對(duì)復(fù)雜數(shù)據(jù)的處理要求頗高,也確實(shí)讓自己發(fā)現(xiàn)了很多之前被忽視的細(xì)節(jié)。鳴人佐助卡卡西佐助佐助佐助但是很遺憾及更早版本也不支持。
??最近手頭上做了一個(gè)很大的后臺(tái)管理項(xiàng)目,前端對(duì)復(fù)雜數(shù)據(jù)的處理要求頗高,也確實(shí)讓自己發(fā)現(xiàn)了很多之前被忽視的細(xì)節(jié)。在此特整理出來(lái),希望不熟悉的朋友們們以后可以繞開我踩的這些坑。本文初衷在于幫助大家梳理一些數(shù)組操作上的重點(diǎn)和易錯(cuò)點(diǎn),希望也能幫助和提醒大家,我會(huì)盡可能寫的幽默些,加深大家的記憶。水平有限,真心無(wú)限。希望大家喜歡,請(qǐng)不要吝嗇你們的贊,謝謝
一、常用方法解析??說(shuō)起數(shù)組操作,我們肯定第一反應(yīng)就是想到forEach()、map()、filter()等方法,下面分別闡述一下各方法的優(yōu)劣。
1、forEach 1.1 基礎(chǔ)點(diǎn)??forEach的使用頻率很高,多用于對(duì)數(shù)組自身的改變和各元素相關(guān)統(tǒng)計(jì)性的計(jì)算,重要特性如下:
可以改變數(shù)組自身,沒(méi)有返回值;
中途不能用常規(guī)操作跳出循環(huán),可以用拋出異常(try/catch)的方式,但不推薦這樣做;
1.2 易錯(cuò)點(diǎn)forEach()不一定改變自身數(shù)組。我們可以看看數(shù)組中的元素是值類型和引用類型場(chǎng)景下,是否都能獲得改變:
var arr1 = [ {name:"鳴人",age:16}, {name:"佐助",age:17} ]; var arr2 = [1,2,3]; arr1.forEach(item => { item.age = item.age + 1} ); //=> [{name:"鳴人",age:17},{name:"佐助",age:18}] arr2.forEach(item => { item = item * 2} ) // => [1,2,3]
最后的結(jié)果是,arr1發(fā)生了改變,鳴人、佐助都長(zhǎng)了一歲,arr2沒(méi)有任何改變。所以,可以粗暴得出結(jié)論:當(dāng)數(shù)組中元素是值類型,forEach絕對(duì)不會(huì)改變數(shù)組;當(dāng)是引用類型,則可以改變數(shù)組
不支持鏈?zhǔn)讲僮?,所以以下代碼是錯(cuò)誤的:
[1,2,3,4,5].forEach( item => console.log(item) ).filter(item => { return item > 2 }) // Uncaught TypeError: Cannot read property "filter" of undefined
注意:這里我們說(shuō)僅僅是forEach()這個(gè)方法不支持鏈?zhǔn)秸{(diào)用,在調(diào)用forEach之前,前面的數(shù)組你怎么玩鏈?zhǔn)蕉紱](méi)問(wèn)題,最后返回一個(gè)正常數(shù)組即可:
// 這個(gè)沒(méi)問(wèn)題 [1,2,3,4,5].filter(item => { return item > 2 }).forEach(item => { console.log(item) })
不會(huì)在迭代之前創(chuàng)建數(shù)組的副本,這個(gè)使用場(chǎng)景太少太少了,忽略了...
2、map??map()功能很強(qiáng)大,forEach()的一些局限性它很多都能解決。"map"即"映射",也就是原數(shù)組被"映射"成對(duì)應(yīng)新數(shù)組。
2.1 基礎(chǔ)點(diǎn)新建一個(gè)數(shù)組,需要有承載對(duì)象,也意味著原始數(shù)組在調(diào)用它后不會(huì)發(fā)生變化;
該數(shù)組中的每個(gè)元素都調(diào)用一個(gè)提供的函數(shù)后返回結(jié)果。
2.2 易錯(cuò)點(diǎn)創(chuàng)建新數(shù)組不代表不能用它改變?cè)袛?shù)組,你用原有數(shù)組去承載就可以:
let arr = [1,2,3]; arr = arr.map(item => { return item * 2 })
arr同樣也會(huì)改變,所以這也不費(fèi)事嘛。。。
map()中每個(gè)元素都要執(zhí)行相應(yīng)的回調(diào)函數(shù),所以必須要有return(千萬(wàn)別學(xué)某些人,判斷過(guò)程一復(fù)雜,忘了return,最后得到的是個(gè)空數(shù)組,哭天喊地的~~~),如果你想給數(shù)組做一定的過(guò)濾處理,那map()基本上行不通:
let newArr = [1,2,3,4,5].map(item => { if(item > 3) return item }) // => [undefined, undefined, undefined, 4, 5]
最終得到的結(jié)果是[undefined, undefined, undefined, 4, 5]。別和我說(shuō)你簡(jiǎn)單處理一下就能湊合用,人生不能湊合,代碼也是!
3、filter??map()沒(méi)法做到的過(guò)濾,就交給filter()去完成,這個(gè)大家肯定也都知道。filter()和map()很像,就像周董《東風(fēng)破》和《發(fā)如雪》一樣像,也是創(chuàng)建一個(gè)新數(shù)組,新數(shù)組中的元素是篩選出來(lái)的符合條件的所有對(duì)象。簡(jiǎn)單寫個(gè)例子:
let newArr = [1,2,3,4,5].filter(item =>{ if(item > 3) return item }) // => [4,5]
這個(gè)相信也沒(méi)啥易錯(cuò)點(diǎn),有的話歡迎評(píng)論指出~~~
4、sort()sort()用于對(duì)數(shù)組的元素進(jìn)行排序。排序順序可以是字母或數(shù)字,并按升序或降序。
4.1 基礎(chǔ)點(diǎn)1.默認(rèn)排序按字母升序(更準(zhǔn)確一些是根據(jù)字符串Unicode碼點(diǎn)):
[3,4,2,1,5].sort() // => [1,2,3,4,5] ["Javascript","Vue","React","Node","Webpack"].sort(); // => ["Javascript", "Node", "React", "Vue", "Webpack"]4.2 易錯(cuò)點(diǎn)
sort()與map()、filter()等不同,它直接改變?cè)紨?shù)組(很重要!);
如果想按照其他標(biāo)準(zhǔn)進(jìn)行排序,就需提供比較函數(shù)compareFunction(a,b),數(shù)組會(huì)按照調(diào)用該函數(shù)的返回值排序,即a和b是兩個(gè)將要比較的元素:
如果compareFunction(a,b)小于0,則a排列到b之前;
如果 compareFunction(a, b)等于0,a和b的相對(duì)位置不變(并不保證);
如果 compareFunction(a, b)大于0,b排列到a之前;
直接上例子:
let Users = [ {name:"鳴人",age:16}, {name:"卡卡西",age:28}, {name:"自來(lái)也",age:50}, {name:"佐助",age:17} ]; Users.sort((a,b)=> { return a.age - b.age }) // => 鳴人、佐助、卡卡西、自來(lái)也5、some()
some()也是很好的一個(gè)方法,用于檢查數(shù)組中是否有某些符合條件。
5.1 基礎(chǔ)點(diǎn)只要有一個(gè)滿足即返回true,之后的不再執(zhí)行(所以說(shuō)對(duì)性能很友好!)。
var result = [ {name:"鳴人",age:16}, {name:"佐助",age:17} ].some(item => { return item.age > 16 }); => true5.2 易錯(cuò)點(diǎn)
??some()和下面講的every()返回的都是Boolean值,僅此而此,別多想......
6、every()??如果說(shuō)some()是"||"判斷,那every()就是"&&"判斷,它用于檢測(cè)數(shù)組中的每一項(xiàng)是否都滿足條件,只有都滿足了才會(huì)返回true。這點(diǎn)也很好理解:
var result = [ {name:"鳴人",age:16}, {name:"佐助",age:17} ].every(item => { return item.age > 16 }); => false二、其他經(jīng)典方法
??在我們的日常工作中,會(huì)有很多業(yè)務(wù)需求是上述方法做不到的,比如下面三個(gè)需求:
給一個(gè)數(shù)組做去重處理;
判定當(dāng)前數(shù)組里是否有某個(gè)元素,并返回該元素;
判定當(dāng)前數(shù)組里是否有某個(gè)元素,并把它去除;
針對(duì)需求1,我相信看到"去重",你肯定會(huì)想到new Set(),這也是個(gè)經(jīng)常出現(xiàn)的面試題;針對(duì)需求2,當(dāng)你看到判定當(dāng)前數(shù)組中是否有某個(gè)元素,也許會(huì)說(shuō)filter() 不就是干這臟活累活的嗎? 還真不是,不信,我們分別展開討論一下吧。
1. 數(shù)組去重(沒(méi)你想的那么簡(jiǎn)單) 1.1 new Set() 的局限性??數(shù)組去重,基本上論壇上各位大神的面試題里都會(huì)有這個(gè),沒(méi)錯(cuò),正是new Set(),很經(jīng)典的辦法,面試必備:
let tempArr = new Set([1,2,3,3,4,4,5]) // => {1,2,3,4,5} //并且已有元素是添加不進(jìn)去的: tempArr.add(3) // => {1,2,3,4,5} tempArr.add(6) // => {1,2,3,4,5,6}
恩,很棒,一定注意new Set()會(huì)將結(jié)果轉(zhuǎn)換成對(duì)象!但實(shí)際工作中我們很少會(huì)和元素是值類型的數(shù)組打交道,那看看元素是引用類型還行不行:
let mySet = new Set(); mySet.add(1); // Set(1) {1} mySet.add(5); // Set(2) {1, 5} mySet.add(5); // Set(2) {1, 5} 這里體現(xiàn)了值的唯一性 mySet.add("some text"); [...mySet] // => [1,5,"some text"] mySet.add({name:"jay Chou",age:40}); mySet.add({name:"jay Chou",age:40}); [...mySet] // => [1,5,"some text",{name:"jay Chou",age:40},{name:"jay Chou",age:40}]
看到了吧,Set()沒(méi)法去重元素是引用對(duì)象的數(shù)組。那接下來(lái)咋整呀?
1.2 _.uniqWith()別擔(dān)心,Lodash幫我們,Lodash是一個(gè)一致性、模塊化、高性能的JavaScript實(shí)用工具庫(kù)。它有提供給了我們一個(gè)很好的方法——_.uniqWith():
import _ from "lodash"; //=> [{ "x": 1, "y": 2 }, { "x": 2, "y": 1 }]
其中, _.isEqual(value,other)用于執(zhí)行深比較來(lái)確定兩者的值是否相等。 _.uniqWith()做去重處理。
2. 獲取數(shù)組中的指定元素??在工作中我們還有一個(gè)比較常見的場(chǎng)景,就是在數(shù)組中找到我想要的那一個(gè),并且返回給我。好的,some()已經(jīng)辦不到了,它只會(huì)告訴我是否存在,filter()確實(shí)可以做到,但是如果我本身就知道這個(gè)數(shù)組里即使有我想的那個(gè),也肯定只有一個(gè),不可能出現(xiàn)多個(gè),所以,出于性能的考慮,我不想用filter()給我從頭遍歷到尾,這樣怎么辦?
2.1 findIndex()??好了,既然filter()不支持中斷遍歷,那我們就要找一個(gè)能中斷遍歷的方法,我們可以使用for...of,該方法支持中斷遍歷,但是該方法代碼量較大,不建議使用,感興趣的同學(xué)可以查閱一下。針對(duì)這個(gè)場(chǎng)景,我們可以使用 findIndex()幫我們先獲取到所需元素的索引值,拿到索引后,你要?dú)⒁獎(jiǎng)庪S你便
let testArr = [{name:"鳴人",age:16},{name:"佐助",age:17},{name:"卡卡西",age:26}] let index = testArr.findIndex(item => { return item.age > 16 }); // => 1
或者也可以使用Lodash提供的_.findIndex(),通過(guò)對(duì)象屬性值直接獲取對(duì)應(yīng)索引:
let testArr = [{name:"鳴人",age:16},{name:"佐助",age:17},{name:"卡卡西",age:26}] let index = _.findIndex(testArr, {name:"佐助"}); // => 1
注意:IE 11 及更早版本不支持findIndex() 方法。所以,如果對(duì)瀏覽器兼容有要求,那就用Lodash的 _.findIndex()
2.2 find()??find()顧名思義,就是用來(lái)在數(shù)組中找到我們所需要的元素,并且和some()一樣,只要有一個(gè)滿足即返回該元素,不會(huì)多余遍歷,對(duì)性能很友善。
let testArr = [{name:"鳴人",age:16},{name:"佐助",age:17},{name:"卡卡西",age:27},{name:"佐助",age:17}] let result = testArr.find(item => { return item.name == "佐助"}); // => { name:"佐助",age:17 }
但是!很遺憾IE 11 及更早版本也不支持 find()。
??在實(shí)際工作中,對(duì)數(shù)組的各種操作必須要做到嫻熟、嫻熟、再嫻熟,希望我整理的這些問(wèn)題都能對(duì)大家有所收獲。好了,就這么多吧,后面遇到其他問(wèn)題了再接著補(bǔ)充,希望大家喜歡!謝謝你們的贊!
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/103361.html
摘要:拷貝目錄的話,是拷貝目錄里頭的文件,不包括目錄本身原樣拷貝,不支持遠(yuǎn)程文件設(shè)置指令只能存在一個(gè),多個(gè)的話,執(zhí)行最后的那一個(gè)。設(shè)置鏡像的元屬性指定被其他鏡像作為基礎(chǔ)鏡像時(shí)運(yùn)行的操作指令指定確保服務(wù)出現(xiàn)任何問(wèn)題而意外結(jié)束時(shí),自動(dòng)重新啟動(dòng)。 pause docker pause可以暫時(shí)停止容器,以釋放一部分CPU出來(lái)給其他服務(wù)使用docker unpause可以解凍 docker stop ...
摘要:與比較中與比較關(guān)鍵字用來(lái)在函數(shù)或其他局部作用域中使用全局變量。親自動(dòng)手試后,發(fā)現(xiàn)使用了只會(huì)讀閉包內(nèi)的變量,可以隔著多層上一哥們類比看作為步驟 這篇文章是抄抄寫寫得來(lái)的,純粹是這個(gè)編輯器比筆記的好太多,才在這兒寫。 函數(shù)參數(shù)傳遞 Python的函數(shù)參數(shù)傳遞 對(duì)于變量(與對(duì)象相對(duì)的概念),其實(shí),python函數(shù)參數(shù)傳遞可以理解為就是變量傳值操作,用C++的方式理解,就是對(duì)void*賦值。如...
摘要:前一個(gè)值,當(dāng)前值,索引,數(shù)組對(duì)象產(chǎn)生新數(shù)組的迭代器方法類似,對(duì)數(shù)組的每個(gè)元素使用某個(gè)函數(shù),并返回新數(shù)組和相似,傳入一個(gè)返回值為布爾類型的函數(shù)。 1. 前言 數(shù)組真的是每天用了,但是有很多方法都是記不住,總是要百度查,很煩,所以才寫了個(gè)數(shù)組使用總結(jié),有什么不對(duì)的希望大家指出來(lái)。 2. 思路 先看看這些問(wèn)題都記得很清楚么? 創(chuàng)建數(shù)組,怎么創(chuàng)建數(shù)組的 數(shù)組的構(gòu)造方法Array有哪些方法?E...
摘要:本文是重溫基礎(chǔ)系列文章的第十篇。返回一個(gè)由回調(diào)函數(shù)的返回值組成的新數(shù)組。返回一個(gè)數(shù)組迭代器對(duì)象,該迭代器會(huì)包含所有數(shù)組元素的鍵值對(duì)。回調(diào)函數(shù)接收三個(gè)參數(shù),當(dāng)前值當(dāng)前位置和原數(shù)組。 本文是 重溫基礎(chǔ) 系列文章的第十篇。 今日感受:平安夜,多棒。 系列目錄: 【復(fù)習(xí)資料】ES6/ES7/ES8/ES9資料整理(個(gè)人整理) 【重溫基礎(chǔ)】1.語(yǔ)法和數(shù)據(jù)類型 【重溫基礎(chǔ)】2.流程控制和錯(cuò)誤...
摘要:此專欄文章是對(duì)力扣上算法題目各種方法的總結(jié)和歸納整理出最重要的思路和知識(shí)重點(diǎn)并以思維導(dǎo)圖形式呈現(xiàn)當(dāng)然也會(huì)加上我對(duì)導(dǎo)圖的詳解目的是為了更方便快捷的記憶和回憶算法重點(diǎn)不用每次都重復(fù)看題解畢竟算法不是做了一遍就能完全記住的所 ...
閱讀 3406·2021-11-22 15:22
閱讀 2386·2021-09-06 15:00
閱讀 886·2020-06-22 14:39
閱讀 3714·2019-08-30 15:56
閱讀 1550·2019-08-30 12:55
閱讀 3290·2019-08-29 17:19
閱讀 3239·2019-08-26 11:41
閱讀 625·2019-08-23 17:14