ES6—數組

作者:米書林
參考文章:《菜鳥教程》藐翎、《 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()方法都可以接受第二個參數爱榕,用來綁定回調函數的 this對象瓣喊。

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)定的

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市胧沫,隨后出現的幾起案子昌简,更是在濱河造成了極大的恐慌占业,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件纯赎,死亡現場離奇詭異谦疾,居然都是意外死亡,警方通過查閱死者的電腦和手機犬金,發(fā)現死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門念恍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人晚顷,你說我怎么就攤上這事峰伙。” “怎么了该默?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵瞳氓,是天一觀的道長。 經常有香客問我栓袖,道長匣摘,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任裹刮,我火速辦了婚禮音榜,結果婚禮上,老公的妹妹穿的比我還像新娘捧弃。我一直安慰自己赠叼,他們只是感情好,可當我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布塔橡。 她就那樣靜靜地躺著梅割,像睡著了一般。 火紅的嫁衣襯著肌膚如雪葛家。 梳的紋絲不亂的頭發(fā)上户辞,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天,我揣著相機與錄音癞谒,去河邊找鬼底燎。 笑死,一個胖子當著我的面吹牛弹砚,可吹牛的內容都是我干的双仍。 我是一名探鬼主播,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼桌吃,長吁一口氣:“原來是場噩夢啊……” “哼朱沃!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤逗物,失蹤者是張志新(化名)和其女友劉穎搬卒,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體翎卓,經...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡契邀,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了失暴。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片坯门。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖逗扒,靈堂內的尸體忽然破棺而出古戴,到底是詐尸還是另有隱情,我是刑警寧澤缴阎,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布允瞧,位于F島的核電站,受9級特大地震影響蛮拔,放射性物質發(fā)生泄漏述暂。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一建炫、第九天 我趴在偏房一處隱蔽的房頂上張望畦韭。 院中可真熱鬧,春花似錦肛跌、人聲如沸艺配。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽转唉。三九已至,卻和暖如春稳捆,著一層夾襖步出監(jiān)牢的瞬間赠法,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工乔夯, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留砖织,地道東北人。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓末荐,卻偏偏與公主長得像侧纯,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子甲脏,可洞房花燭夜當晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內容