valueOf()、toString()
valueOf()和toString()是JavaScript對象的通用方法。
valueOf()表示對該對象求值。不同的對象的valueOf方法不盡一致,數組的valueOf方法返回數組的本身。
let array = [1, 2, 3]
array.valueOf() // [1, 2, 3]
let array1 = [1, 3, 3, 'a', [1, 2, 3]]
array1.valueOf() // [1, 3, 3, 'a', [1, 2, 3]]
toString()返回的是數組的字符串形式。
let array = [1, 2, 3]
array.toString() // 1,2,3
let array1 = [1, 3, 3, 'a', [1, 2, 3], {obj: 1}]
array1.toString() // 1,3,3,a,1,2,3,[object Object]
Array.isArray()
該方法返回一個布爾值,表示參數是否爲數組。
因爲數組本質上是一種特殊的對象,所以typeof運算符會返回數組的類型爲object
。使用Array.isArray方法可以識別數組,可以彌補typeof運算符的不足。
let array = [1, 2, 3]
typeof array // object
Array.isArray(array) // true
添加:push()、unshift()
push()方法用於在數組的末端添加一個或多個元素,並返回添加新元素後的數組長度,該方法會改變原數組。
let array = [1, 3]
array.push(2)
array.push('a', 'b')
array.push(true, {})
console.log(array) // [1, 3, 2, "a", "b", true, {}]
unshift()方法用於在數組的第一個位置添加元素,並返回添加新元素後的數組長度,該方法會改變原數組。
unshift()可以接受多個參數,這些參數都會添加到目標數組頭部。
let array = [1, 2, 3]
array.unshift('a')
array.unshift('b', 'c')
console.log(array) // ["b", "c", "a", 1, 2, 3]
刪除:pop()、shift()
pop()方法用於刪除數組的最後一個元素,並返回該元素,該方法會改變原數組。
如果對空數組使用pop方法,不會報錯,而是返回undefined
let array = [1, 3, 3, 4]
console.log(array.pop()) // 4
console.log(array) // [1, 3, 3]
[].pop() // undefined
shift()方法用於刪除數組的第一個元素,並返回該元素,該方法會改變原數組。
let array = [1, 3, 3, 4]
array.shift()
console.log(array) // [3, 3, 4]
-
push和pop兩個方法結合使用,就構成了“後進後出”的棧結構(stack)。
-
push和shift結合使用,構成了“先進先出”的隊列結構(queue)。
join()
join方法以指定參數作爲分隔符,將所有數組成員連接成一個字符串返回。如果沒有提供參數,默認逗號分隔。
如果數組成員是undefined或null或空位,會被轉成空字符串。
let array = [1, 2, 3, 4, ,, null, undefined]
console.log(array.join()) // 1,2,3,4,,,,
console.log(array.join(' ')) // 1 2 3 4
console.log(array.join('-')) // 1-2-3-4----
通過call方法,join也可以用於字符串或者類似數組的對象。
Array.prototype.join.call('hello', '-') // h-e-l-l-o
let obj = {0: 'a', 1: 'b', 2: 'c', length: 3}
Array.prototype.join.call(obj, '-') // a-b-c
合併:concat()
concat方法用於多個數組的合併,它將新數組的成員,添加到原數組成員的後面,然後返回一個新數組,原數組不變。
['hello'].concat(['world'])
// ["hello", "world"]
['hello'].concat(['world'], ['!'])
// ["hello", "world", "!"]
[].concat({a: 1}, {b: 2})
// [{ a: 1 }, { b: 2 }]
[2].concat({a: 1})
// [2, {a: 1}]
concat還可以接受其他類型的值作爲參數,添加到目標數組尾部。
[1, 2, 3].concat(4, 5, 6)
// [1, 2, 3, 4, 5, 6]
如果數組成員包括對象,concat方法返回當前數組的一個淺拷貝。
var obj = { a: 1 };
var oldArray = [obj];
var newArray = oldArray.concat();
obj.a = 2;
newArray[0].a // 2
reverse()
reverse()方法用於顛倒排列數組元素,返回改變後的數組。
let array = [1, 2, 3, 4]
array.reverse()
array // [4, 3, 2, 1]
splice()
splice()方法用於刪除原數組的一部分成員,並可以在刪除的位置添加新的數組成員,返回的是被刪除的元素。
arr.splice(start, count, addElement1, addElement2, ...);
splice的第一個參數是刪除的起始位置,第二個參數是被刪除的元素個數。如果後面有更多的參數,表示這些是要被插入數組的元素。
如果起始位置是負數,表示從倒數位置開始刪除。
let arr = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
arr.splice(1, 2) // ["b", "c"]
arr // ['a', 'd', 'e', 'f', 'g']
arr.splice(0, 1, 1, 2, 3, 4)
arr // [1, 2, 3, 4, "d", "e", "f", "g"]
arr.splice(-6, 4)
arr // [1, 2, "f", "g"]
sort()
對數組成員進行排序,默認按照字典順序排序。排序後,原數組將被改變。
如果要自定義排序方式,可以傳入一個函數作爲參數。
let array = [1, 4, 3, 'a', 6, 2, 1, 10, 98, 7]
array.sort()
array // [1, 1, 10, 2, 3, 4, 6, 7, 98, "a"]
// 降序
let array1 = [1, 4, 3, 6, 2, 1, 10, 98, 7]
array1.sort((a, b) => b - a)
array1 // [98, 10, 7, 6, 4, 3, 2, 1, 1]
map()
將數組的所有成員依次傳入參數函數,然後把每一次的執行結果組成一個新數組返回。
let array = [1, 3, 5]
let new_array = array.map(function(n) {
return n + 2
})
console.log(new_array) // [3, 5, 7]
console.log(array) // [1, 3, 5]
調用參數函數時,map向函數傳入三個參數:當前成員、當前位置、數組本身。
let array = [1, 3, 5]
let new_array = array.map(function(n, index, arr) {
console.log(n, index, arr)
return n * index
})
console.log(new_array)
此外,map方法還可以接受第二個參數,用來綁定回調函數內部的this變量
var arr = ['a', 'b', 'c'];
[1, 2].map(function (e) {
return this[e];
}, arr)
// ['b', 'c']
filter()
用於過濾數組成員,滿足條件的成員組成一個新數組返回。
[1, 2, 3, 4, 5].filter(function (elem) {
return (elem > 3);
})
// [4, 5]
filter方法和map一樣,可以接受第二個參數,用來綁定參數函數內部的this,參數函數可接收三個參數。
var obj = { MAX: 3 };
var myFilter = function (item) {
if (item > this.MAX) return true;
};
var arr = [2, 8, 3, 4, 1, 3, 2, 9];
arr.filter(myFilter, obj) // [8, 4, 9]
some()、every()
這兩個方法接受一個函數作爲參數,所有數組成員依次執行該函數。該函數接受三個參數:當前成員、當前位置、整個數組,然後返回一個布爾值,表示判斷數組成員是否符合某個條件。
some()方法只要一個成員的返回值爲true,則整個some方法的返回值就是true,否則返回false。
let array = [1, 3, 5, 7]
array.some(function(el, index, arr) {
return el > 5
}) // true
every方法是所有成員的返回值都是true,整個every方法才返回true,否則返回false。
let array = [1, 3, 5, 7]
array.some(function(el, index, arr) {
return el > 1
}) // false
對於空數組,some方法返回false,every方法返回true,回調函數都不會執行。
reduce()、reduceRight()
reduce方法和reduceRight方法依次處理數組的每個成員,最終累計爲一個值。
reduce是從左到右處理,reduceRight是從右到左處理。
array.reduce(func, defaultValue)
reduce和reduceRight接收兩個參數,第一個是函數,第二個是累積變量初始值。
第一個參數函數接受下面四個參數:
- 累積變量,默認爲數組的第一個成員(必須)
- 當前變量,默認爲數組的第二個成員(必須)
- 當前位置,從0開始(可選)
- 原數組(可選)
累積變量初始值是個可選參數。
[1, 2, 3, 4, 5].reduce(function (a, b) {
return a + b;
}, 10);
// 25
indexOf()、lastIndexOf()
indexOf方法返回給定元素在數組中第一次出現的位置,如果沒有出現則返回-1。該方法可接受第二個參數,用來指定搜索開始的位置。
['a', 'b', 'd'].indexOf('b') // 1
['a', 'b', 'd'].indexOf('b', 2) // -1
lastIndexOf方法返回給定元素的最後一次出現的位置,如果沒有出現返回-1。
var a = [2, 5, 9, 2];
a.lastIndexOf(2) // 3
a.lastIndexOf(7) // -1
這兩個方法不能用來搜索NaN的位置,因爲方法內部使用嚴格相等運算符
===
進行比較,而NaN是唯一一個不等於自身的值。
下面我們來看下ES6新增的數組方法:
Array.from()
用來將下面兩類對象轉爲真正的數組。
- 類似數組的對象(array-like object)
- 可遍歷(iterable)的對象(包括ES6新增的數據結構Set和Map)
Array.from()會將數組的空位轉爲undefined
// 類似數組的對象
let arrayLike = {
0: 'a',
1: 'b',
2: 'c',
length: 3
}
// ES5 寫法
let newArr1 = [].slice.call(arrayLike) // ["a", "b", "c"]
// ES6 寫法
let newArr2 = Array.from(arrayLike) // ["a", "b", "c"]
// 可遍歷的對象
Array.from('hello') // ["h", "e", "l", "l", "o"]
let set = new Set(['a', 'b', 'c'])
Array.from(set) // ['a', 'b', 'c']
Array.of()
用於將一組值轉換爲數組。如果沒有參數則返回一個空數組。
Array.of(1, 2, 3, 4) // [1, 2, 3, 4]
數組實例的 copyWithin()
在當前數組內部,將指定位置的成員複製到其他位置(會覆蓋原有成員),然後返回當前數組。
copyWithin()會連空位一起拷貝。
Array.prototype.copyWithin(target, start = 0, end = this.length)
- target:必需,從該位置開始替換數據,如果爲負值,表示倒數。
- start:可選,從該位置開始讀取數據,默認爲0。如果爲負值,表示從尾部開始計算。
- end:可選,到該位置停止讀取數據,默認爲數組長度,如果爲負值,表示從末尾開始計算。
[1, 2, 3, 4, 5].copyWithin(0, 3) // [4, 5, 3, 4, 5]
[1, 2, 3, 4, 5].copyWithin(0, 3, 4) // [4, 2, 3, 4, 5]
數組實例的 find()和findeIndex()
find:找出第一個符合條件的數組成員。參數是一個回調函數。如果沒有符合條件的成員,返回undefined
[1, 5, 10, 15].find(function(value, index, arr) {
return value > 9;
}) // 10
findIndex的用法和find方法類似,返回第一個符合條件的數組成員的位置,如果沒有符合條件的成員,返回-1。
[1, 5, 10, 15].findIndex(function(value, index, arr) {
return value > 9;
}) // 2
數組實例的 fill()
fill方法使用給定值,填充一個數組。
如果數組中已有元素,會被全部抹去。
fill方法還可以接受第二個和第三個參數,用來指定填充的起始和結束位置。
fill()會將空位視爲正常的數組位置。
[1, 2, 3].fill(4) // [4, 4, 4]
new Array(3).fill(4) // [4, 4, 4]
[1, 2, 3, 4, 5].fill(10, 1, 3) // [1, 10, 10, 4, 5]
如果填充的類型爲對象,那麼被賦值的是同一個內存地址的對象,而不是深拷貝對象。
let arr = new Array(3).fill({name: "Mike"});
arr[0].name = "Ben";
arr
// [{name: "Ben"}, {name: "Ben"}, {name: "Ben"}]
let arr = new Array(3).fill([]);
arr[0].push(5);
arr
// [[5], [5], [5]]
數組實例的 entries()、keys()、values()
這三個是ES6新增的三個用於遍歷數組的方法。它們都返回一個遍歷器對象,可用for…of循環進行遍歷。
keys()是對鍵名的遍歷,values()是對鍵值的遍歷,entries()是對鍵值對的遍歷。
for (let index of ['a', 'b'].keys()) {
console.log(index);
}
// 0
// 1
for (let elem of ['a', 'b'].values()) {
console.log(elem);
}
// 'a'
// 'b'
for (let [index, elem] of ['a', 'b'].entries()) {
console.log(index, elem);
}
// 0 "a"
// 1 "b"
數組實例的 includes()
Array.prototype.includes方法返回一個布爾值,表示某個數組是否包含給定的值,與字符串的includes方法類似。ES2016 引入了該方法。
[1, 2, 3].includes(2) // true
[1, 2, 3].includes(4) // false
[1, 2, NaN].includes(NaN) // true
該方法的第二個參數表示搜索的起始位置,默認爲0。如果第二個參數爲負數,則表示倒數的位置,如果這時它大於數組長度(比如第二個參數爲-4,但數組長度爲3),則會重置爲從0開始。
[1, 2, 3].includes(3, 3); // false
[1, 2, 3].includes(3, -1); // true
可以用該方法判斷數組中是否有NaN
[NaN].includes(NaN)
// true
數組實例的 flat()、flatMap()
flat()
Array.prototype.flat()用於將嵌套的數組“拉平”,變成一維的數組。該方法返回一個新數組,對原數據沒有影響。
flat()默認只會“拉平”一層,如果要“拉平”多層嵌套數組,可以將flat()方法的參數寫成一個整數,表示要拉平的層數。
如果不管多少層嵌套,都要轉成一維數組,可以用Infinity
關鍵字作爲參數。
如果原數組存在空位,flat方法會跳過空位。
[1, 2, [3, [4, 5]]].flat()
// [1, 2, 3, [4, 5]]
[1, 2, [3, [4, 5]]].flat(2)
// [1, 2, 3, 4, 5]
[1, [2, [3]]].flat(Infinity)
// [1, 2, 3]
flatMap()
flatMap方法對原數組的每個成員執行一個函數,然後對返回值組成的數組執行flat方法。該方法返回一個新的數組。
flatMap方法只能“拉平”一層數組。
[2, 3, 4].flatMap((x) => [x, x * 2])
// [2, 4, 3, 6, 4, 8]
[1, 2, 3, 4].flatMap(x => [[x * 2]])
// [[2], [4], [6], [8]]
flatMap()方法的參數是一個遍歷函數,該函數可以接受三個參數,分別是當前數組成員、當前數組成員的位置(從零開始)、原數組。
arr.flatMap(function callback(currentValue[, index[, array]]) {
// ...
}[, thisArg])
flatMap方法可以有第二個參數,用來綁定遍歷函數中的this
參考資料:
- https://wangdoc.com/javascript/stdlib/array.html
- https://es6.ruanyifeng.com/#docs/array