上一篇文章簡單的介紹了一下js的類型,以及數組的增刪方法。這一篇文章,我們一起來看看數組還有哪些用法,以及在實際工作中我們可以用這些方法來做些什么。由於其中有部分內容並不常用,所以我盡量縮小篇幅。在這篇文章內介紹完大部分的數組方法,加快我們實現其它數據結構的腳步。
1、concat()
合並數組,可以合並一個或多個數組。會按照參數順序依次合並進想要合並的數組。
//concat的參數並不是只能傳入數組,字符串,數字,布爾值,對象等都可以傳入。 var arr = [0,1,2,3,4,5,6]; var a = "7"; var b = true; var c = {a:1} var d = [9,10] var newArr = arr.concat(a,b,c,"d",{b:2}) //[0, 1, 2, 3, 4, 5, 6, "7", true, {a:1}, "d", {b:2}]
需要注意的是,concat方法會生成一個新的數組,並不會改變原數組的值。那么這里還是要說一下,concat的主要作用在於合並數組!而且前面也說過,並不建議在數組中存入不同類型的參數,所以上面例子合並的參數只是為了測試可以這么做,但是不要這么做,到時候會有意想不到的亂子!
2、join()
把所有的數組元素依照分隔符(也就是參數)鏈接成一個字符串。如果不傳入參數則以","逗號分隔。該方法同樣會生成一個新的字符串結果。
var arr = ["z","a","k","i","n","g"]; var arrStr = arr.join("-"); //["z", "a", "k", "i", "n", "g"] //z-a-k-i-n-g
3、some()和every()
some()方法,會遍歷數組中的每個元素,直到返回false結束!而every()呢,與some()相反,直到返回true結束!下面簡單舉兩個例子:
var isEven = function (val) { return (val % 2) == 0 ? true : false; } var nums = [1,2,3,4,5,6,7,8,9,10]; var judgeA= nums.every(isEven) //false var judgeB = nums.some(isEven) //true
解釋一下,其實簡單來說,some用來判斷本數組中是否存在(至少有一個)符合傳入函數的條件的值,而every則判斷是否本數組中每一個值都符合條件。
那么在上面的例子中,some方法確定數組中存在符合條件的值,所以返回true,后面有沒有符合條件的跟我沒關系了。只要找到找一個符合條件的就說明我可以返回true了。如果some方法遍歷了整個數組還沒有找到符合條件的值,則會遺憾的返回false。
而every方法,跟some方法其實剛好相反。我只要發現一個不符合條件,我就高高興興的返回false,只有在遍歷了整個數組元素發現都符合條件,才會可憐兮兮的返回true。
如果要記憶區分這兩種方法,其實並不是很難,every(每一個),說明只有所有都對才算是true。而some(一些),說明你有一個就行啦,我就給你返回true。
4、forEach(),map()和filter()
敲黑板!這是重點!重點!
forEach():
forEach()方法,它接受一個方法(function)作為參數,該方法中可以有三個參數(item,index,arr)分別是調用forEach數組中的每一項元素,每一項元素的下標,調用forEach方法的數組。該方法會遍歷數組中的每一項,為每一項執行你想做的事,不更改原數組並且沒有返回值。但是我們可以自己通過數組的索引來修改原來的數組。
var nums = [1,2,3,4,5,6,7,8,9,10]; var newNumsB = []; var newNumsA = nums.forEach(function (item,index,arr){ newNumsB.push(item + 100) arr[index] = item + 10; }) console.log(nums) //[11, 12, 13, 14, 15, 16, 17, 18, 19, 20] console.log(newNumsB) //[101, 102, 103, 104, 105, 106, 107, 108, 109, 110] console.log(newNumsA) //undefined
forEach方法並不會改變原數組,如果你想要操作調用方法所修改后的值,需要把他重新賦值給一個空數組,或者,如果修改原數組是你想要的結果,那么可以通過匿名函數的第三個參數來獲取到原數組從而更改他。
map():
map()方法,其實簡單來說就是一個映射,但是map必須要有返回值,並且map會返回一個新數組。同樣的,map也可以有三個參數,跟forEach是一樣的。但是,你卻無法向forEach那樣來通過匿名函數的第三個參數來改變原數組,因為map需要return!
var nums = [1,2,3,4,5,6,7,8,9,10]; var newMapNums = nums.map(function (item,index,arr) { console.log(item,index,arr); return item * item; }) console.log(newMapNums) // [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
filter():
還有一個filter()方法,也就是“過濾”。filter會返回一個調用該方法數組的一個子集,什么意思呢,就是說filter的參數是一個函數,該函數是用來邏輯判斷的(類似於every和some的那種判定),如果判斷結果返回true或者可以作為true值返回,那么就會成為這個子集中的一個元素。簡單說就是,你(調用filter方法的數組中每一個元素)是否能通過我(filter的function方法)的判定,如果可以就會成為我(返回的新數組)的一員。
var nums = [1,2,3,4,5,6,7,8,9,10]; var newNums = nums.filter(function(item,index,arr){ return item > 5 }) console.log(newNums) //[6, 7, 8, 9, 10]
這里要注意的是,原數組仍舊是無法更改的,跟map一樣。因為它有返回值,是通過返回值來組織新的數組的。
5、reduce()
英文的解釋是縮減,剛好,咱們js中reduce方法差不多就是這個意思。該方法接收一個函數作為累加器,數組中的每個值(從左到右)開始縮減,最終計算為一個值。
reduce的參數有點多,我還是這樣寫吧reduce(function(total,item,index,arr){},initalVal)。其中item,index,arr我就不說了,大家都知道是啥。total是啥呢?initalVal能猜到是什么么?
var nums = [1,2,3,4,5,6,7,8,9,10]; var newNums = nums.reduce(function(total,item,index,arr){ return total + item*100 },100) console.log(newNums) //5600
total其實就是指你之前所累加的值,而initalVal就是你最初的total是多少,也就是你在即將開始reduce方法時初始值是多少(從什么值開始累加),可以不傳或者傳為0。那我就有點小問題了,reduce只能做數值的計算么?能不能加字符串,布爾值設置數組呢?咱們來小試一下。
var strs = ["a","b","c","d","e","f"]; var newStrs = strs.reduce(function(total,item,index){ return total + item + "-" }) console.log(newStrs) //ab-c-d-e-f-
哎?竟然會是這樣的結果,那么咱們來看看為什么。首先咱們沒有傳initalVal,那么就是從strs的第一項開始加,total的第一個值為字符串”a“,而后面呢我們又return了item + ”-“,也就說是從數組的第二項開始得到了我們想要的結果,最后我們給數組的最后一個元素”f“,也加上了”-“,這就是為啥會有這樣的結果的原因了。所以,如果大家確實一定不得不想要做這樣的操作,請你用join方法!
那么,我們可不可以在數組中加入其它元素呢?這里不再贅述,你們要自己去試試噢。
6、toString(),把數組中所有元素作為字符串輸出。
toString有點類似於join,但是join是數組方法,toString卻適用於幾乎所有的javascript對象。這里不多說,點一下就好。
7、valueOf()
與toString和join在數組中的使用方法是一樣的,也同樣是返回以逗號分隔的字符串對象。
但是這里不會多說但是會強調,toString和valueOf都不僅僅只是數組的方法,他們幾乎適用於所有的原生JS對象。而且依照對象的不同會有不同的展現形式!
8、indexOf()和lastIndexOf()
這兩個東西不太好解釋,我看看怎么簡單說明一下呢~~~。
indexOf是返回與參數匹配的第一個元素的索引,lastIndexOf返回與參數匹配的最后一個元素的索引。
var nums = [0,1,2,3,4,5,6,6,7,"a",9,10,{name:"zaking"},["b","c"]]; var a = nums.indexOf(7); var b = nums.lastIndexOf(7); var c = nums.indexOf(6); var d = nums.lastIndexOf(6); var e = nums.indexOf(100); var f = nums.lastIndexOf(100); console.log(a,b,c,d,e,f) //8 8 6 7 -1 -1 var x = nums.indexOf("a"); var y = nums.lastIndexOf("a"); console.log(x,y); //9 9 var m = nums.indexOf({name:"zaking"}); var n = nums.lastIndexOf({name:"zaking"}); console.log(m,n) //-1,-1 var i = nums.indexOf("b"); var j = nums.indexOf(["b","c"]) console.log(i,j) //-1,-1
其實可以說indexOf是從數組的頭部開始搜索,搜索到了匹配的第一個值就停止搜索並返回該值的下標。而lastIndexOf則是從尾部開始,搜索到了第一個匹配的值就停止並返回該值的下標。
這里有一個令人不容易注意但是卻十分容易混亂的事情,就是,無論從頭還是從尾來搜索數組,數組的下標計算方式是永遠不會變的,所以,不要認為從尾部搜索就是尾部的第一個數組元素下標為0,不是這樣的!
那么再說,如果搜索的參數在數組中並不存在,那么則返回-1,兩個方法都是一樣的。
而且我們還可以從上面的簡單測試代碼中發現,這兩個方法的參數只適用於基本類型,如果對數組中的引用類型元素進行索引查找是不可以也通常是不會應用的!
那么這篇文章就到這里了,簡單介紹了ES5數組的幾乎所有的方法,其實ES6對數組進行了不錯的擴展並且新增了很多方法,但是這里不會多說,因為那樣的話又會多出幾篇的篇幅,還有一個原因就是阮一峰大神的ES6入門已經介紹的十分詳細,大家如果有興趣可以自行查閱。下一篇文章會介紹一下多維數組(也就二維三維...)和數組的簡單排序。
最后,由於本人水平有限,能力與大神仍相差甚遠,若有錯誤或不明之處,還望大家不吝賜教指正。非常感謝!