javascript中數組的方法你真的都了解嗎?


本篇文章主要講述ES5中的數組,包括數組兩種創建方式,屬性,以及 9 大類 ,總共23個操作方法,非常全面,看完之后ES5數組這一部分基本都了解了,下一篇文章,我會講述ES6中對數組的加成,新增了哪些方法,以及定型數組,類數組和類數組的所有方法,記得關注哦!

數組作為javascript中最常用的數據類型之一,掌握好數組的方法在日常的開發中是非常有必要的,javascript中的數組相比其他語言來說更靈活,因為數組的每一項都可以是不同的數據類型,可以是對象,數組,字符串,數值等等,接下來一點一點的了解吧!

1.數組的創建

說到數組首先肯定是創建,只有創建或者聲明一個變量是數組之后才可以使用它,以及他的一些屬性和方法。數組的創建有兩種方式,即,構造函數式和數組字面量式。

  • 第一種構造函數式創建,利用new Array來創建,下面先上一段例子:

    var arr =  new Array();
    var arr1 = new Array(3);
    var arr2 = new Array("xiao mage");
    var arr3 = new Array(12,34,);
    var arr4 = new Array(,,,,,);
    console.log(arr);				//[]			
    console.log(arr1);			//[empty*3]
    console.log(arr2);			//["xiao mage"]
    console.log(arr3);			//在谷歌瀏覽器中報錯,不能多逗號,注意
    console.log(arr4);			//在谷歌瀏覽器中報錯,這樣也是不行的
    

    分析一下,第一行創建了一個空數組;第二行創建了一個長度為3的空數組,注意這個3是數組的長度為3,不是數組的第一項是數值3,切記!在下一篇講到的類數組方法Array.of()方法就可以創建數值3;第三個是創建了一個字符串數組,里面只有一個值;第四行,第五行都目前chrome瀏覽器無法編譯通過,寫法有問題,特意列出來注意一下。 在使用Array 的時候new也可以省略,其效果也是一樣的。

  • 第二種是數組字面量創建數組,即直接用[]。

    var arr = [];             		//[]
    var arr1 =[12,34,];			    //[12,34]
    var arr2 = [,,,,] ;  		    //[empty*4]
    var arr3 = ["xiaomage"];		//["xiaomage"]
    var arr4 = [1,2,3,4,5];			//[1,2,3,4,5]
    var arr5 = [1,{"a":1,"b":2},[434,798],"xiaomage"];
    console.log(arr);				//[]			
    console.log(arr1);			//[12,34]
    console.log(arr2);			//[empty*4]
    console.log(arr3);			//["xiaomage"]
    console.log(arr4);			//[1,2,3,4,5]
    console.log(arr5);			//[1, {…}, Array(2), "xiaomage"],展開就是[1,{"a":1,"b":2},[434,798],"xiaomage"]
    
    

    再分析一下,第一行也是創建了一個空數組;第二行創建了一個長度為2的數組,數組中包含12,34,在有的瀏覽器中長度為3,注意一下。第三行創建了一個長度為4的空數組,數組的每一項值是undefined,有的瀏覽器也可能數組的長度是5。第四行創建了一項含有字符串的數組;第五行創建一個全是數值的數組,最后一行創建了一個長度為4的數組,每一項都是不同的數據類型。

    注意: 1. var arr = new Array(,,,,);是報錯的,而var arr = [,,,,];是可以創建數組的;以及var arr = new Array(12,34,)也是報錯的,而var arr = [12,34,]是可以的,這些注意不要搞混淆了,日常工作中都不推薦此種方法創建數組; 2. 雖然兩種方法都可以創建數組,但是數組字面量要比構造函數的性能好,原因是:json格式的語法瀏覽器引擎能直接解析,而new Array需要調用Array的構造器。日常工作中可以使用前者,方便快速省性能。

2. length屬性

大家都知道length屬性表示數組的長度為多少,現在用構造函數式和數組字面量式創建一個長度為10的空數組,試試看:

var  arr = new  Array(10);
console.log(arr.length) ;     			//10
var arr1 = [];
console.log(arr1.length);		        //0
arr.length = 10;
console.log(arr);      					//[empty*10]
var arr2 = [,,,,,,,,,,];
console.log(arr2.length);         		//10

