JavaScript 處理數組函數總結

JavaScript 的array可以包含任意數據類型,並通過索引來訪問每個元素。

1、檢測數組:instanceofslice()Array.isArray()

_檢測一個對象是不是數組_的三種方法:
(1) 方法一:instanceOf 檢測方法

var arr = ['a','b','c'];
if (arr instanceof Array){
// do something...
}

或者:

var arr = ['a','b','c'];
if (Array.prototype.isPrototypeOf(arr)){
// do something...
}
  • 問題:instanceof 操作符假設只有一個全局執行環境。如果網頁中包含多個框架,那實際上存在兩個以上的不同全局執行環境,從而存在兩個以上不同版本的Array構造函數。如果從一個框架向另一個框架傳入數組,那麼傳入的數組與第二框架中原生的數組分別具有各自不同的構造函數。從而將傳入的數組誤判爲非數組。

  • 注意:如果只有一個全局執行環境,可以用 instanceof檢測數組,關於instanceof操作符的原理,請移步這裏理解 Javascript_07_理解 instanceof 實現原理.

A instanceof B: 檢查B.prototype 是否存在於A的原型鏈[[prototype]]中。

(2) 方法二:Array.isArray(obj) 方法

var arr = ['a','b','c'];
if (Array.isArray(arr)){
// do something...
}

這個方法克服了instanceof的問題,可以確定某個變量是不是數組,而不管它是在哪個全局執行環境中創建的。

  • 問題:但是支持Array.isArray()方法的瀏覽器有IE9+Firefox4+Safari5+Opera10.5+Chrome

(3) 方法三:萬能方法

function isArray(arr){
    return Object.prototype.toString.call(arr) == '[object Array]';
}
var arr = ['a','b','c'];
isArray(arr);//true
  • 原理:在任何值上調用Object原型的toString() 方法,都會返回一個[object NativeConstructorName] 格式的字符串。每個類在內部都有一個 [Class] 屬性,這個屬性就指定了上述字符串中的構造函數名NativeConstructorName。如:
var arr = [];
console.log(Object.prototype.toString.call(arr)); // "[object Array]"
  • 引申: 這種思路也可用於檢測某個值是不是原生函數或正則表達式。
// Array
Object.prototype.toString.call(value); // "[object Array]"

// Function
Object.prototype.toString.call(value); // "[object Function]"

// RegExp
Object.prototype.toString.call(value); // "[object RegExp]"

// Date
Object.prototype.toString.call(value); // "[object Date]"
  • 注意:ObjecttoString()方法不能檢測非原生的構造函數的構造函數名,因此,開發人員定義的任何構造函數都將返回[object Object]

2、獲取數組長度:length

直接訪問length屬性獲取數組長度:

var arr = [1,'hihi',3.14,null,true];
arr.length;//5

注意: length還是可寫的,直接給Arraylength賦一個新的值會導致Array大小的變化:

var arr = [1,2,3];
arr.length;//3
arr;//1,2,3
arr.length = 5;
arr;//1,2,3,undefined,undefined
arr.length = 2;
arr;//1,2

通過設置Arraylength屬性,可以從數組的末尾移除或者添加若干新項。
利用length屬性還可以方便的向數組末尾添加新項:arr[arr.length]="black",不過,這種方法通常可以用'push'方法來替代。

3、修改數組元素

Array可以通過索引把對應的元素修改爲新的值,因此,對Array的索引進行賦值會直接修改這個Array

var arr = [1,2,3];
arr[2] = 5;
arr;//1,2,5

_注意:_如果通過索引賦值時,索引超過了範圍,仍然會引起Array的大小變化:

var arr = [1,2,3];
arr[5] = 8;
arr;//1,2,3,undefined,undefined,8

**建議:**大多數其他編程語言不允許直接改變數組的大小,越界訪問索引會報錯。然而,JavaScript 的Array卻不會有任何錯誤。在編寫代碼時,不建議直接修改Array的大小,訪問索引時要確保索引不會越界。

4、位置方法

與 String 類似,Array也可以通過indexOf()來搜索一個指定的元素在Array中_首次_出現的位置:

var arr = [10,20,'30',20,30];
arr.indexOf(20);//1
arr.indexOf(20,2)//3

補充:

stringObject.indexOf(searchvalue,fromindex)
indexOf() 方法可返回某個指定的字符串值在字符串中首次出現的位置。

searchvalue: 必需。規定需檢索的字符串值。
fromindex: 可選的整數參數。規定在字符串中開始檢索的位置。它的合法取值是 0 到 stringObject.length - 1。如省略該參數,則將從字符串的首字符開始檢索。

  • indexOf() 方法對大小寫敏感!

  • 如果要檢索的字符串值沒有出現,則該方法返回 -1。

  • 在判斷查找的項是否存在時,使用的是全等===

  • lastIndexOfindexOf操作符類似,不過是從數組的末尾開始向前查找的。

