JavaScript中對數組的定義
數組的標準定義是:一個存儲元素的線性集合(collection)
,元素可以通過索引來任意存取,索引通常是數字,用來計算元素之間存儲位置的偏移量。幾乎所有的編程語言都有類似的數據結構。然而JavaScript 的數組卻略有不同。
JavaScript 中的數組是一種特殊的對象,用來表示偏移量的索引是該對象的屬性,索引可能是整數。然而,這些數字索引在內部被轉換爲字符串類型,這是因爲JavaScript 對象中的屬性名必須是字符串。數組在JavaScript 中只是一種特殊的對象,所以效率上不如其他語言中的數組高。
JavaScript 中的數組,嚴格來說應該稱作對象,是特殊的JavaScript 對象,在內部被歸類爲數組。由於Array 在JavaScript 中被當作對象,因此它有許多屬性和方法可以在編程時使用。
簡單介紹數組的概念
創建數組
最簡單的方式——聲明一個數組變量:
var arr = []
上面會創建一個長度爲0的空數組。
也可以在聲明數組變量時,直接在[] 操作符內放入一組元素:
var arr = [1,2,3,4,5]
使用構造函數 —— new Array:
var arr = new Array(1,2,3,4,5)
構造參數方式只傳入一個值,意味着指定數組的長度:
var arr = new Array(10)
與其他很多語言不同的是,數組的元素不必是同一種類型:
var arr = [1,null,true,{},'aa']
判斷一個對象是否是數組 —— isArray:
Array.isArray(arr)
由字符串生成數組 —— split:
'sadf'.split('') // ["a", "s", "d", "f"]
複製引用:
var arr1 = [1,2,3];
var arr2 = arr;
當把一個數組賦給另外一個數組時,只是爲被賦值的數組增加了一個新的引用。當你通過原引用修改了數組的值,另外一個引用也會感知到這個變化。
淺複製:
for (var i = 0; i < arr1.length; ++i) {
arr2[i] = arr1[i];
}
將原數組中的每一個元素都複製一份到新數組中。
深複製:
function deepClone(obj){
//定義對象來判斷當前的參數是數組還是對象
let objClone = Array.isArray(obj)?[]:{};
if(obj&&typeof obj == "object"){
for(let key in obj){
if(obj.hasOwnProperty(key)){
//如果obj的子元素爲對象,那麼遞歸(層級遍歷)
if(obj[key]&&typeof obj[key] == "object"){
objClone[key] = deepClone(obj[key]);
}else{
//如果不是,直接賦值
objClone[key] = obj[key];
}
}
}
}
return objClone;
}
關於深、淺複製可以參考這篇文章
常用數組操作
查詢是否包含 —— indexOf:
arr.indexOf('aa')
如果目標數組包含該參數,就返回該元素在數組中的索引;如果不包含,就返回-1。如果數組中包含多個相同的元素,indexOf() 函數總是返回第一個與參數相同的元素的索引。
數組轉字符串——join:
// join()
arr.join(','); // '1,2,3'
// reduce
arr.reduce(function(a,b){
return a + ',' + b
}) // '1,2,3'
// toString()
arr.toString() // '1,2,3'
合併數組——concat:
var arr2 = [].concat(arr) // 複製數組(淺複製)
作爲參數的數組,其中的所有元素都被連接到調用concat() 方法的數組後面。
剪切數組——splice:
var arr2 = arr.splice() // 同時會修改arr
從現有數組裏截取一個新數組。該方法的第一個參數是截取的起始索引,第二個參數是截取的長度。這個操作會影響到原數組。splice() 還有其他用法,下面介紹。
添加元素到尾部——push:
// push()
arr.push('aa')
// length
arr[arr.length] = 'aa'
添加元素到頭部——unshift:
arr.unshift('aa')
// 手寫實現 —— 低效
for(var i=arr.length;i>=0;i--){
arr[i] = arr[i-1]
}
arr[0] = 'aa'
刪除末尾元素——pop:
// pop()
arr.pop()
// length
arr.length = arr.length -1
刪除開頭元素——shift:
// shift()
arr.shift('aa')
// 手寫實現 —— 低效
for(var i=0;i<arr.length;i++){
arr[i] = arr[i+1]
} // [1,2, 3, 4, undefined]
arr.length = arr.length -1 // [1,2,3,4]
中間位置添加和刪除元素——splice:
使用splice() 方法爲數組添加元素,需提供如下三個參數:
- 起始索引(也就是你希望開始添加元素的地方);
- 需要刪除的元素個數(添加元素時該參數設爲 0);
- 想要添加進數組的元素。
翻轉排序——reverse:
// reverse()
arr.reverse()
// reduceRight + split
arr.reduceRight(function(a,b){
return a + ',' + b
}).split(',')
大小排序——sort:
// sort
arr.sort(function(a,b){
return a-b
})
循環遍歷——forEach:
arr.forEach(function(a){
console.log(a*2)
}) // 沒有返回值
數組元素判斷同真則返回真——every:
arr.every(function(item){
return typeof item == 'number'
})
數組元素判斷有一個爲真就返回真——some:
arr.some(function(item){
return typeof item == 'number'
})
累加操作——reduce/reduceRight:
// refuce 正向累加
arr.reduce(function(a,b){
return a+b
})
// reduceRight 反向累加
arr.reduceRight(function(a,b){
return a+b
})
遍歷生成新數組——map:
arr.map(function(item){return item*2})
返回過濾成功的數組——filter:
arr.map(function(item){return item/2 = 2})