一、數組
1. 定義
- 數組(array)是按次序排列的一組值。每個值的位置都有編號(從 0 開始),整個數組用方括號表示。
var arr = ['a', 'b', 'c'];
- 任何類型的數據,都可以放入數組。
- 如果數組的元素還是數組,就形成了多維數組。
2. 數組的本質
本質:數組屬于一種特殊的對象。typeof 運算符返回數組的類型是 object.
特殊性:數組的鍵名是按次序排列的一組整數(0,1,2…)
- 數組的鍵名其實也是字符串??梢杂脭抵底x取,是因為非字符串的鍵名會被轉為字符串。這點在賦值時也成立,先轉成字符串再進行賦值。
var arr = ['a', 'b', 'c'];
arr['0'] // 'a'
arr[0] // 'a'
- 因為數值鍵名不符合標識符規(guī)范,不能使用點結構讀取,數組成員只能用方括號
arr[0]或arr['0']讀取。
3. length 屬性
- 數組的
length屬性,返回數組的成員數量。 - 只要是數組,就一定有 length 屬性。length 是動態(tài)的值,等于鍵名中的最大整數加上 1.
var arr = ['a', 'b', 'c'];
length.arry // 3
arr[9] = 'e';
arr.length // 10
- JavaScript 使用 32 位整數保存數組的元素個數。這意味著,數組成員最多只有 4294967295 個(2^32 - 1)個,因此 length 屬性的最大值是 4294967295。
- length 屬性是可寫的。若設置一個小于當前成員個數的值,該數組的成員會自動減少到 length 設置的值。
- 清空數組的一個有效方法,就是將 length 屬性設為 0。
- 若設置 length 大于當前元素個數,則數組的成員數量會增加到這個值,新增的位置都是空位。
var arr = [ 'a', 'b', 'c' ];
arr.length // 3
arr.length = 4
arr[3] //undefined
arr.length = 2;
arr // ["a", "b"]
arr.length = 0;
arr // []
- 由于數組本質上是一種對象,所以可以為數組添加屬性,但是這不影響 length 屬性的值。
var a = [];
a['p'] = 'abc';
a.length // 0
a[2.1] = 'abc';
a.length // 0
4. in 運算符
- 檢查某個鍵名是否存在,適用于對象,也適用于數組。
- 注意,如果數組的某個位置是空位,
in運算符返回false。
var arr = [];
arr[100] = 'a';
100 in arr // true
1 in arr // false
5. 遍歷數組
-
for...in循環(huán)可以遍歷數組,但它不僅遍歷數字鍵,還遍歷非數字鍵。所以可以使用for循環(huán)或while循環(huán)遍歷數組。 - 數組的
forEach方法也可以用來遍歷數組:
var colors = ['red', 'green', 'blue'];
colors.forEach(function (color) {
console.log(color);
});
// red
// green
// blue
6. 數組的空位
- 當數組的某個位置是空元素,即兩個逗號之間沒有任何值,我們稱該數組存在空位(hole)。
- 數組的空位是可以讀取的,返回 undefined。
- 用
delete命令刪除一個數組成員,會形成空位,且不影響length屬性。
var a = [1, , 1];
a.length // 3
a[1] // undefined
delete a[2];
a.length // 3
- 空位:表示數組沒有這個元素,遍歷數組時空位會跳過
undefined:表示數組有這個元素,值是 undefined,遍歷不會跳過
7. 類似數組的對象
對象的所有鍵名都是正整數或零,并且有 length 屬性,語法上稱為“類似數組的對象”(array-like object):
var obj = {
0: 'a',
1: 'b',
2: 'c',
length: 3
};
- 這種 length 屬性不是動態(tài)值,不會隨著成員的變化而變化。
- 類似數組的對象(array-like object)并不是數組,
instanceof運算符返回false:
arrayLike instanceof Array // false
二、Array 對象
1. 構造函數
Array 是 JavaScript 的全局對象,同時是構造數組的一個構造函數。
- 基本用法,以下三種寫法都可以:
let f = new Array('a,' 'b')
let f = Array('a,' 'b')
let f = ['a', 'b'] // 常用方法
f // ["a", "b"]
對于基本類型 Number、String 和 Boolean,構造函數時不加 new 創(chuàng)建的的是對應的基本類型,加 new 創(chuàng)建的是對象;對于復雜類型 Object(包括 Array 和 Function),加與不加 new 創(chuàng)建的都是對象。
- 創(chuàng)建空數組:
var a = new Array(3)
a // [empty * 3]
a.length // 3
Array 構造函數的參數 3,表示生成一個長度為 3 的數組,每個位置都是空值:
創(chuàng)建數組
- 不一致性
var a = new Array(3, 3)
// [3, 3]
上面的例子,第一個參數不再指數組的長度,說明 Array 作為構造函數具有不一致性。內存圖解:
不一致性
2. JS 中數組的本質
- 我們對數組的理解:數組就是數據的有序集合。
JS 對數組的理解:數組就是原型鏈中有Array.prototype的對象。
- Array 既有
valueOf(),toString()等所有對象都擁有的靜態(tài)方法,還有push()、pop()、shift()、join()等 Array 獨有的方法(Array.prototype)。
- Array 與 Object 的區(qū)別
var a = [1,2,3]
var obj = {0:1, 1:2, 2:3, length:3}
二者的內存是沒有區(qū)別的,它們的區(qū)別是原型不同。內存圖解:
Array 與 Object 的區(qū)別
3. 偽數組
- 定義:一個對象,有
0,1,2,3,4,5...n,length這些key,但原型鏈中沒有Array.prototype,這樣的對象就是偽數組。 - 目前知道的偽數組有
arguments對象
document.querySelectAll('div')返回的對象
偽數組 arguments
4. 數組的 API
API:瀏覽器提供的接口。
- Array.prototype.forEach:遍歷
-
forEach()方法對數組的所有成員依次執(zhí)行參數函數。forEach()方法的參數是一個函數,該函數接受三個參數:當前值value、當前位置key、整個數組。 - 它不返回值,只用來操作數據。
arr.forEach( function(){} )