5、操作方法:slice()concat()splice()

slice()就是對應 String 的substring()版本,它截取Array的部分元素,然後返回一個新的Array

var arr = ['A','B','C','D','E','F','G'];
arr.slice(1,3);//['B','C']
arr.slice(3);//['D','E','F','G']
arr.slice(3,50);//['D','E','F','G']
arr.slice(-3);//['E','F','G']
arr.slice(3,-2);//['D','E']

注意

  • 到 slice() 的起止參數包括開始索引,不包括結束索引。

  • 如果結束索引省略,將返回從開始索引到數組結束的所有元素。

  • 如果結束索引超過了範圍,將返回從開始索引到數組結束的所有元素。

  • 開始索引可以去負值,它規定從從數組尾部開始算起的位置。

補充:

arrayObject.slice(start,end)
slice() 方法可從已有的數組中返回選定的元素。

start: 必需。規定從何處開始選取。如果是負數,那麼它規定從數組尾部開始算起的位置。也就是說,-1 指最後一個元素,-2 指倒數第二個元素,以此類推。(這裏的必需,有待商榷,實際上不寫也是可以的)
end: 可選。規定從何處結束選取。該參數是數組片斷結束處的數組下標。如果沒有指定該參數,那麼切分的數組包含從 start 到數組結束的所有元素。如果這個參數是負數,那麼它規定的是從數組尾部開始算起的元素。

  • 請注意,該方法並不會修改數組,而是返回一個子數組。如果想刪除數組中的一段元素,應該使用方法 Array.splice()

小技巧:複製數組
如果不給 slice() 傳遞任何參數,它就會從頭到尾截取所有元素。利用這一點,我們可以很容易地複製一個 Array:

var arr = ['A','B','C','D','E','F','G'];
var aCopy = arr.slice();
aCopy;//['A','B','C','D','E','F','G']
arr === aCopy;//false(如果,你不知道這裏爲什麼是`false`,那麼你應該去看看原始值和引用對象)

splice()方法是修改Array的 “萬能方法”,它可以從指定的索引開始刪除若干元素,然後再從該位置添加若干元素:

var arr = ['Microsoft', 'Apple', 'Yahoo', 'AOL', 'Excite', 'Oracle'];
// 從索引2開始刪除3個元素,然後再添加兩個元素:
arr.splice(2, 3, 'Google', 'Facebook'); // 返回刪除的元素 ['Yahoo', 'AOL', 'Excite']
arr; // ['Microsoft', 'Apple', 'Google', 'Facebook', 'Oracle']
// 只刪除,不添加:
arr.splice(2, 2); // ['Google', 'Facebook']
arr; // ['Microsoft', 'Apple', 'Oracle']
// 只添加,不刪除:
arr.splice(2, 0, 'Google', 'Facebook'); // 返回[],因爲沒有刪除任何元素
arr; // ['Microsoft', 'Apple', 'Google', 'Facebook', 'Oracle']

補充:

arrayObject.splice(index,howmany,item1,item2,...,itemx)
splice() 方法向 / 從數組中添加 / 刪除項目,然後返回被刪除的項目。

index: 必需。整數,規定添加 / 刪除項目的位置,使用負數可從數組結尾處規定位置。
howmany: 必需。要刪除的項目數量。如果設置爲 0,則不會刪除項目。
item1,item2,...,itemx: 可選。向數組添加的新項目。

  • 返回值:包含被刪除項目的新數組,如果有的話。

注意:

  • splice() 方法可刪除從 index 處開始的零個或多個元素,並且用參數列表中聲明的一個或多個值來替換那些被刪除的元素。

  • 如果從 arrayObject 中刪除了元素,則返回的是含有被刪除的元素的數組。

  • 請注意,splice() 方法與 slice() 方法的作用是不同的,splice() 方法會直接對數組進行修改。

concat()方法把當前的Array和另一個Array連接起來,並返回一個新的Array:

var arr = ['one','two','three'];
var arrAdd = arr.concat([1,2,3]);
arrAdd;//['one','two','three',1,2,3];
arr;//['one','two','three']

_注意:_請注意,concat()方法並沒有修改當前Array而是返回了一個新的Array
實際上,concat()方法可以接收任意個元素和Array,並且自動把Array拆開,然後全部添加到新的Array裏:

var arr = ['one','two','three'];
var arrAdd = arr.concat(1,2,['A','B']);
arrAdd;//['one','two','three',1,2,'A','B']