現在用數組的length屬性來操作數組的長度,不用arr.pop()和arr.shift()方法怎么來搞呢?

var arr1 = [0,1,2,3,4,5,6,7,8,9];
console.log(arr1.length);          //10
arr1.length = 8;
console.log(arr1);                //[0,1,2,3,4,5,6,7]

var arr2 = [1,2];
arr2.length = 100;
console.log(arr2) ;                 //[1, 2, empty × 98]
console.log(arr2[10]);               //undefined
arr2[99]  = 'xiaomage';
console.log(arr2)                   //[1, 2, empty × 97, "xiaomage"]
console.log(arr2.length);
arr2[arr2.length] = 1100000;
console.log(arr2);					//[1, 2, empty × 97, "xiaomage",1100000]

分析一下:首先arr1 是一個長度為10的數組,當把數組的長度成為8的時候,此時會從數組的第一個元素開始向后截取8個作為數組的新值,此操作會改變數組。 arr2是一個長度為2的數組,將數組的長度設為100后,將依次為數組的剩余97項設置值為undefined,當再改變某一項的元素的時候就是正常的賦值了,最后一個給數組添加一項,當前數組的最后一項的索引是length-1,當arr.length就是添加一項。

3.數組的檢測

數組作為引用類型之一,檢測方法有兩種:instanceof和isArray。其中instanceof適用於在一個網頁或者一個全局作用域的情況比較實用,隨着前端框架越來越多,在項目 中引入太多的框架的時候,每個框架對數組可能進行過二次封裝,這樣導致一個問題就是instanceof 返回的結果可能會不同,使用時得注意,基本用法如下:

var arr = [] ;
console.log(arr instanceof Array);			//true

基於以上的問題,ES5又新增了新的檢測方法,isArray 來確定某個值到底是不是數組,而不用管其他的作用域問題。寫法如下:

var arr = [];
console.log(Array.isArray(arr));   		//true

4.類棧操作相關

數據結構棧的特點就是后進先出(LIFO, last-in-first-out) ,比喻成容器罐好理解點,最后放的在上面,拿的時候也先從上面拿,操作推入和彈出,都發生在棧的頂部,javascript數組中有專門的方法push()和pop()來模擬棧的操作。

push()方法,接受不限制個數的參數,在數組的末尾插入元素,返回值是修改后的數組的長度,此方法會改變原數組;pop()方法,不接受參數,從數組的末尾來刪除最后一個元素,返回值是刪除的元素,此方法也會改變原數組。下面我們來看看具體用法:

var arr = [92,09,13,'xiaomage'];
console.log(arr.length);					//4
var count = arr.push('daqianduan',89);
console.log(count);							//6
console.log(arr);							//[92, 9, 13, "xiaomage", "daqianduan", 89]
var item = arr.pop();
console.log(item);							//89
console.log(arr);							//[92, 9, 13, "xiaomage", "daqianduan"]

5.類隊列操作相關

上面聊完了棧,現在來看看隊列,相信這兩個詞大家都不陌生,隊列的特點是:先進先出(FIFO , first-in-first-out),看做是一個空的管道比較好理解,從一端進入,另一端出去。javscript數組提供了shift()和push()方法來模擬隊列的特點。

shift() , 從數組的頭部刪除一個元素,返回值是刪除的元素,此方法會改變原數組,看看使用情況:

var arr = [25,78,{'a':1,'b':10},'javascript'];
var count = arr.push([12,34]);
console.log(count);					//5
console.log(arr);					//[25, 78, {…}, "javascript", Array(2)]
var item = arr.shift();
console.log(item);					//25
console.log(arr);					//[78, {…}, "javascript",Array(2)]
console.log(arr.length);			//4

跟shift()方法結果剛好相反的是unshift()方法,shift()是從數組頭部刪除元素,而unshift()剛好是從頭部添加元素,接受不限個數的參數,返回值是改變后的數組的長度,此方法會改變數組,其實,這個方法效果跟push()一樣,只不過一個在數組前面插入,一個在后面插入,看看效果:

var arr = ['xiaomage',[15],90,23];
arr.push('string1',10);
console.log(arr);								//["xiaomage", Array(1), 90, 23, "string1", 10]
var count = arr.unshift([34,45],'string2');
console.log(count);								//8
console.log(arr);								//[Array(2), "string2", "xiaomage", Array(1), 90, 23, "string1", 10]
arr.shift();
console.log(arr);								//[Array(2), "string2", "xiaomage", Array(1), 90, 23, "string1", 10]
arr.pop();
console.log(arr);								//["string2", "xiaomage", Array(1), 90, 23, "string1"]

6.數組的重排序方法

說到數組的重排序方我們肯定想到的是reverse()和sort()方法,來了解一下這兩個方法,首先:

reverse()方法是將數組進行反轉,調換順序,比較簡單哈,返回結果是改變順序后的數組,此方法會改變原數組。

var arr = [0 ,1 ,2 ,4,5,10,15];
var arr2 = arr.reverse();
console.log(arr2);					//[15, 10, 5, 4, 2, 1, 0]
console.log(arr);					//[15, 10, 5, 4, 2, 1, 0]

即返回的結果就是原數組改變后的結果,二者是相等的,但是這個方法只能反轉不方便啊,比如說我想把數組按照升序或者降序排列,reverse就干不了,這時候就得用到sort()方法了。

sort()方法,默認是按照升序排列的,返回的結果也是改變后的數組,此方法會改變原數組。

var arr = [0,1,10000000,15,10,5];
var arr1 = arr.sort();
console.log(arr);					//[0, 1, 10, 10000000, 15, 5]
console.log(arr1);					//[0, 1, 10, 10000000, 15, 5]

首先,同學們可能會疑問,怎么返回的結果跟我預想的不一樣呢,不應該是[0 , 1 , 5, 10 ,15 , 10000000]嗎?這是因為當調用sort()方法的時候,首先sort()會把數組的每一項值都先調用toString()方法變成對應的字符串,即['0','1','10000000','15','10','5'];第二步再進行字符串的比較,挨個字符比較。上一篇《一篇文章搞定javascript中的字符串》我講過字符串的比較方法,不了解的回過去看一下哈,然后得出結果[0, 1, 10, 10000000, 15, 5]。

這里同學可能就有疑問,我就想要結果[0 , 1 , 5, 10 ,15 , 10000000]。也不是不可以,這時候我們可以使用sort()方法的參數來進行處理,此方法接受一個比較函數來作為一個參數,里面我們可以自定義我們想要的結果,是想讓升序呢,還是降序都可以實現。

var arr = [0,1,10000000,15,10,5];
var arr1 = arr.sort(compareArray);
console.log(arr1);						//[0, 1, 5, 10, 15, 10000000]
console.log(arr);						//[0, 1, 5, 10, 15, 10000000]

function compareArray(item1,item2){
    if(item1 < item2 ){
        return -1 ;
    }else if(item1 > item2 ){
        return 1 ;
    }else{
        return  0 ;
    }
}

是的,我們想要的結果得到了,這里解釋一下compareArray,次方法作為sort()方法的參數,接受兩個參數,分別是要比較的數組的兩項,返回結果是三種,大於0 ,小於0,或者等於0.然后sort根據返回的結果,如果小於零則不用換位置,如果大於零則需要調換位置,等於零則代表相等,不做處理,進行下一次的比較。

前面我們看了升序的寫法,那么降序也是一樣的,只不過把返回值調換一下就可以了。

var arr = [0,1,10000000,15,10,5];
var arr1 = arr.sort(compareArray);
console.log(arr1);						//[10000000, 15, 10, 5, 1, 0]
console.log(arr);						//[10000000, 15, 10, 5, 1, 0]
function compareArray(item1,item2){
    if(item1 < item2 ){
        return 1 ;
    }else if(item1 > item2 ){
        return -1 ;
    }else{
        return  0 ;
    }
}

//這里我只是把sort的參數方法提出來了,下面這樣寫也是等價的。
var arr2 = arr.sort(function(item1 , item2){
     if(item1 < item2 ){
        return 1 ;
    }else if(item1 > item2 ){
        return -1 ;
    }else{
        return  0 ;
    }
});
console.log(arr2);

