摘要:然而彌補了數組構造函數的不足,將參數依次轉化為數組中的一項,然后返回這個新數組,而不管這個參數是數字還是其它,它的行為非常統一。方法無法識別數組的成員,但是方法可以借助方法做到。用于將嵌套的數組拉平。其中和屬于構造函數方法。
在javascript中,數組是最重要的數據結構,沒有之一,因為所有的數據結構都可以使用數組模擬和表達。可以說掌握了數組,就掌握了js與數據操作的大部分核心功能。
ES6給數組添加了一些新特性,而這些新特性到目前為止完全可以運用到自己的業務層。
但是,開發者初次接觸ES6,很多東西都看得云里來霧里,無從下手。在這一節中將總結有關于ES6給數組提供一些新特性的使用方法,讓用戶能夠聽得懂,用的起來。
1、新增數組創建方法
1.1 Array.from
Array.from的設計目的是快速便捷把一個類似數組的可迭代對象創建成一個新的數組實例。
通俗的講,只要一個對象有length,Array.from就能把它變成一個數組,返回新的數組,而不改變原對象。
let likeArr = {
"0": "a",
"1": "b",
"2": "c",
length: 3
};
// ES5的寫法
var arr1 = [].slice.call(likeArr); // ["a", "b", "c"]
// ES6的寫法
let arr2 = Array.from(likeArr); // ["a", "b", "c"]
常見的類似數組的對象還有 DOM 操作返回的 NodeList 集合,以及函數內部的 arguments 對象。Array.from都可以將它們轉為真正的數組。
// NodeList對象
let div = document.querySelectorAll("div");
console.log(div); // NodeList(8)?[div#cst, div, div.gb_3,?…]
console.log(Array.from(div)); //(8)?[div#cst, div, div.gb_3,?…]
// arguments對象
function foo() {
var args = Array.from(arguments);
console.log(args);
}
foo(1,2,34,666,333,663); // [1, 2, 34, 666, 333, 663]
Array.from 對 String,Set,Map 等擁有迭代器的對象也可以進行轉換。
// String
Array.from("abc"); // ["a", "b", "c"]
// Set
Array.from(new Set(["abc", "def"])); // ["abc", "def"]
// Map
Array.from(new Map([[1, "abc"], [2, "def"]])); // [[1, "abc"], [2, "def"]]
此外,生成一個從0到指定數字的新數組,Array.from可以輕易的做到:
Array.from({length: 10}, (v, i) => i); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]復制代碼
Array.from 接收的第二個參數,作用類似于數組的map方法,用來對每個元素進行處理,處理后的值放入返回的數組:
let arrayLike = [1,3,5]; Array.from(arrayLike, x => x+1); //?[2, 4, 6] // 等同于 Array.from(arrayLike).map(x => x+1); //?[2, 4, 6]
1.2 Array.of
當參數個數大于1時,Array() 才會返回由參數組成的新數組。當參數個數只有一個時,實際上是指定數組的長度。
Array() // [] Array(3) // [, , ,] Array(3, 4, 5) // [3, 4, 5]
由于參數個數的不同,會導致 Array() 的行為有差異。
然而 Array.of 彌補了數組構造函數 Array() 的不足,Array.of 將參數依次轉化為數組中的一項,然后返回這個新數組,而不管這個參數是數字還是其它,它的行為非常統一。
Array.of() // [] Array.of(undefined) // [undefined] Array.of(3) // [3] Array.of(3, 4, 5) // [3, 4, 5]
Array.of 總是返回參數值組成的數組。如果沒有參數,就返回一個空數組。
2、新增數組修改方法
2.1 copyWithin
可以在當前數組內部,將指定位置的數組項復制到其他位置,會覆蓋原數組項,然后返回當前數組。使用該方法會修改當前數組。
Array.prototype.copyWithin(target, start = 0, end = this.length)
它接受三個參數:
(1)target(必需):從該位置開始替換數據。如果為負值,表示倒數。
(2)start(可選):從該位置開始讀取數據,默認為 0。如果為負值,表示倒數。
(3)end(可選):到該位置前停止讀取數據,默認等于數組長度。如果為負值,表示倒數。
這三個參數都應該是數值,如果不是,會自動轉為數值。
["a","b","c","d","e","f","g"].copyWithin(0, 3) // ["d", "e", "f", "g", "e", "f", "g"]
上面代碼表示將從 3 號位 直到數組結束的成員("d","e","f","g"),復制到從 0 號位開始的位置,結果覆蓋了原來的 "a" 和 "b" 。
將3號位復制到0號位,可以這么寫:
["a","b","c","d","e","f","g"].copyWithin(0, 3, 4) // ["d", "b", "c", "d", "e", "f", "g"]
start、end 為負數的情況:
["a","b","c","d","e","f","g"].copyWithin(0, -3, -1) // ["e", "f", "c", "d", "e", "f", "g"]
start -3 指的是 "e",-3 - (-1)=2,就是用 "e" , "f" 兩個元素替換掉從0開頭的 "a" , "b"
2.2 fill
使用給定值,填充一個數組。
[1,2,3,4,5].fill("a");
// ["a", "a", "a", "a", "a"]
new Array(3).fill(12)
// [12, 12, 12]
fill 方法用于空數組的初始化非常方便。數組中已有的元素,會被全部抹去。
fill方法還可以接受第二個和第三個參數,用于指定填充的起始位置和結束位置。
[1,2,3,4,5].fill("a",2,4);
// [1, 2, "a", "a", 5]
fill 方法從 2 號位開始,向原數組填充 "a",直到 4 號位之前結束。
注意,如果填充的類型為對象,那么被賦值的是同一個內存地址的對象,而不是深拷貝對象。
let arr = new Array(3).fill({name: "aaa"});
arr[0].name = "bbb";
console.log(arr) // [{name: "bbb"}, {name: "bbb"}, {name: "bbb"}]
let arr = new Array(3).fill([]);
arr[0].push("ccc");
console.log(arr) // [["ccc"], ["ccc"], ["ccc"]]
3、新增數組查找遍歷方法
3.1 find 和 findIndex
find 返回數組中第一個滿足條件的元素(如果有的話), 如果沒有,則返回undefined。
[1, 4, -5, 10].find((n) => n < 0) // -5 [1, 4, -5, 10].find((n) => n < -10) // undefined
find方法的回調函數可以接受三個參數,依次為當前的值、當前的位置和原數組。
[1, 5, 10, 15].find(function(value, index, arr) {
return value > 9;
})
// 10
[1, 5, 10, 15].find(function(value, index, arr) {
return console.log(value, index, arr)
})
1 0 [1, 5, 10, 15]
5 1 [1, 5, 10, 15]
10 2 [1, 5, 10, 15]
15 3 [1, 5, 10, 15]
數組實例的 findIndex 方法的用法與 find 方法很類似,返回第一個符合條件的數組成員的位置,如果所有成員都不符合條件,則返回 -1。
[1, 5, 10, 15].findIndex(function(value, index, arr) {
return value > 9;
})
// 2
indexOf 方法無法識別數組的 NaN 成員,但是 findIndex 方法可以借助 Object.is 方法做到。
["a","b",NaN,"c"].indexOf(NaN) // -1 ["a","b",NaN,"c"].findIndex(y => Object.is(NaN, y)) // 2
3.2 includes
方法返回一個布爾值,表示某個數組是否包含給定的值,與字符串的 includes 方法類似。
沒有該方法之前,我們通常使用數組的 indexOf 方法,檢查是否包含某個值。
if (arr.indexOf(el) !== -1) {
}
indexOf 方法有兩個缺點:
一是不夠語義化,它的含義是找到參數值的第一個出現位置,所以要去比較是否不等于 -1,表達起來不夠直觀。
二是,它內部使用嚴格相等運算符(===)進行判斷,這會導致對 NaN 的誤判。
[NaN].indexOf(NaN) // -1
includes 使用的是不一樣的判斷算法,就沒有這個問題。
[NaN].includes(NaN) // true
includes 第二個參數表示搜索的起始位置:
["a","b","c","d"].includes("c",2) //true
["a","b","c","d"].includes("c",3) //false
如果第二個參數為負數,則表示從倒數第幾位向后搜索:
["a","b","c","d"].includes("c",-1) //false (-1指的是倒數第一位"d")
["a","b","c","d"].includes("c",-2) //true (-2指的是倒數第二位"c")
3.3 entries、keys、values
它們都返回一個遍歷器對象,都可以用 for...of 循環進行遍歷。
唯一的區別是 keys 是對鍵名的遍歷、 values 是對鍵值的遍歷, entries 是對鍵值對的遍歷。
for (let index of ["a", "b", "c"].keys()) {
console.log(index);
}
// 0
// 1
// 2
for (let elem of ["a", "b", "c"].values()) {
console.log(elem);
}
// "a"
// "b"
// "c"
for (let [index, elem] of ["a", "b", "c"].entries()) {
console.log(index, elem);
}
// 0 "a"
// 1 "b"
// 2 "c"
4、數組降維方法
4.1 flat
說到數組拍平,我們先看一道阿里面試題:
編寫一個 JavaScript 函數,接受一個僅包含數字的 多維數組 ,返回拍平以后的結果。例如傳入:[1, [[2], 3, 4], 5],返回 [1, 2, 3, 4, 5]。
(本題來源:阿里巴巴前端筆試題)
const arr = [1, [[2], 3, 4], 5];
const flatten = arr => {
return arr.reduce((flat, toFlat) => {
return flat.concat(Array.isArray(toFlat) ? flatten(toFlat) : toFlat);
}, []);
};
const res = flatten(arr);
console.log(res);
OK,我知道你覺得它太復雜,我這里只是展示一下數組拍平的應用場景,接下來,我們詳細說說關于數組拍平的知識。
flat用于將嵌套的數組“拉平”。該方法返回一個新數組,對原數據沒有影響。
[1, 2, [3, 4]].flat() // [1, 2, 3, 4]
默認只會“拉平”一層,如果想要“拉平”多層的嵌套數組,可以將flat方法的參數寫成一個整數,表示想要拉平的層數,默認為1。
[1, 2, [3, [4, 5]]].flat(2) // [1, 2, 3, 4, 5]
如果數組嵌套的層數不固定怎么辦?把flat里的參數寫成1000或者100000?
這樣寫太死板了,可以聯想到 Infinity (無窮大)啊。
不管有多少層嵌套,如果都要轉成一維數組,可以用 Infinity 關鍵字作為參數。
[1, [2, [3, [4]]]].flat(Infinity) // [1, 2, 3, 4]
4.2 flatMap
方法對原數組的每個成員執行一個函數(相當于執行 Array.prototype.map),然后對返回值組成的數組執行 flat() 方法。該方法返回一個新數組,不改變原數組。
[2, 3, 4].flatMap((x) => [x, x * 2]) // [2, 4, 3, 6, 4, 8] // 相當于 [[2, 4], [3, 6], [4, 8]].flat()
注意:flatMap() 只能展開一層數組。
5、總結
數組新增的方法,一方面起到了增強型作用,一方面讓代碼變得更加簡潔。
其中 Array.from 和 Array.of 屬于構造函數方法。
從是否改變數組自身的角度看:
copyWithin、fill 會改變數組自身,
includes、flat、flatMap不會改變數組自身。
entries、keys、values、find、findeIndex屬于數組遍歷方法。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.hztianpu.com/yun/110213.html
摘要:前一個值,當前值,索引,數組對象產生新數組的迭代器方法類似,對數組的每個元素使用某個函數,并返回新數組和相似,傳入一個返回值為布爾類型的函數。 1. 前言 數組真的是每天用了,但是有很多方法都是記不住,總是要百度查,很煩,所以才寫了個數組使用總結,有什么不對的希望大家指出來。 2. 思路 先看看這些問題都記得很清楚么? 創建數組,怎么創建數組的 數組的構造方法Array有哪些方法?E...
摘要:定義類常用新特性在一個數組或者列表中檢查是否存在一個值還能在字符串中使用除了增強了可讀性語義化,實際上給開發者返回布爾值,而不是匹配的位置。 ES6常用新特性 1. let && const let 命令也用于變量聲明,但是作用域為局部 { let a = 10; var b = 1; } 在函數外部可以獲取到b,獲取不到a,因此例如for循環計數器就適...
摘要:定義類常用新特性在一個數組或者列表中檢查是否存在一個值還能在字符串中使用除了增強了可讀性語義化,實際上給開發者返回布爾值,而不是匹配的位置。 ES6常用新特性 1. let && const let 命令也用于變量聲明,但是作用域為局部 { let a = 10; var b = 1; } 在函數外部可以獲取到b,獲取不到a,因此例如for循環計數器就適...
閱讀 759·2023-04-25 17:26
閱讀 1741·2021-08-05 09:58
閱讀 2133·2019-08-30 13:17
閱讀 1157·2019-08-28 17:52
閱讀 1262·2019-08-26 18:27
閱讀 1627·2019-08-26 14:05
閱讀 3822·2019-08-26 14:05
閱讀 1902·2019-08-26 10:45