補充:

arrayObject.concat(arrayX,arrayX,...,arrayX)
concat() 方法用於連接兩個或多個數組。

arrayX: 必需。該參數可以是具體的值,也可以是數組對象。可以是任意多個。

  • 返回值:返回一個新的數組。該數組是通過把所有 arrayX 參數添加到 arrayObject 中生成的。如果要進行 concat() 操作的參數是數組,那麼添加的是數組中的元素,而不是數組。

關於數組的操作方法

  • 如果要修改數組中的某些項的值,可以使用[]splice.

  • 若果要在數組中插入某些項,只能使用'splice'

6、棧方法:pushpop

var arr = [1, 2];
arr.push('A', 'B'); // 返回Array新的長度: 4
arr; // [1, 2, 'A', 'B']
arr.pop(); // pop()返回'B'
arr; // [1, 2, 'A']
arr.pop(); arr.pop(); arr.pop(); // 連續pop 3次
arr; // []
arr.pop(); // 空數組繼續pop不會報錯,而是返回undefined
arr; // []

補充:

(1)push: 方法可向數組的末尾添加一個或多個元素,並返回Array新的長度

arrayObject.push(newElement1,newElement2,...,newElementX)

newElement1: 必需。要添加到數組的第一個元素。
newElement2: 可選。要添加到數組的第二個元素。
newElementX: 可選。可添加多個元素。

  • 返回值:把指定的值添加到數組後的新長度。

  • push() 方法可把它的參數順序添加到 arrayObject 的尾部。它直接修改 arrayObject,而不是創建一個新的數組。push() 方法和 pop() 方法使用數組提供的先進後出棧的功能。

(2)pop: 方法用於刪除並返回數組的最後一個元素

arrayObject.pop()

  • 返回值:arrayObject 的最後一個元素。

  • pop() 方法將刪除 arrayObject 的最後一個元素,把數組長度減 1,並且返回它刪除的元素的值。如果數組已經爲空,則 pop() 不改變數組,並返回 undefined 值。

7、隊列方法:unshiftshift

unshiftshift的作用於pushpop類似,只不過前者操作的是Array的頭部.

var arr = [1, 2];
arr.unshift('A', 'B'); // 返回Array新的長度: 4
arr; // ['A', 'B', 1, 2]
arr.shift(); // 'A'
arr; // ['B', 1, 2]
arr.shift(); arr.shift(); arr.shift(); // 連續shift 3次
arr; // []
arr.shift(); // 空數組繼續shift不會報錯,而是返回undefined
arr; // []

注意: unshift() 方法無法在 Internet Explorer 中正確地工作!

8、重排序方法:sortreserve

sort()可以對當前Array進行排序,它會直接修改當前Array的元素位置,直接調用時,按照默認順序 (將按字母順序對數組中的元素進行排序) 排序:

var arr = ['c','b','a','C','B','A'];
arr.sort();
arr;//['A','B','C','a','b','c'];

補充

arrayObject.sort(sortby)
sort() 方法用於對數組的元素進行排序。

sortby: 可選。規定排序順序。必須是函數。

  • 返回值:對數組的引用。請注意,數組在原數組上進行排序,不生成副本。

  • 如果調用該方法時沒有使用參數,將按字母順序對數組中的元素進行排序,說得更精確點,是按照字符編碼的順序進行排序。要實現這一點,首先應把數組的元素都轉換成字符串(如有必要),以便進行比較

  • 如果想按照其他標準進行排序,就需要提供比較函數,該函數要比較兩個值,然後返回一個用於說明這兩個值的相對順序的數字。比較函數應該具有兩個參數 a 和 b,其返回值如下:

  • 若 a 小於 b,在排序後的數組中 a 應該出現在 b 之前,則返回一個小於 0 的值。

  • 若 a 等於 b,則返回 0。

  • 若 a 大於 b,則返回一個大於 0 的值。

舉例說明:
實例 1:按數字大小對數字排序

function sortNumber(a,b){
    return a-b
}

var arr=[3,5,1,10,21];
arr.sort();
arr;//[1,10,21,3,5];
arr.sort(sortNumber);
arr;//[1,3,5,10,21]

實例 2:默認情況下,對字符串排序,是按照 ASCII 的大小比較的,現在,我們提出排序應該忽略大小寫,按照字母序排序

var arr = ['Google','apple','Microsoft','BUPT'];
arr.sort();
arr;//['BUPT','Google','Microsoft''apple'];
arr.sort(function(s1,s2){
    var x1 = s1.toLowerCase();
    var x2 = s2.toLowerCase();
    if(x1<x2)
        return -1;
    if(x1>x2)
        return 1;
    return 0;
});
arr;//['apple','BUPT','Google','Microsoft']

