作者:米書林
參考文章:《菜鳥教程》藐翎、《 ECMAScript 6 入門》(阮一峰)
數組的創(chuàng)建
傳統(tǒng)js數組的創(chuàng)建
傳統(tǒng)js創(chuàng)建數組有兩種方式:
1.new一個Array()構造函數
// 先定義,后賦值
let arr = new Array();
arr[0] = 1;
arr[1] = 2;
console.log(arr) // [1, 2]
// 定義時賦值
let arr = new Array(1,2,3);
console.log(arr); // [1, 2,3]
2.使用字面量定義
let arr = [1,2,3];
console.log(arr); // [1, 2, 3]
ES6數組的創(chuàng)建
1.Array.of()
作用:將參數中所有值作為元素形成數組
背景:傳統(tǒng)js使用Array()構造函數創(chuàng)建數組玩裙,會因傳遞參數的個數存在爭議(只傳遞一個參數時枪向,參數會被當作數組長度處理)
Array() // []
Array(2) // [, , ]
Array(1, 2) // [1, 2]
用法:
直接使用Array.of(),向括號中傳遞任何類型的參數帝火,參數全部處理為數組的元素
let arr = Array.of(1,"2",{},[],new Map(),new Set(),null,undefined,NaN,true,false,function a(){});
console.log(arr);
// (12) [1, "2", {…}, Array(0), Map(0), Set(0), null, undefined, NaN, true, false, ?]
模擬Array.of方法:
function ArrayOf(){
return [].slice.call(arguments);
}
2.Array.from()
作用:將類數組對象或可迭代對象(包括 ES6 新增的數據結構 Set 和 Map)轉化為數組
1.基本用法:
接收三個參數:
-第一個是轉換的類數組對象或可迭代對象;
-第二個是對參數進行處理的map 函數(可選)湃缎;
-第三個是指定 map 函數執(zhí)行時的 this 對象(可選)
let map = {
haha: function(n) {
return 2;
}
do: function(n) {
return n * 2;
}
}
let arrayLike = [1, 2, 3];
console.log(Array.from(arrayLike, function (n){
console.log(this); /// 這里this是map對象
return this.do(n);
}, map)); // [2, 4, 6]
2.轉換類數組對象
let arrayLike = {
'0': 'a',
'1': 'b',
'2': 'c',
length: 3
};
// ES5的寫法
var arr1 = [].slice.call(arrayLike); // ['a', 'b', 'c']
// ES6的寫法
let arr2 = Array.from(arrayLike); // ['a', 'b', 'c'];
// 注意:一定要是類數組對象犀填,即定義了length屬性,若沒有定義則返回空數組
let arrayLike1 = {
'0': 'a',
'1': 'b',
'2': 'c',
};
let arr3 = Array.from(arrayLike1); // [];
// 元素屬性名不為數值且無法轉換為數值嗓违,返回長度為 length 元素值為 undefined 的數組
let arr4 = Array.from({
a: 1,
b: 2,
length: 2
});
console.log(array4); // [undefined, undefined]
3.轉換可迭代對象
a.數組本身
let arr = [1,2,3];
let arr1 = Array.from(arr); // [1,2,3]
// 注意這是數組淺拷貝九巡,上面我們修改arr1的值不會影響arr,但下面的情況就不一樣的
let arr2 = [1,2,[3,4]];
let arr3 = Array.from(arr2);
arr3[2][0] = 5;
console.log(arr2); // [1,2,[5,4]]
// 上面的代碼我們可以看出,我們修改新數組蹂季,原數組的值也跟著變了冕广,同樣的還有concat,slice等方法
b.轉換Map結構數據
let map = new Map();
map.set("one",1);
map.set("two",2);
let arr = Array.from(map); // [["one",1],["two",2]]
c.轉換Set結構數據
let set = new Set([1,2,3,3]);
let arr = Array.from(set); // [1, 2, 3]
d.轉換字符串
let str = 'abc';
console.log(Array.from(str)); // ["a", "b", "c"]
擴展運算符
寫法:...
用途:將一個數組轉為用逗號分隔的參數序列
// 基礎用法
console.log(...[1,2,3]); // 1 2 3
// 上面語句相當于console.log(1,2,3)
// 數組缺少某元素時用undefined替換
console.log(...[1,2,,3]); // 1 2 undefined 3
// 擴展運算符后面放置表達式
const arr = [1,...[1+2]]; // arr = [1,3];
const arr1 = [
...(x > 0 ? ['a'] : []),
'b',
];
const arr2 = ['a',...('b'+'c')]; // ["a", "b", "c"]
// 注意:...后面表達式必須是可迭代對象乏盐,即const arr = [1,(1+2)]會報錯
// 擴展運算符后面是空數組會被忽略
[...[], 1] // [1]
擴展運算符的應用場景
1.替換函數的apply方法
// ES5 的寫法
Math.max.apply(null, [20, 35, 17])
// ES6 的寫法
Math.max(...[20, 35, 17])
// 等同于
Math.max(20, 35, 17);
2.復制數組
// ES5寫法
const arr1 = [1, 2];
const arr2 = arr1.concat();
arr2[0] = 3;
console.log(arr1,arr2) // [1, 2] [3, 2]
// ES6寫法
const arr1 = [1, 2];
const arr2 = [...arr1];
arr2[0] = 3;
console.log(arr1,arr2) ;
// [1, 2] [3, 2]
// 但是當數組中包含多層數組時佳窑,修改新數組還是會影響原數組
const arr1 = [1, 2,[3,4]];
const arr2 = [...arr1];
arr2[0] = 3;
arr2[2][0] = 5;
console.log(arr1,arr2) ; // [1, 2,[5,4]] [3, 2,[5,4]]
// 這時候我們還是得使用遞歸才能進行深度拷貝
3.合并數組
const arr1 = ['a', 'b'];
const arr2 = ['c'];
const arr3 = ['d', 'e'];
// ES5 的合并數組
arr1.concat(arr2, arr3);
// [ 'a', 'b', 'c', 'd', 'e' ]
// ES6 的合并數組
[...arr1, ...arr2, ...arr3]
// [ 'a', 'b', 'c', 'd', 'e' ]
4.與解構賦值結合生成新數組
const [first, ...rest] = [1, 2, 3, 4, 5];
first // 1
rest // [2, 3, 4, 5]
5.將字符串轉為真正的數組
能夠識別四個字節(jié)的 Unicode 字符,這是使用split()方法不能實現的
let str = 'x\uD83D\uDE80y';
let arr = str.split(""); // ["x", "?", "?", "y"]
[...str]; // ["x", "??", "y"]
6.將Map 和 Set 結構數據轉換為數組
let map = new Map([[1,"一"],[2,"二"]]);
let set = new Set([1,2,3]);
[...map]; // [[1,"一"],[2,"二"]]
[...set]; // [1, 2, 3]
7.返回Generator 函數執(zhí)行的結果
let fun= function*(){
yield 1;
yield 2;
yield 3;
};
[...fun()] // [1, 2, 3]
擴展的方法
查找
1.find()
作用:查找數組中符合條件的元素,若有多個符合條件的元素父能,則返回第一個元素神凑,如果沒有符合條件的成員,則返回undefined
[1,2,3,4,5].find(x=>x>3); // 4
[1,2,3,4,5].find(x=>x<0); // undefined
// 返回數組的第一個元素
[1,2,3,4].find(x=>true); // 1
find方法的回調函數可以接受三個參數何吝,依次為當前的值溉委、當前的位置和原數組。
[1, 2, 3, 4].find(function(value, index, arr) {
return value > 3;
}) // 4
find()方法都可以接受第二個參數爱榕,用來綁定回調函數的 thi
s對象瓣喊。
function foo(value){
return value> this.age;
}
let person = {name: '張三', age: 22};
[18, 2, 24, 20].find(foo, person); // 24
2.findIndex()
作用:查找數組中符合條件的元素索引,若有多個符合條件的元素黔酥,則返回第一個元素索引藻三,若未查找到符號條件的元素則返回-1.
其他和find()函數類似
另外,這兩個方法都可以發(fā)現NaN跪者,彌補了數組的indexOf方法的不足
[NaN].indexOf(NaN)
// -1
[NaN].findIndex(y => Object.is(NaN, y))
// 0
填充
1.fill()
作用:使用給定值填充數組(修改原數組)
基本用法:
[1,2,3,4].fill(5);
// [5, 5, 5, 5]
可傳遞的參數:共三個棵帽,第一個是用于填充的內容,第二個是指定開始位置渣玲,第三個指定結束位置
[1,2,3,4].fill(5,1,2); // [1, 5, 3, 4]
特殊情況:屬于淺拷貝逗概,即若填充內容是引用類型,則改變填充后的內容會影響原數據
let obj = {name:"張三"};
let arr = [1,2,3,4];
arr.fill(obj,0,1);
console.log(arr); // [{name:"張三"}, 2, 3, 4]
arr[0].name = "李四";
console.log(arr); // [{name:"李四"}, 2, 3, 4]
console.log(obj); // {name: "李四"}
// 引用類型都會被影響
2.copyWithin()
作用:將同數組的某一部分用另一部分替換
參數:供三個忘衍,第一個指定被替換元素的起始位置逾苫,第二個指定用來替換的元素的起始位置卿城,第三個指定用來替換元素的結束位置(實際結束位置=第三個參數-1)。
用法:
let arr = [1,2,3,4,5,6];
arr.copyWithin(0,2,5);
console.log(arr); // [3, 4, 5, 4, 5, 6]
特殊情況:
1.省略第三個參數铅搓,表示替換元素結束位置是字符串末尾
let arr = [1,2,3,4,5,6];
arr.copyWithin(0,2); // 相當于arr.copyWithin(0,2,6); 或者arr.copyWithin(0,2,arr.length);
console.log(arr); // [3, 4, 5, 6, 5, 6]
2.第一個參數為負數表示從倒數第n個元素開始替換
console.log([1, 2, 3, 4].copyWithin(-2, 0)); // [1, 2, 1, 2]
3.后面兩個參數同為負數表示從倒數第幾個開始到倒數第結束的替換元素
console.log([1, 2, 3, 4].copyWithin(0, -2,-1)); // [3, 2, 3, 4]
4.后面兩個參數有一個為負數瑟押,另一個不為負數將不會起作用
console.log([1, 2, 3, 4].copyWithin(2, -1,0)); // [1, 2, 3, 4]
遍歷
1.entries()
作用:遍歷鍵值對
// 使用for...of遍歷
let arr = [1,2]
for(let chl of arr.entries()){
console.log(chl )
}
// [0, 1]
// [1, 2]
// chl是包含鍵和值數組
// 不用for...of循環(huán)遍歷
let entr = arr.entries();
console.log(entr.next().value); // [0,1]
console.log(entr.next().value); // [1, 2]
// 數組含空位
console.log([...[,'a'].entries()]); // [[0, undefined], [1, "a"]]
2.keys()
作用:遍歷鍵名
for(let key of ['a', 'b'].keys()){
console.log(key);
}
// 0
// 1
// 數組含空位
console.log([...[,'a'].keys()]); // [0, 1]
3.values()
作用:遍歷鍵值
for(let value of ['a', 'b'].values()){
console.log(value);
}
// "a"
// "b"
// 數組含空位
console.log([...[,'a'].values()]); // [undefined, "a"]
包含
1.includes()
作用:數組是否包含指定值
let arr = [1,"2",null,NaN,undefined,true];
arr.includes(1); // true
arr.includes("2"); // true
arr.includes(2); // false
arr.includes(null); // true
arr.includes(undefined); // true
arr.includes(NaN); // true
arr.includes(true); // true
let arr1 = [];
arr1.includes(undefined); // false
arr1.includes(null); // false
arr1.includes(NaN); // false
該方法的第二個參數表示搜索的起始位置,默認為0狸吞。如果第二個參數為負數勉耀,則表示倒數的位置,如果這時它大于數組長度(比如第二個參數為-4蹋偏,但數組長度為3)便斥,則會重置為從0開始。
[1, 2, 3].includes(3, 3); // false
[1, 2, 3].includes(3, -1); // true
Map 和 Set 數據結構有一個has方法威始,需要注意與includes區(qū)分枢纠。
Map 結構的has方法,是用來查找鍵名的黎棠,比如Map.prototype.has(key)
晋渺、WeakMap.prototype.has(key)
、Reflect.has(target
, propertyKey)
脓斩。
Set 結構的has方法木西,是用來查找值的,比如Set.prototype.has(value)
随静、WeakSet.prototype.has(value)
八千。
嵌套數組轉一維數組
1.flat()
作用:用于將嵌套的數組“拉平”,變成一維的數組燎猛。該方法返回一個新數組恋捆,對原數據沒有影響。
基本用法:
console.log([1 ,[2, 3]].flat());
// 自動跳過空位
console.log([1, [2, , 3]].flat());<p> // [1, 2, 3]
特殊情況:
1.拉平多層
console.log([1 ,[2, [3,4,5,[6,7]]]].flat(2)); // [1, 2, 3, 4, 5, [6,7]]
2.拉平所有
console.log([1 ,[2, [3,4,5,[6,7]]]].flat(Infinity)); // [1, 2, 3, 4, 5, 6,7]
2.flatMap()
作用:先對數組中每個元素進行了的處理重绷,再對數組執(zhí)行 flat() 方法沸停。該方法返回一個新數組,不改變原數組昭卓。
// 相當于 [[2, 4], [3, 6], [4, 8]].flat()
[2, 3, 4].flatMap((x) => [x, x * 2])
// [2, 4, 3, 6, 4, 8]
注意:
flatMap()只能展開一層數組
// 相當于 [[[2]], [[4]], [[6]], [[8]]].flat()
[1, 2, 3, 4].flatMap(x => [[x * 2]])
// [[2], [4], [6], [8]]
// 參數1:遍歷函數愤钾,該遍歷函數可接受3個參數:當前元素、當前元素索引候醒、原數組
// 參數2:指定遍歷函數中 this 的指向
arr.flatMap(function callback(currentValue[, index[, array]]) {
// ...
}[, thisArg])
排序穩(wěn)定性
排序穩(wěn)定性:是排序算法的重要屬性绰垂,指的是排序關鍵字相同的項目,排序前后的順序不變火焰。
const arr = [
'peach',
'straw',
'apple',
'spork'
];
const stableSorting = (s1, s2) => {
if (s1[0] < s2[0]) return -1;
return 1;
};
arr.sort(stableSorting)
// ["apple", "peach", "straw", "spork"] 穩(wěn)定的
const unstableSorting = (s1, s2) => {
if (s1[0] <= s2[0]) return -1;
return 1;
};
arr.sort(unstableSorting)
// ["apple", "peach", "spork", "straw"] 不穩(wěn)定的