看着一個數組的比較,寫了這么多的代碼,有沒有高級寫法,簡寫的讓自己的代碼看起來更有逼格一點呢,當然有啊,這里我們用到ES6來改寫一下:

var arr = [0,1,10000000,15,10,5];
arr.sort((item1 , item2)=> item1 - item2);
console.log(arr);				//[0, 1, 5, 10, 15, 10000000]  

簡單明了,這是升序的結果,如果想要降序用item2 - item1就可以。這里稍微解釋一下,第一,箭頭函數是原始函數的簡寫,方便輕巧,第二,當箭頭函數中代碼塊中只有一行語句並且包含return時,可以省略{}和return。關於ES6后面的文章中我會在后面的文章中寫,記得關注。

7.數組的轉換方法

數組的轉換方法有三個toString(),toLocaleString(),valueOf().

toString(),將數組轉換成字符串 ,返回值是改變后的字符串,此方法不會改變數組。

var arr = [1, 'xiaoma' , [1,2,3], 10000];
var str = arr.toString();
console.log(arr);			//(4) [1, "xiaoma", Array(3), 1000]
console.log(str);			//1,xiaoma,1,2,3,1000

toLocaleString(),在有的時候,結果和toString()一樣,當然也不總是 一樣,,這得跟當地的編碼有關,使用時也得注意,此方法轉換時每一項都調用toLocaleString()。

var arr = [1, 'xiaoma' , [1,2,3], 1000000];
var str = arr.toLocaleString();
console.log(arr);			//[1, "xiaoma", Array(3), 1000000]
console.log(str);			//1,xiaoma,1,2,3,1,000,000
var arr2 = str.split(',');
console.log(arr2);			//(8) ["1", "xiaoma", "1", "2", "3", "1", "000", "000"]

在我們地區,超過三位以上的數字會以 ’,‘ 隔開的。所以得到的結果會和toString()不同。

valueOf(),該方法是數組對象的默認內置方法,返回Array對象的原始值,該原始值由Array對象派生的所有對象繼承,此方法不會改變原數組。

var arr = [1, 'xiaoma' , [1,2,3], 1000000];
var arr2 = arr.valeuOf();
console.log(arr);			//[1, "xiaoma", Array(3), 1000000]
console.log(arr2);			// [1, "xiaoma", Array(3), 1000000]

注意:所有的對象含有toString(),toLocaleString(),valueOf()這三個內置方法,並不是數組獨有。

8.數組的操作方法

  • concat():顧名思義,連接,將一些數組拼接到一起形成一個新的數組,此方法不改變原數組。可以接受任意多個參數,參數可以是數組,字符串,數值都可以。當不傳參數的時候只返回原數組的副本。
var arr = ['xiaoma' , 324, 90, 33] ;
var arr1 = arr.concat();
var arr2 = arr.concat('javascript',[1,3,,4],[5,6,7],10);
console.log(arr);			//["xiaoma", 324, 90, 33]
console.log(arr1);			//["xiaoma", 324, 90, 33]
console.log(arr2);			//["xiaoma", 324, 90, 33, "javascript", 1, 3, empty, 4, 5, 6, 7, 10]
  • slice():即截取,接受一個或者兩個參數,第一個參數是要截取的起始項,第二個參數是截止項。當只有一個參數的時候,默認是從起始項到數組末尾,該方法返回的是一個新數組,不改變原數組。
var arr = ['xiaoma', [1,2,3],10,45,{'a':1,'b':2},'javascript'];
var newArr = arr.slice(1);
var newArr2 = arr.slice(2,4);
console.log(arr);				//["xiaoma", Array(3), 10, 45, {…}, "javascript"]
console.log(newArr);			//[Array(3), 10, 45, {…}, "javascript"]
console.log(newArr2);			// [10, 45]

當slice的參數中含有負數的參數的時候,則用數組的長度+負參數作為新的參數值再開始截取,計算后的第二個參數比第一個參數小時,則返回的是一個空數組。

