建立數組
(1)new Array() 【ES5】
建立數組可以通過
Array
構造函數的方式構造數組 (new 操作符可以省略)
let colors = new Array('red', 'green', 'yellow');
console.log(colors); // ['red', 'green', 'yellow']
特殊:當傳入一個數值的時候,會建立一個指定數組的數組,用逗号建立的數組空位,值為
undefined
(關于數組空位,發現一些好玩的,請看這篇博文)
let arr = Array(10); // 這裡省略了new操作符
console.log(arr); // [empty × 10]
console.log(arr.length); // 10
(2)Array.of() 【ES6】
建立一個具有可變數量參數的新數組執行個體,而不考慮參數的數量或類型
Array.of()
代替了之前用
Array.of()
轉數組的笨拙寫法
Array.prototype.slice.call(arguments)
和
Array.of()
構造函數的差別在于處理單個數組的情況
Array
Array(10); // [empty × 10]
Array.of(10); // [10]
(3)Array.from() 【ES6】
Array.from()
建立一個具有可變數量參數的新數組執行個體,而不考慮參數的數量或類型
文法(注意:容易被忽略)
參數
-
:類數組或者可疊代對象(如Map,Set等)或者有一個arrayLike
屬性和可索引元素的結構length
-
(可選):用于增強數組元素的回調函數mapFn
-
(可選):執行回調時的thisArg
對象this
舉例
// 第二個參數的妙用
let arrLike = {
'0': 1,
'1': 2,
'2': 3,
'3': 4,
length: 4,
};
let arr = Array.from(arrLike, item => item * 3);
console.log(arr); // [3,6,9,12]
Array.from()
對現有數組是淺拷貝
let arr1 = [5,6,7,8];
let arr2 = Array.from(arr1);
console.log(arr1 === arr2); // false
數組索引
(1)中括号索引法
let colors = ['red', 'green', 'yellow'];
console.log(colors[1]); // green
(2)Array.length()
Array.length()
傳回或設定一個數組中的元素個數
let colors = ['red', 'green', 'yellow'];
console.log(colors.length); // 3
注意:數組的
length
并不隻是可讀的,而是可以通過修改
length
屬性,從數組的末尾删除或者添加元素
// 删除
let colors = ['red', 'green', 'yellow'];
colors.length = 2;
console.log(colors); // ['red', 'green']
// 添加
let colors = ['red', 'green', 'yellow'];
colors.length = 4;
console.log(colors[3]); // undefined
// 使用length屬性可以友善為數組末尾添加元素
let colors = ['red', 'green', 'yellow'];
colors[colors.length] = 'pink';
console.log(colors); // ['red', 'green', 'yellow', 'pink']
檢測數組
(1)Array.isArray()
Array.isArray([1,2,3]); // true
Array.isArray({name: 'Katrina'}); // false
思考:檢測一個對象是否是數組的方法有?
疊代器方法
(1)Array.prototype.values() 【ES6】
方法傳回一個新的
values()
對象,該對象包含數組每個索引的值
Array Iterator
(2)Array.prototype.keys() 【ES6】
方法傳回一個包含數組中每個索引鍵的
keys()
對象
Array Iterator
(3)Array.prototype.entries() 【ES6】
entries()
方法傳回一個新的Array Iterator對象,該對象包含數組中每個索引的鍵/值對
const a = ['foo', 'bar', 'baz', 'qux'];
const aValues = Array.from(a.values());
const aKeys = Array.from(a.keys());
const aEntries = Array.from(a.entries());
console.log(aValues); // ['foo', 'bar', 'baz', 'qux']
console.log(aKeys); // [0, 1, 2, 3]
console.log(aEntries); // [[0, 'foo'], [1, 'bar'], [2, 'baz'], [3, 'qux']]
// 利用解構指派可以很容易拆分鍵值對
for (let [key, value] of aEntries) {
console.log(key, value);
};
/*
0 'foo'
1 'bar'
2 'baz'
3 'qux'
*/
手寫實作
// entries()
Array.prototype.myEntries = function(arr) {
let res = [];
for (let i = 0; i < this.length; i++) {
res.push([i, this[i]])
};
return res;
};
// test
const a = ['foo', 'bar', 'baz', 'qux'];
console.log(a.myEntries());
/*
[[0, 'foo'], [1, 'bar'], [2, 'baz'], [3, 'qux']]
*/
複制和填充
(1)批量複制:copyWithin() 【ES6】
copyWithin()
方法淺複制數組的一部分到同一數組中的另一個位置,并傳回它,不會改變原數組的長度
文法
參數
-
:從這個位置開始填充target
-
(可選):填充的内容從這個位置開始截取start
-
(可選):填充的内容到這個位置截取完畢(不包含end)end
注意
- 負索引會被計算成負索引+length
-
靜默忽略超出數組邊界、零長度及方向相反的索引範圍copyWithin()
舉例
let arr = [0,1,2,3,4,5];
arr.copyWithin(0, 2, 4); // [2,3,2,3,4,5]
/*
需要注意:
1. copyWithin()靜默忽略超出數組邊界、零長度及方向相反的索引範圍
2. 不會改變原數組的長度
*/
Array.prototype.myCopyWithin = function(target, start, end) {
target < 0 ? target +length : target;
start < 0 ? start +length : start;
end < 0 ? end +length : end;
const arr = this;
for (let i = start; i < end; i++) {
arr[target] = arr[i]
};
return arr;
};
// test
let arr = [0,1,2,3,4,5];
arr.copyWithin(0, 2, 4); // [2,3,2,3,4,5]
(2)填充數組:fill() 【ES6】
fill()
方法用一個固定值填充一個數組中從起始索引到終止索引内的全部元素,不包括終止索引,會改變原數組
文法
參數
-
:用于填充數組的元素value
-
:起始索引,預設為0start
-
:終止索引,預設為end
this.length
注意
- 負索引會被計算成負索引+length
-
靜默忽略超出數組邊界、零長度及方向相反的索引範圍fill()
舉例
let arr = [1,2,3,4,5,6,7];
// 索引過低忽略
arr.fill(0, -3, 4);
console.log(arr); // [1,2,3,4,5,6,7]
// 索引過高忽略
arr.fill(0, 20, 24);
console.log(arr); // [1,2,3,4,5,6,7]
// 索引反向忽略
arr.fill(0, 6, 3);
console.log(arr); // [1,2,3,4,5,6,7]
// 索引部分可用,填充可用部分
arr.fill(0, 3, 20);
console.log(arr); // [1,2,3,0,0,0,0]
手寫實作
/*
需要注意:
1. fill()靜默忽略超出數組邊界、零長度及方向相反的索引範圍
2. 會改變原數組
*/
Array.prototype.myFill = function(value, start, end) {
start < 0 ? start + length : start;
end < 0 ? end + length : end;
end > this.length ? this.length : end;
for (let i = start; i < end; i++) {
this[i] = value;
};
return this;
};
// test
let arr = [1,2,3,4,5,6,7];
arr.fill(0, 3, 20);
console.log(arr); // [1,2,3,0,0,0,0]
轉換方法
(1)toString() && toLocaleString() && valueOf()
傳回數組本身
valueOf()
傳回由數組中每個值的等效字元串拼接而成的一個逗号分隔的字元串
toString()
傳回一個字元串表示數組中的元素。數組中的元素将使用各自的
toLocaleString()
方法轉成字元串,這些字元串将使用一個特定語言環境的字元串(例如一個逗号 “,”)隔開
toLocaleString
舉例
let colors = ['red', 'green', 'yellow'];
colors.toString(); // 'red,green,yellow'
colors.valueOf(); // ['red', 'green', 'yellow']
alert(colors.toString()) // 'red,green,yellow'
alert(colors.valueOf()) // 'red,green,yellow'
alert(colors) // 'red,green,yellow'
/*
這裡被顯式調用toString()方法和valueOf()方法,分别傳回數組的字元串表示
最後alert(colors),因為alert期待字元串,是以調用了toString()方法
*/
let person1 = {
toLocaleString() {
return "Nikolaos";
},
toString() {
return "Nicholas";
}
};
let person2 = {
toLocaleString() {
return "Grigorios";
},
toString() {
return "Greg";
}
};
let people = [person1, person2];
alert(people); // Nicholas,Greg 調用toString()
alert(people.toString()); // Nicholas,Greg 調用toString()
alert(people.toLocaleString()); // Nikolaos,Grigorios 調用toLocaleString()
(2)join()
join()
傳回以指定分隔符分隔數組元素的字元串
let colors = ['red', 'green', 'yellow'];
console.log(colors.join('-')); // 'red-green-yellow'
注意:如果數組中某一項是
null
或者
undefined
,則傳回值會以空字元串表示
手寫實作
/*
需要注意:
1. separator預設為逗号分隔
2. 如果數組中某一項是``null``或者``undefined``,則傳回值會以空字元串表示
*/
Array.prototype.myJoin = function(separator = ',') {
let res = '';
for (let i = 0; i < this.length; i++) {
this[i] = this[i] === undefined || this[i] === null ? '' : this[i];
if (i < this.length - 1) {
res += (this[i] + separator);
} else if (i === this.length - 1) {
res += this[i];
};
};
return res;
};
// test
const a = [1,,3,4,undefined,6];
console.log(a.myJoin()); // 1,,3,4,,6
console.log(a.myJoin('-')); // 1--3-4--6
棧和隊列方法
(1)push() 【ES5】
向數組末尾添加元素,傳回修改後數組的長度
手寫實作
/*
需要注意:傳回的是修改後數組的長度
*/
Array.prototype.myPush = function() {
return [...this, ...arguments].length;
};
// test
let a = [1,2,4,5,6];
console.log(a.myPush(8,9)); //7
(2)pop() 【ES5】
删除數組的最後一項,同時減少數組的 length
值,傳回被删除的元素
手寫實作
/*
需要注意:
1. 要減少數組的length值
2. 傳回被删除的元素
3. 數組長度為0時傳回undefined
*/
Array.prototype.myPop = function() {
if (this.length === 0) return undefined;
const res = this[this.length - 1];
this.length = this.length - 1;
return res;
};
let a = [1,2,4,5,6];
console.log(a.myPop()); // 6
console.log(a.length); // 4
(3)shift() 【ES5】
删除數組的第一項,同時減少數組的 length
值,傳回被删除的元素
手寫實作
/*
需要注意:
1. 要減少數組的length值
2. 傳回被删除的元素
3. 數組長度為0時傳回undefined
*/
Array.prototype.myShift = function() {
if (this.length === 0) return 0;
const res = this[0];
for (let i = 1; i < this.length; i++) {
this[i-1] = this[i];
};
this.length = this.length - 1;
return res;
};
let a = [1,2,4,5,6];
console.log(a.myShift()); // 1
console.log(a); // [2,4,5,6]
(4)unshift() 【ES5】
在數組開頭添加元素,傳回修改後數組的長度
手寫實作
/*
需要注意:傳回的是修改後數組的長度
*/
Array.prototype.myUnshift = function() {
return [...arguments, ...this].length;
};
// test
let a = [1,2,4,5,6];
console.log(a.myUnshift(8,9)); //7
排序方法
補課啦:常見的排序算法及JS實作
(1)數組排序:sort() 【ES5】
sort()
方法用原地算法(即不建立額外的空間)對數組的元素進行排序,并傳回數組。預設排序順序是在将元素轉換為字元串,然後比較它們的 UTF-16 代碼單元值序列時建構的
文法
參數
-
(可選):用來指定按某種順序進行排列的函數。如果省略,元素按照轉換為的字元串的各個字元的 Unicode 位點進行排序compareFunction
function compareFunction(value1, value2) {
if (value1 < value2) {
return -1; // 負值,value1排在value2前面
} else if (value1 > value2) {
return 1; // 正值,value1排在value2後面
} else {
return 0;
}
};
(2)翻轉數組:reverse() 【ES5】
reverse()
方法将數組中元素的位置颠倒,并傳回該數組,該方法會改變原數組
手寫實作
/*
改變原數組
*/
Array.prototype.myReverse = function() {
if (this.length <= 1) return this;
let left = 0, right = this.length -1;
while (left <= right) {
[this[left], this[right]] = [this[right], this[left]];
left++;
right--;
};
return this;
};
// test
const arr = ['h', 'e', 'l', 'l', 'o'];
console.log(arr.myReverse()); // ['o', 'l', 'l', 'e', 'h']
操作方法
(1)合并數組:concat() 【ES5】
concat()
方法用于合并兩個或多個數組,此方法會首先建立一個目前數組的副本,然後再把參數添加到副本末尾,是以不會更改現有數組,而是傳回一個新數組
文法
參數
-
:可以是數組或者值valueN
注意
可以使用
Symbol.isConcatSpreadable
來控制傳入的類數組對象是否強制打平,
true
為強制打平
舉例
let a1 = [1,2,3];
let a2 = {
[Symbol.isConcatSpreadable]:true,
length: 2,
0: 4,
1: 5,
};
let a3 = {
[Symbol.isConcatSpreadable]:false,
length: 2,
0: 4,
1: 5,
};
// 強制打平
let a1_2 = a1.concat(a2);
console.log(a1_2); // [1,2,3,4,5]
// 不強制打平
let a1_3 = a1.concat(a3);
console.log(a1_3); // [1,2,3, {[Symbol.isConcatSpreadable]:false,length: 2,0: 4,1: 5}]
手寫實作
/*
注意:此方法會建立一個目前數組的副本,并不會修改原數組
*/
Array.prototype.myConcat = function() {
let args = [...arguments];
let res = this;
for (let i = 0; i < args.length; i++) {
if (typeof args[i] === 'object') {
res = [...res, ...args[i]];
} else {
res[res.length] = args[i];
}
};
return res;
};
// test
const a1 = [1,2,3];
const a2 = [5,6];
console.log(a1.myConcat(4, a2)); // [1,2,3,4,5,6]
(2)截取數組:slice() 【ES5】
方法傳回一個新的數組對象,這一對象是一個由
slice()
和
begin
決定的原數組的淺拷貝(包括
end
,不包括
begin
),原始數組不會被改變
end
文法
參數
-
(可選):起始索引,預設為0start
-
(可選):終止索引(不含),預設為end
this.length
注意
- 遇到負索引需要進行索引+length處理
-
超過原數組的索引範圍傳回空數組start
-
大于原數組的長度,則截取到原數組的末尾end
手寫實作
Array.prototype.mySlice = function(start, end) {
start > 0 ? start : start +length;
end > 0 ? end : end +length;
end > this.length ? this.length : end;
let res = [];
for (let i = start; i < end; i++) {
res.push(this[i]);
};
return res;
};
// test
const arr = ['h', 'e', 'l', 'l', 'o'];
console.log(arr.mySlice(2,4)); // ['l', 'l'];
console.log(arr); // ['h', 'e', 'l', 'l', 'o']
(3)插入元素:splice() 【ES5】
splice()
方法通過删除或替換現有元素或者原地添加新的元素來修改數組,并以數組形式傳回被修改的内容,此方法會改變原數組
文法
參數
-
:起始位置start
-
(可選):要移除數組元素的個數,0或者負數表示不移除deletecount
-
(可選):要添加的元素item1 item2
傳回值
由被删除的元素組成的一個數組
如果隻删除了一個元素,則傳回隻包含一個元素的數組
如果沒有删除元素,則傳回空數組
方法
- 删除:傳2個參數
- 插入:傳3個參數
- 替換:傳3個參數
手寫實作
/*
改變原數組
*/
Array.prototype.mySlice = function() {
let args = [...arguments];
let start = Array.prototype.shift.call(args);
let deletecunt = Array.prototype.shift.call(args);
let left = this.slice(0, start); // 左邊數組
let right = this.slice(start+deletecount, this.length); // 右邊數組
let res = [...left, ...atgs, ... right];
// 改變原數組
for (let i = 0; i < res.length; i++) {
this[i] = res[i];
};
return this.slice(start, start + deletcount); // 傳回删除的資料
};
// test
var myFish = ['angel', 'clown', 'drum', 'mandarin', 'sturgeon'];
var removed = myFish.splice(3, 1);
console.log(removed); // ['mandarin']
var myFish = ['angel', 'clown', 'drum', 'sturgeon'];
var removed = myFish.splice(2, 1, "trumpet");
console.log(removed); // ['drum]
搜尋和位置方法
(1)按嚴格相等搜尋:indexOf() 【ES5】 && lastIndexOf() 【ES5】 && inclues() 【ES6】
方法傳回在數組中可以找到一個給定元素的第一個索引,如果不存在,則傳回-1
indexOf()
方法傳回指定元素(也即有效的 JavaScript 值或變量)在數組中的最後一個的索引,如果不存在則傳回 -1,從數組的後面向前查找,從
lastIndexOf()
處開始
fromIndex
方法用來判斷一個數組是否包含一個指定的值,根據情況,如果包含則傳回
includes()
,否則傳回
true
false
注意
- 三者都可以指定
,即從哪一項開始尋找fromIndex
- 三者都采用嚴格相等搜尋,即
比較===
- 找到目标之後不會繼續往下找
手寫實作
/*
嚴格相等
*/
// indexOf()
Array.prototype.myIndexOf = function(num, fromIndex = 0) {
for (let i = fromIndex; i < this.length; i++) {
if (this[i] === num) {
return i;
};
};
return -1;
};
// test
const arr = [1,2,3,4,5,6];
console.log(arr.myIndexOf(2)) // 1
console.log(arr.myIndexOf(2, 4)) // -1
// includes()
Array.prototype.myIncludes = function(num, fromIndex = 0) {
for (let i = fromIndex; i < this.length; i++) {
if (this[i] === num) {
return true;
};
};
return false;
};
// test
const arr = [1,2,3,4,5,6];
console.log(arr.myIncludes(2)) // true
console.log(arr.myIncludes(2, 4)) // false
(2)按斷言函數搜尋:find() && findIndex() 【ES6】 ALL
方法傳回數組中滿足提供的測試函數的第一個元素的值,否則傳回undefined
find()
方法傳回數組中滿足提供的測試函數的第一個元素的索引,若沒有找到對應元素則傳回-1
findIndex()
注意
- 兩者都采用斷言函數搜尋,斷言函數接收3個參數:元素 索引 數組本身
- 是以兩個的參數都是一個回調函數
- 找到符合條件的元素後就不會再繼續
手寫實作
Array.prototype.myFind = function(callback) {
if (typeof callback !== 'function') {
throw new Error('callback must be a function');
}
const arr = this;
for (let i = 0; i < arr.length; i++) {
if (callback(arr[i], i, arr)) {
return arr[i];
};
};
return undefined;
};
// test
const arr = [1,2,3,4,5,6];
const res = arr.myFind((item, index, arr) => item > 4);
console.log(res, arr); // 5 [1,2,3,4,5,6]
// findIndex()
Array.prototype.myFindIndex = function(callback) {
if (typeof callback !== 'function') {
throw new Error('callback must be a function');
}
const arr = this;
for (let i = 0; i < arr.length; i++) {
if (callback(arr[i], i, arr)) {
return i;
};
};
return -1;
};
疊代方法
(1)every() 【ES5】
every()
方法測試一個數組内的所有元素是否都能通過某個指定函數的測試,它傳回一個布爾值
舉例
let arr = [3,4,5,6,7];
arr.every(item => item > 2); // true
arr.every(item => item > 4); // false
/*
特點:必須每一項元素都滿足條件
*/
手寫實作
Array.prototype.myEvery = function(callback) {
if (typeof callback !== 'function') {
throw new Error('callback must be a function');
};
for (let i = 0; i < this.length; i++) {
if (!callback(this[i], i, this)) {
return false;
}
};
return true;
};
// test
let arr = [3,4,5,6,7];
arr.myEvery(item => item > 2); // true
arr.myEvery(item => item > 4); // false
(2)some() 【ES5】
some()
方法測試數組中是不是至少有 1 個元素通過了被提供的函數測試,它傳回一個布爾值
舉例
let arr = [3,4,5,6,7];
arr.some(item => item > 2); // true
arr.some(item => item > 4); // true
/*
特點:隻要有一項元素滿足即可
*/
手寫實作
Array.prototype.mySome = function(callback) {
if (typeof callback !== 'function') {
throw new Error('callback must be a function');
};
for (let i = 0; i < this.length; i++) {
if (callback(this[i], i, this)) {
return true;
}
};
return false;
};
// test
let arr = [3,4,5,6,7];
arr.mySome(item => item > 4); // true
arr.mySome(item => item > 8); // false
(3)filter() 【ES5】
filter()
方法建立一個新數組,其包含通過所提供函數實作的測試的所有元素
舉例
let arr = [3,4,5,6,7];
arr.filter(item => item > 5); // [ 6, 7]
手寫實作
// 疊代法
Array.prototype.myFilter = function(callback) {
if (typeof callback !== 'function') {
throw new Error('callback must be a function');
};
let res = [];
for (let i = 0; i < this.length; i++) {
if (callback(this[i], i, this)) {
res.push(this[i]);
};
};
return res;
};
let arr = [3,4,5,6,7];
arr.myFilter(item => item > 5); // [ 6, 7]
// 借助reduce
Array.prototype.myFilter = function(callback) {
if (typeof callback === 'function') {
return this.reduce((prev, item, index, arr) => {
if (callback(item, index, arr)) {
prev.push(item);
};
return prev;
}, [])
} else {
throw new Error('callback is not a fucntion');
}
};
// test
let arr = [3,4,5,6,7];
arr.myFilter(item => item > 5); // [ 6, 7]
(4)forEach() 【ES5】
forEach()
方法對數組的每個元素執行一次給定的函數,沒有傳回值,改變原數組
舉例
let arr = [3,4,5,6,7];
arr.forEach(item => item*2);
console.log(arr); // [6,8,10,12,14]
手寫實作
/*
注意: 改變原數組
*/
Array.prototype.myForEach = function(callback, thisArg) {
const arr = this;
for (let i = 0; i < arr.length; i++) {
callback.call(thisArg, arr[i]);
};
};
const obj = {
num: 10
};
const arr = [1, 2, 3, 4, 5, 6];
arr.myForEach(function (value, index, arr) {
console.log(value + this.num); // 依次列印:11 12 13 14 15 16
}, obj);
console.log(arr); // [1, 2, 3, 4, 5, 6]
(5)map() 【ES5】
map()
方法建立一個新數組,這個新數組由原數組中的每個元素都調用一次提供的函數後的傳回值組成
舉例
let arr = [3,4,5,6,7];
let newArr = arr.map(item => item*2);
console.log(newArr); // [6,8,10,12,14]
注意
-
僅對每一項已配置設定值得索引調用map
let a = [1,2,,4];
let newA = a.map(item => item*2); // [2,4,,8]
手寫實作
// 疊代法
Array.prototype.myMap = function(callback) {
if (typeof callback !== 'function') {
throw new Error('callback must be a function');
};
let arr = this;
let res = [];
for (let i = 0; i < arr.length; i++) {
let value = callback(arr[i], i, arr);
res.push(value);
};
return res;
};
// test
let a = [1,2,4];
let newA = a.myMap(item => item*2); // [2,4,8]
// reduce改進
Array.prototype.myMap = function(callback) {
if (typeof callback !== 'function') {
throw new Error('callback must be a function');
};
let arr = this;
return arr.reduce((prev, curr, index, arr) => {
prev.push(callback(curr, index, arr));
return prev;
}, [])
};
// test
let a = [1,2,4];
let newA = a.myMap(item => item*2); // [2,4,8]
歸并方法
(1)reduce() 【ES5】
reduce()
接收兩個參數:歸并函數和歸并起點的初始值
其中歸并函數接收四個參數:上一個歸并值、目前項、目前項的索引、數組本身。歸并函數傳回的任何值都會成為下一次調用同一個函數的第一個參數,即歸并值,如果沒有歸并起點的初始值,則把第一個元素作為初始值,疊代從第二個元素開始
reduce的應用詳見:強大的reduce
手寫實作
Array.prototype.myReduce = function(callbackFn, initalValue) {
// Step1:檢驗
if (this === null) {
throw new Error('Array.prototype.reduce called on null or undefined');
};
if (typeof callbackFn !== 'function') {
throw new Error('Callback must be a function');
};
let obj = Object(this);
const lenValue = obj.length;
const len = lenValue >>> 0;
if (!len && !initalValue) {
throw new TypeError('The array contains no elements and initalValue is not provided')
};
// Step2: 确定accumulator初始值
let k = 0;
let accumulator;
if (initalValue) {
accumulator = initalValue;
} else {
let kPressent = false;
while (!kPressent && k < len) {
const pK = String(k);
kPressent = obj.hasOwnProperty(pK); // 是否有效
if (kPressent) {
accumulator = obj[pK];
};
k++;
};
if (!kPressent) {
throw new TypeError('The array contains error elements');
};
};
// Step3:确定傳回值
while (k < len) {
if (k in obj) {
accumulator = callbackFn(accumulator, obj[k], k, obj);
};
k++;
};
return accumulator;
};
// test
const arr = [1,2,3,4,5];
const sum = arr.myReduce((prev, curr) => prev+curr, 0);
console.log(sum); // 15
(2)reduceRight() 【ES5】
與
reduceRight()
唯一不同的就是周遊方向是從最後一項到第一項,其餘全部相同
reduce()
其他
(1)數組扁平化:flat() 【ES6】
flat()
方法會按照一個可指定的深度遞歸周遊數組,并将所有元素與周遊到的子數組中的元素合并為一個新數組傳回
文法
參數
-
(可選):指定要提取嵌套數組的深度,預設為1depth
function myFlat(arr, depth = 1) {
if (depth < 1) return arr;
return arr.reduce((prev, curr, index, arr) => {
return Array.isArray(curr) ? prev.concat(myFlat(curr, depth - 1)) : prev.concat(curr);
}, [])
};
// test
const arr = [1, 2, [[3,4]]]
myFlat(arr, 1) // [1, 2, [3,4]]
myFlat(arr, 2) // [1, 2, 3, 4]
總結
(1)改變原數組方法
push
unshift
pop
shift
reverse
splice
sort
(2)ES6新增方法
Array.from
Array.of
copyWithin()
fill()
find()
findIndex()
entries()
keys()
values()
includes()
flat()
知識補充
數組空位
map和forEach的差別
強大的reduce
深淺拷貝
參考
MDN Array