將整個Array的元素給掉個 (gě) 個(gè),也就是反轉:

var arr = ['one','two','three'];
arr.reverse();
arr;//['three','two','one'];

**注意:**該方法會直接改變原來的數組,而不會創建新的數組。

9、轉換方法:jointoStringtoLocaleStringvalueOf

該方法會返回由數組中每個值的字符串形式拼接而成的一個以分割的字符串. 該方法首先會針對數組中的每一項調用其相應的toString()方法得到字符串,然後再用,拼接這些字符串。

該方法會返回數組本身。

該方法也會創建一個數組值的以,分隔的字符串,但是與前面兩個方法不同的是,這一次爲了取得數組中每一項的值,調用的是每一項的toLocaleString()方法。

join()方法是一個非常實用的方法,它把當前Array的每個元素都用指定的字符串連接起來,然後返回連接後的字符串:

var arr = ['a','b','c',1,2,3];
var arrToString = arr.join('-');
arrToString;//a-b-c-1-2-3

**注意:**如果Array的元素不是字符串,將自動轉換爲字符串後再連接。

補充:

arrayObject.join(separator)
join()方法用於把數組中的所有元素放入一個字符串。元素是通過指定的分隔符進行分隔的。

separator: 可選。指定要使用的分隔符。如果省略該參數,則使用逗號作爲分隔符

  • 返回值:返回一個字符串。該字符串是通過把 arrayObject 的每個元素轉換爲字符串,然後把這些字符串連接起來,在兩個元素之間插入 separator 字符串而生成的。

關於轉換方法,需要注意:

如果數組中某一項的值爲nullundefined, 那麼該值在這些方法的返回結果中以空白字符串表示。

10、迭代方法:everyfilterforEachmapsome

這些方法都接收兩個參數:要在每一項上運行的函數和(可選的)運行該函數的作用域對象——影響this的值。傳入這些方法的函數會接收三個參數:數據項的值、該項在數組中的位置和數組對象本身。

這兩個方法會忽略數組中undefined

注意,該方法與jQuery$().filter()方法的區別

  • filter(expr|obj|ele|fn): 篩選出與指定表達式匹配的元素集合。這個方法用於縮小匹配的範圍。用逗號分隔多個表達式。

expr: 字符串值,包含供匹配當前元素集合的選擇器表達式。
obj: 現有的 jQuery 對象,以匹配當前的元素。
ele: 一個用於匹配元素的 DOM 元素。
fn: 一個函數用來作爲測試元素的集合。它接受一個參數index,這是元素在jQuery集合的索引。在函數, this指的是當前的DOM元素。

注意,該方法不會遍歷只聲明而爲定義的值

注意,該方法與jQuery$.each()each()方法的區別。

  • $.each(object,callback): 不同於例遍 jQuery 對象的 $().each() 方法,此方法可用於例遍任何對象。如果需要退出 each 循環可使回調函數返回 false,其它返回值將被忽略。

object: 需要例遍的對象或數組。
callback: 每個成員 / 元素執行的回調函數。回調函數擁有兩個參數:第一個爲對象的成員或數組的索引index,第二個爲對應變量或內容value

  • $().each(callback): 以每一個匹配的元素作爲上下文來執行一個函數。意味着,每次執行傳遞進來的函數時,函數中的this關鍵字都指向一個不同的DOM元素(每次都是一個不同的匹配元素)。而且,在每次執行函數時,都會給函數傳遞一個表示作爲執行環境的元素在匹配的元素集合中所處位置的數字值作爲參數(從零開始的整型)。 返回 false 將停止循環 (就像在普通的循環中使用 break)。返回 true 跳至下一個循環 (就像在普通的循環中使用continue)。

calback: 對於每個匹配的元素所要執行的函數。回調函數只有一個參數,即 index。

11、歸併方法:reducereduceRight

  • 這兩個方法都會迭代數組中的所有項,然後構建一個最終返回的值。reduce()從數組的第一項開始,逐個遍歷到最後,而reduceRight()從最後一項開始。

  • 這兩個方法都接收兩個參數:一個在每一項上調用的函數,和(可選的)最爲歸併基礎的初始值。

  • 傳給這兩個方法的函數接收 4 個參數:前一個值,當前值,當前值的索引和數組對象。這個函數返回的任何值都會作爲第一個參數自動傳給下一項,因此,第一次迭代發生在數組的第二項上。

參考

1、數組 - 廖雪峯的官方網站
2、js 中 substr,substring,indexOf,lastIndexOf 的用法小結
3、 JavaScript 檢測數組
4、javascript 高級教程

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://segmentfault.com/a/1190000005118701