forEach()
-
for i循環(huán)和Array.prototype.forEach都可以遍歷數組,二者區(qū)別為:
for是關鍵字,不是函數;Array.prototype.forEach是一個函數。
for循環(huán)可以break和continue;Array.prototype.forEach不支持break和continue.
-
Array.prototype.sort:排序
sort()方法的內置排序一般是快排。排序后,原數組被改變。
默認按照字典順序排序,若想自定義排序,可傳入一個函數作為參數。
sort()
- 返回 (x-y)和返回(y-x)的排序結果是不同的,一個從小到大排序,一個從大到小排序。
-
Array.prototype.join:連接數組成員為字符串
join()方法以指定參數作為分隔符,將所有數組成員連接成一個字符串。
如果不提供參數,默認用逗號分隔。
join() -
Array.prototype.concat:合并多個數組
concat()方法用于多個數組的合并。將新數組的成員添加到原數組成員的后部,然后返回一個新數組,原數組不變。
concat()
- 特殊用法:用來復制一個數組。把當前數組
concat一個空數組[],返回一個新的數組。
- Array.prototype.map:映射
-
map()方法將數組的所有成員依次傳入參數函數(與forEach相同),然后把每一次的執(zhí)行結果組成一個新數組返回(與forEach不同)。 -
map()方法也接受一個函數作為參數,該函數調用時,map()方法向它傳入三個參數:當前值value、當前位置key和數組本身。
map()
- Array.prototype.filter:過濾
-
filter()方法用于過濾數組成員,滿足條件的成員組成一個新數組返回。 - 它的參數是一個函數,所有數組成員依次執(zhí)行該函數,返回結果為
true的成員組成一個新數組返回。該方法不會改變原數組。
filter() -
鏈式操作,同時使用
filter和map方法:
鏈式操作
-
Array.prototype.reduce
reduce()方法從左到右依次處理數組的每個成員(從第一個成員到最后一個成員),最終累計為一個值。
上面代碼中,reduce()reduce方法求出數組所有成員的和。第一個參數是一個函數,sum 為之前求和的結果,n 為當前數字,最后一個參數 0 是初始值。
-
map和filter用reduce表示:map 和 filter 用 reduce 表示
-
Array.prototype.reverse:顛倒
reverse()方法用于顛倒排列數組元素,返回改變后的數組。該方法會改變原數組。
reverse() Array.prototype.slice:提取
-
slice()方法用于提取目標數組的一部分,返回一個新數組,原數組不變。
arr.slice(start, end)
-
它的第一個參數為起始位置(從 0 開始),第二個參數為終止位置(不包含該位置的元素本身)。如果省略第二個參數,則一直返回到原數組的最后一個成員。slice()
- 特殊用法:最后一個例子
slice沒有參數,實際上等于返回一個原數組的拷貝。
- Array.prototype.splice:刪除
-
splice()方法用于刪除原數組的一部分成員,并可以在刪除的位置添加新的數組成員,返回值是被刪除的元素。該方法會改變原數組。
arr.splice(start, count, addElement1, addElement2, ...)
-
splice的第一個參數是刪除的起始位置(從0開始),第二個參數是被刪除的元素個數。如果后面還有更多的參數,則表示這些就是要被插入數組的新元素。
splice() -
如果只提供第一個參數,等同于將原數組在指定位置拆分成兩個數組:splice() 一個參數
- 例題:var a = [1,2,3,4,5,6,7,8,9],計算所有奇數的和。
var a = [1,2,3,4,5,6,7,8,9]
a.reduce(function(arr, n){
if(n % 2 !== 0){
arr.push(n)
}
return arr
},[]).reduce(function(sum, n){
return sum + n
},0)
// 或者
a.reduce( (sum,n)=> {
return n%2===1 ? sum + n : sum
}, 0)












