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