var arr = ['xiaoma', [1,2,3],10,45,{'a':1,'b':2},'javascript'];
var newArr = arr.slice(-3,-2);  //重新計算相當於slice(3,4)
console.log(newArr);				//[45]
var newArr2 = arr.slice(-3,-4);		//slice(3,2)
console.log(newArr2);				//[]

  • splice(): slice 是截取數組,而splice是向數組中插入元素或者刪除元素,或者替換元素,參數的個數的不同起到的作用也不同。

    1. 刪除元素,兩個參數,第一個是起始位置,第二個是要刪除的個數。此方法會改變原數組,返回值是刪除的新數組,不改變原數組。
  var arr = [1,2,3,4,5,6,7,8];
  var item = arr.splice(3,3);
  console.log(item);			//[4, 5, 6]
  console.log(arr);			//(6) [1, 2, 3, 7, 8]

2.插入元素,三個參數,第一個參數是起始位置,第二個參數刪除的個數為0,第三個是要插入的元素,如果要插入多個項,則會有第四個,五個參數,總之,從第三個開始都是要插入的項數,返回值是[],會改變原數組。

var arr = [1,2,3,4,5,6,7,8];
var item = arr.splice(4,0,"xiaomage");
console.log(arr);		//(9) [1, 2, 3, 4, "xiaomage", 5, 6, 7, 8]					
console.log(item);      //[]
var item2 = arr.splice(5,0,[10,23,45],"js","web");
console.log(arr);		//(12) [1, 2, 3, 4, "xiaomage",[10,23,45], "js", "web", 5, 6, 7, 8]
console.log(item2);		//[]
  1. 替換元素,三個以上的參數,其中第二個參數不能為0,否則就是插入元素了,先刪除后替換。返回值是刪除原數組的元素所組成的數組
var arr = [1,2,3,4,5,6,7,8];
var item = arr.splice(3,2,100000,10000001,10002);
console.log(arr);			//(9) [1, 2, 3, 100000, 10000001, 10002, 6, 7, 8]
console.log(item);			// [4, 5]

分析一下,首先是從第三個開始刪除了兩項,得到[4,5],然后再在此位置上插入了三項,刪除項和替換項不一定要相等。

9. 查找位置相關的方法

javascript數組提供查找位置的方法有兩種,indexOf()和lastIndexOf(). 查找的時候當數組中有重復的元素是只返回首次出現的元素的位置。

  1. indexOf(): 如果在數組中能查找到則返回其索引值,如果找不到則返回-1。此方法接受兩個參數,第一個參數是要查找的元素,第二個參數是查找的起始位置, 如果沒有第二個參數則默認從0開始查, 如果第二個參數是負數的話,則將其作為數組末尾值得一個抵消,即-1表示從最后一個元素開始向后查找,-2表示從倒數第二個元素查找。 如果第二個參數大於數組的長度,表示 已經超出查找范圍了,直接返回-1。一直都是從前向后查找,跟參數是不是 負數,查出范圍沒關系,此方法不會改變原數組。
  2. lastIndexOf(): 與indexOf()不同的是這個方法是從后向前查找,其他的都一樣。
var arr =  [1, 2, 3, 100000, 10000001,[34,45],6,3 ,10002, 6, 7, 8];
var count = arr.indexOf(6);		
var count5 = arr.indexOf(6,100);
var count1 = arr.indexOf([34,45]);
console.log(count);						//6
console.log(count5)						//-1
console.log(count1);					//-1
var count2 = arr.indexOf("xiaoamge");
console.log(count2);					//-1
var count3  = arr.lastIndexOf(3);
console.log(count3);					//7
var count4 = arr.lastIndexOf([34.45]);
console.log(count4);					//-1

10.數組的迭代方法

數組的迭代在ES5中是有5個,分別是every,filter,forEach,map,some,這五個方法接受兩個參數,第一個是函數,是要作用在數組的每一項上面的函數,第二個參數是作用域對象,可選,默認是this即數組對象本身。第一個參數函數接受三個參數,分別是數組的每一項,第二個是索引,第三個是當前的數組。下面分別來看一下其含義和用法:

  • every() : 英文意思,簡單理解是每一個,即作用在數組每一項上面的函數的返回都為true的時候,Array.every才返回true,此方法不會改變原數組。看一個例子,有一個學生的成績數組,判斷是不是都及格了,看看怎么寫:
var arr = [99,57,67,88,100,78];
var result = arr.every(function(item, index ,array){
    return item > 60 ;
});
console.log(result);			//false
console.log(arr);				//[99,57,67,88,100.78]

var arr2 = [100,98,87,76,61];
var result2 = arr2.every(function(item, index , array){
    return item >60 ;
});
console.log(result2);			//true
  • filter() : 過濾,即把符合指定條件的過濾出來,比較簡單,看看例子,把及格的學生篩選出來:
var arr = [99,57,67,88,60,100,78];
var newArr = arr.filter(function(item , index ,array){
    return item >= 60 ;
});
console.log(newArr);			//[99, 67, 88, 60,100, 78]
  • forEach() : 遍歷數組的每一項然后進行后續的邏輯操作 , 此方法沒有返回值。
var arr = [99,57,67,88,60,100,78] ;
var newArr = [] ;
arr.forEach(function(item , index ,array){
    if(item >=60){
        newArr.push('及格') ;
    }else {
        newArr.push('不及格') ;
    };
});
console.log(newArr); 			//["及格", "不及格", "及格", "及格", "及格", "及格", "及格"]
  • map() : 遍歷整個數組的每一項,返回指定操作后的結果。
var arr = [99,57,67,88,60,100,78] ;
var newArr = arr.map(function(item , index ,array){
    //return item * 10 +10 ;		//[1000, 580, 680, 890, 610, 1010, 790]
    return item>=60 ? '及格' : '不及格' ;
});
console.log(newArr) ; 			//["及格", "不及格", "及格", "及格", "及格", "及格", "及格"]
  • some() :此方法跟every()不同的是,every只有都滿足條件的時候才返回true ,some是只要有一個滿足條件就返回true。every 類似於 && ,而some 類似於 ||。看個例子,查看班級里面有沒有成績超過90分的同學,並且計算有幾個:
var arr = [45, 60 , 80, 90 ,99 ,94];
var count = 0 ;
var result = arr.some(function(item , index , array){
   return item >90 ; 
});
console.log(result) ;		//true

var count = arr.filter(function(item , index ,array){
    return item >=90;
}).length;
                       
console.log(count) ;		//3

11.數組的縮小方法

ES5中提供了兩個數組縮小的方法,reduce()和reduceRight(), 兩個方法都會遍歷數組的所有項,然后返回一個操作后的最終結果。這兩個方法都接受兩個參數,第一個,作用在數組項上的函數,第二個,是 作為縮小基礎的初始值,可選。

  • reduce() : 接受四個參數,分別是前一個值(prev),當前值(cur),索引 (index),以及當前數組本身(array),參數名字隨便起。當reduce的第二參數有值的時候,第一次遍歷的時候,函數的的第一個參數(prev)就是這個初始值,沒有值時,第一次遍歷的時候前一個值(prev)和當前值(cur)分別是數組的前兩項。有點斐波那契數列的感覺,遍歷的時候是從前向后。來看一個字符串拼接操作應用:
var arr= ['hello' ,'_this' , '_is' , '_javascript' ,'_Array'];
var result = arr.reduce(function(prev, cur ,index , array ){
    console.log(prev , cur) ;
    // xiomage_  hello
	// xiomage_hello  _this
	// xiomage_hello_this  _is
	// xiomage_hello_this_is  _javascript
	// xiomage_hello_this_is_javascript  _Array
    return prev + cur ;
},'xiomage_');
console.log(result);		//xiomage_hello_this_is_javascript_Array
  • reduceRight() : 和reduce唯一不同的是從后向前遍歷,類似於indexof和lastIndexOf()的查找順序,一個前面開始,一個從后面開始。
var arr = [1,2,3,4,5,6];
var result = arr.reduceRight(function(prev,cur,index,array){
    return prev + cur ;
});
console.log(result);			//21

好了,ES5數組的所有的方法已經講完了,總共9大類,23個函數,你都了解了嗎?

下一篇文章,我會講述ES6中對數組的加成,新增了哪些方法,以及定型數組,類數組和類數組的所有方法,記得關注哦!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM