摘要:方法也是對象的通用方法。這就是說,如果數(shù)組遍歷的目的是為了得到返回值,那么使用方法,否則使用方法。,這兩個方法類似斷言,返回一個布爾值,表示判斷數(shù)組成員是否符合某種條件。,方法和方法依次處理數(shù)組的每個成員,最終累計為一個值。
屬性 length
length 屬性可獲得數(shù)組的長度,即數(shù)組中值的個數(shù)。數(shù)組的長度是比數(shù)組最大索引值多一的數(shù)。
let arr = [1, 2, 3, 4] arr.length // 4;
如果給 length 屬性賦值,指定的數(shù)組長度小于原數(shù)組長度,會縮短數(shù)組。
let arr = [1, 2, 3, 4] arr.length = 3; arr // [1, 2, 3]
length 設(shè)為 0,可以清空數(shù)組。
let arr = [1, 2, 3, 4] arr.length = 0; arr // []方法 靜態(tài)方法 1. Array.isArray()
Array.isArray() 方法返回一個布爾值,表示參數(shù)是否為數(shù)組。它可以彌補(bǔ) typeof 運(yùn)算符的不足。
let arr = [1, 2, 3]; typeof arr // "object" Array.isArray(arr) // true2. Array.from()
Array.from() 方法用于將兩類對象轉(zhuǎn)為真正的數(shù)組:類數(shù)組對象和可遍歷(iterable)的對象(包括 ES6 新增的數(shù)據(jù)結(jié)構(gòu) Set 和 Map)。返回值是新數(shù)組。
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"]
只要是部署了 Iterator 接口的數(shù)據(jù)結(jié)構(gòu),Array.from 都能將其轉(zhuǎn)為數(shù)組。
Array.from("hello") // ["h", "e", "l", "l", "o"] let namesSet = new Set(["a", "b"]) Array.from(namesSet) // ["a", "b"]
任何有 length 屬性的對象,即類數(shù)組對象,都可以通過 Array.from() 方法轉(zhuǎn)為數(shù)組。
Array.from({ length: 3 }); // [ undefined, undefined, undefined ]
Array.from() 還可以接受第二個參數(shù),作用類似于數(shù)組的 map 方法,用來對每個元素進(jìn)行處理,將處理后的值放入返回的數(shù)組。
Array.from(arrayLike, x => x * x); // 等同于 Array.from(arrayLike).map(x => x * x); Array.from([1, 2, 3], (x) => x * x) // [1, 4, 9]
Array.from() 的第三個參數(shù),用來綁定 this。
應(yīng)用
取出一組 DOM 節(jié)點(diǎn)的文本內(nèi)容。
let spans = document.querySelectorAll("span.name"); // map() let names1 = Array.prototype.map.call(spans, s => s.textContent); // Array.from() let names2 = Array.from(spans, s => s.textContent)
將數(shù)組中布爾值為 false 的成員轉(zhuǎn)為 0。
Array.from([1, , 2, , 3], (n) => n || 0) // [1, 0, 2, 0, 3]
返回各種數(shù)據(jù)的類型。
function typesOf () { return Array.from(arguments, value => typeof value) } typesOf(null, [], NaN) // ["object", "object", "number"]
將字符串轉(zhuǎn)為數(shù)組,然后返回字符串的長度。因?yàn)樗苷_處理各種 Unicode 字符,可以避免 JS 將大于 uFFFF 的 Unicode 字符,算作兩個字符的 bug。
function countSymbols(string) { return Array.from(string).length; }3. Array.of()
Array.of() 方法用于將一組值,轉(zhuǎn)換為數(shù)組。
Array.of(3, 11, 8) // [3,11,8] Array.of(3) // [3] Array.of(3).length // 1
Array.of() 總是返回參數(shù)值組成的數(shù)組。如果沒有參數(shù),就返回一個空數(shù)組。
Array.of() // [] Array.of(undefined) // [undefined] Array.of(1) // [1]
Array.of() 方法可以用下面的代碼模擬實(shí)現(xiàn)。
function ArrayOf(){ return [].slice.call(arguments); }實(shí)例方法 1. valueOf(),toString()
valueOf() 方法是一個所有對象都擁有的方法,表示對該對象求值,不同對象的valueOf() 方法不盡一致。數(shù)組的 valueOf 方法是 Array 構(gòu)造函數(shù)的原型上的方法,覆蓋了 Object 的 valueOf() 方法,返回數(shù)組本身。
let arr = [1, 2, 3]; arr.valueOf() // [1, 2, 3]
toString() 方法也是對象的通用方法。數(shù)組的 toString 方法是 Array 構(gòu)造函數(shù)的原型上的方法,覆蓋了 Object 的 toString() 方法,返回數(shù)組的字符串形式。相當(dāng)于調(diào)用 join() 方法,將數(shù)組轉(zhuǎn)換為字符串,用逗號連接。
let arr = [1, 2, 3]; arr.toString() // "1,2,3" let arr = [1, 2, 3, [4, 5, 6]]; arr.toString() // "1,2,3,4,5,6"2. push(),pop()
push() 方法用于在數(shù)組的末端添加一個或多個元素,并返回添加新元素后的數(shù)組長度。
該方法會直接改變原數(shù)組。
let arr = []; arr.push(1) // 1 arr.push("a") // 2 arr.push(true, {}) // 4 arr // [1, "a", true, {}]
pop() 方法用于刪除數(shù)組的最后一個元素,一次只能刪一項(xiàng)。并返回被刪除的該元素。
該方法會直接改變原數(shù)組。
let arr = ["a", "b", "c"]; arr.pop() // "c" arr // ["a", "b"]
對空數(shù)組使用 pop() 方法,不會報錯,而是返回 undefined。
[].pop() // undefined
push() 和 pop() 結(jié)合使用,就構(gòu)成了“后進(jìn)先出”的棧結(jié)構(gòu)(stack)。
let arr = []; arr.push(1, 2); arr.push(3); arr.pop(); // 3 是最后進(jìn)入數(shù)組的,但是最早離開數(shù)組。 arr // [1, 2]3. shift(),unshift()
shift() 方法用于刪除數(shù)組的第一個元素,一次只能刪一項(xiàng)。并返回被刪除的該元素。
該方法會直接改變原數(shù)組。
let arr = ["a", "b", "c"]; arr.shift() // "a" arr // ["b", "c"]
push() 和 shift() 結(jié)合使用,就構(gòu)成了“先進(jìn)先出”的隊(duì)列結(jié)構(gòu)(queue)。
let arr = []; arr.push(1, 2); arr.push(3); arr.shift(); // 1 是最先進(jìn)入數(shù)組的,也最早離開數(shù)組。 arr // [2, 3]
unshift() 方法用于在數(shù)組的第一個位置添加一個或多個元素,并返回添加新元素后的數(shù)組長度。
該方法會直接改變原數(shù)組。
let arr = ["a", "b", "c"]; arr.unshift("x"); // 4 arr.unshift("y", "z") // 6 arr // ["y", "z", "x", "a", "b", "c"]4. join()
join() 方法以指定參數(shù)作為分隔符,將所有數(shù)組成員連接為一個字符串返回。如果不提供參數(shù),默認(rèn)用逗號分隔。
該方法不改變原數(shù)組。
let arr = [1, 2, 3, 4]; arr.join(" ") // "1 2 3 4" arr.join(" | ") // "1 | 2 | 3 | 4" arr.join("~") // "1~2~3~4" arr.join() // "1,2,3,4"
如果數(shù)組成員是 undefined 或 null 或 空位 ,會被轉(zhuǎn)成空字符串。
[undefined, null].join("#") // "#" ["a",, "b"].join("-") // "a--b"
通過 call 方法,這個方法也可以用于字符串或類數(shù)組對象。
Array.prototype.join.call("hello", "-") // "h-e-l-l-o" let obj = { 0: "a", 1: "b", length: 2 }; Array.prototype.join.call(obj, "-") // "a-b"5. concat()
concat() 方法用于多個數(shù)組的合并。它將新數(shù)組的成員,添加到原數(shù)組成員的后面,然后返回一個新數(shù)組。參數(shù)設(shè)置非常靈活,可以是數(shù)組變量,也可以是字符串或數(shù)組字面量。
該方法不改變原數(shù)組。
["hello"].concat(["world"], ["!"]) // ["hello", "world", "!"] [].concat({a: 1}, {b: 2}) // [{ a: 1 }, { b: 2 }] [1, 2, 3].concat(4, 5, 6) // [1, 2, 3, 4, 5, 6] let arr = [2,3]; [1].concat(arr) // [1, 2, 3]
concat() 方法是“淺拷貝”,拷貝的是對象的引用。
let obj = { a: 1 }; let newArray = [].concat(obj); newArray[0].a // 1 obj.a = 2 // 2 newArray[0].a // 26. reverse()
reverse() 方法用于顛倒排列數(shù)組元素,返回改變后的數(shù)組。
該方法會直接改變原數(shù)組。
let arr = ["a", "b", "c"]; arr.reverse() // ["c", "b", "a"] arr // ["c", "b", "a"]7. slice()
slice(start, end) 方法用于提取目標(biāo)數(shù)組中選中的部分作為一個新的數(shù)組返回。
該方法不改變原數(shù)組。
參數(shù)
a. slice(start, end),從下標(biāo) start 開始截取到下標(biāo) end 的元素,包含 start 不包含 end。
let arr = ["a", "b", "c"]; arr.slice(1, 2) // ["b"] arr.slice(2, 6) // ["c"]
b. slice(start),只有 start 一個參數(shù)表示從包含 start 的下標(biāo)開始截取后面所有的元素。
let arr = ["a", "b", "c"]; arr.slice(1) // ["b", "c"]
c. slice(),沒有參數(shù),則相當(dāng)于從下標(biāo) 0 開始截取后面所有的元素,實(shí)際上等于返回一個原數(shù)組的拷貝。
let arr = ["a", "b", "c"]; arr.slice(0) // ["a", "b", "c"] arr.slice() // ["a", "b", "c"]
d. slice(-start, -end),參數(shù)可以用負(fù)數(shù)。表示倒數(shù)計算的位置。-1 表示倒數(shù)計算的第一個位置,依次向前類推。
let arr = ["a", "b", "c"]; arr.slice(-2) // ["b", "c"] arr.slice(-2, -1) // ["b"]
e. 如果第一個參數(shù)大于等于數(shù)組長度,或者第二個參數(shù)小于第一個參數(shù),則返回空數(shù)組。
let arr = ["a", "b", "c"]; arr.slice(4) // [] arr.slice(2, 1) // []
slice() 方法的一個重要應(yīng)用,是通過 call 方法,將類數(shù)組對象轉(zhuǎn)為真正的數(shù)組。
Array.prototype.slice.call({ 0: "a", 1: "b", length: 2 }) // ["a", "b"] Array.prototype.slice.call(document.querySelectorAll("div")); Array.prototype.slice.call(arguments);8. splice()
splice() 方法是一個多功能方法,根據(jù)參數(shù)的不同可以插入、刪除、替換元素,返回值是被刪除的元素組成的數(shù)組。
該方法會直接改變原數(shù)組。
arr.splice(start, count, addElement1, addElement2, ...);
參數(shù)
a. arr.splice(start) 1個參數(shù)是拆分,等同于將原數(shù)組在指定位置拆分成兩個數(shù)組。刪除下標(biāo)之后的全部值。包含 start 。
let arr = ["a", "b", "c", "d", "e", "f"]; arr.splice(3) // ["d", "e", "f"] arr // ["a", "b", "c"]
b. arr.splice(start, count) 2個參數(shù)是刪除,第二個參數(shù)是刪除的個數(shù),相當(dāng)于從 start 開始,刪除第二個參數(shù)指定的元素個數(shù)。
let arr = ["a", "b", "c", "d", "e", "f"]; arr.splice(4, 2) // ["e", "f"] 下標(biāo) 4 開始刪除 2 項(xiàng) arr // ["a", "b", "c", "d"]
c. arr.splice(start, count, ...) 更多參數(shù)是替換,表示從 start 開始,刪除 count 項(xiàng),然后將后面的參數(shù)作為新元素插入原數(shù)組中,返回值是被刪除的元素。
let arr = ["a", "b", "c", "d", "e", "f"]; arr.splice(4, 2, 1, 2) // ["e", "f"] arr // ["a", "b", "c", "d", 1, 2]
d. arr.splice(start, 0, ...) 第二個參數(shù)為0時,表示插入,從 start 開始,刪除 0 項(xiàng),并在 start 之前添加新元素。返回空數(shù)組。
let arr = ["a", "b", "c", "d"]; arr.splice(2, 0, 1, 2) // [] arr // ["a", "b", 1, 2, "c", "d"]
e. arr.splice(-start, ...) 起始位置 start 如果是負(fù)數(shù),就表示從倒數(shù)位置開始進(jìn)行相關(guān)操作。
let arr = ["a", "b", "c", "d"]; arr.splice(-2, 2) // ["c", "d"]9. sort()
sort() 方法對數(shù)組成員進(jìn)行排序,默認(rèn)按照字符順序排序,會將數(shù)字隱式轉(zhuǎn)換為字符串排序。直接返回改變后的原數(shù)組。
該方法會直接改變原數(shù)組。
let arr = ["d", "c", "b", "a"]; arr.sort() // ["a", "b", "c", "d"] arr // ["a", "b", "c", "d"]
會將數(shù)字隱式轉(zhuǎn)換為字符串排序。
let arr=[2,3,45,12,78,67,155] arr.sort() // [12, 155, 2, 3, 45, 67, 78]
自定義排序,可以傳入一個函數(shù)作為參數(shù)。
let arr=[2,3,45,12,78,67,155] arr.sort(function(a,b){ return a-b }) // [2, 3, 12, 45, 67, 78, 155]
sort 的參數(shù)函數(shù)本身接受兩個參數(shù) a 和 b,表示進(jìn)行比較的兩個數(shù)組成員。如果該函數(shù)的返回值 >0,那么 b 排在 a 的前面;=0,位置不變;<0, a 排到 b 的前面。
[{ name: "張三", age: 30 }, { name: "李四", age: 24 }, { name: "王五", age: 22 } ].sort(function (o1, o2) { console.log(o1.age, o2.age); return o1.age - o2.age; }) // 30 24 // 30 22 // 24 22 // [ // { name: "李四", age: 22 }, // { name: "王五", age: 24 }, // { name: "張三", age: 30 } // ]
由上述例子可以看出 sort() 自定義排序參數(shù)傳入的原理,第一次 30 和 24 相比,24 在前,30 在后,排序結(jié)果為 (24,30,22);第二次 30 和 22 相比,22 在前,30 在后,排序結(jié)果為 (24,22,30);第三次用來確定調(diào)換了位置的 30 和 22 中的排序在前的 22 和前一個 24 相比哪個更小,最終排序結(jié)果為 (22,24,30)。
由此可以看出排序的原理,如果位置不變,則依次向后做比較;一旦位置發(fā)生變化,則排列在前的元素會與上一個元素做比較,依次向前直到位置不變?yōu)橹梗俳又鴱陌l(fā)生變化的位置開始依次向后做比較。
應(yīng)用:可以讓一個數(shù)組隨機(jī)亂序。
var arr = [1,2,3,4,5,6,7,8,9,10]; arr.sort(function(){ return Math.random() - 0.5; })10. map()
map() 方法將數(shù)組的所有成員依次傳入?yún)?shù)函數(shù),然后把每一次的執(zhí)行結(jié)果組成一個新數(shù)組返回。
該方法不改變原數(shù)組。
let numbers = [1, 2, 3]; numbers.map(function (n) { return n + 1; }); // [2, 3, 4] numbers // [1, 2, 3]
map() 方法接受一個函數(shù)作為參數(shù)。該函數(shù)調(diào)用時,map方法向它傳入三個參數(shù):第一個為當(dāng)前進(jìn)入函數(shù)的數(shù)組元素,第二個為當(dāng)前元素的下標(biāo),第三個為原始數(shù)組。只有第一個是必須的。
[1, 2, 3].map(function(elem, index, arr) { return elem * index; }); // [0, 2, 6]
如果數(shù)組有空位,map() 方法的回調(diào)函數(shù)在這個位置不會執(zhí)行,會跳過數(shù)組的空位。但不會跳過 undefined 和 null。
let f = function (n) { return "a" }; [1, undefined, 2].map(f) // ["a", "a", "a"] [1, null, 2].map(f) // ["a", "a", "a"] [1, , 2].map(f) // ["a", , "a"]
map() 方法還可以接受第二個參數(shù),用來綁定回調(diào)函數(shù)內(nèi)部的 this 變量
let arr = ["a", "b", "c"]; [1, 2].map(function (e) { return this[e]; }, arr) // ["b", "c"]11. forEach()
forEach() 方法與 map() 方法很相似,也是對數(shù)組的所有成員依次執(zhí)行參數(shù)函數(shù)。但是,forEach() 方法不返回值,只用來操作數(shù)據(jù)。這就是說,如果數(shù)組遍歷的目的是為了得到返回值,那么使用 map() 方法,否則使用 forEach() 方法。
forEach() 的用法與 map() 方法一致,參數(shù)是一個函數(shù),該函數(shù)同樣接受三個參數(shù):當(dāng)前元素、當(dāng)前下標(biāo)、整個數(shù)組。同樣也會跳過數(shù)組的空位。但不會跳過 undefined 和 null。
var log = function (n) { console.log(n + 1); }; [1, undefined, 2].forEach(log) // 2 // NaN // 3 [1, null, 2].forEach(log) // 2 // 1 // 3 [1, , 2].forEach(log) // 2 // 3
forEach() 方法也可以接受第二個參數(shù),綁定參數(shù)函數(shù)的 this 變量。
let out = []; [1, 2, 3].forEach(function(elem) { this.push(elem * elem); }, out); out // [1, 4, 9]
注意,forEach() 方法無法中斷執(zhí)行,總是會將所有成員遍歷完。如果希望符合某種條件時,就中斷遍歷,要使用 for 循環(huán)。
let arr = [1, 2, 3]; for (let i = 0; i < arr.length; i++) { if (arr[i] === 2) break; console.log(arr[i]); } // 112. filter()
filter() 方法用于過濾數(shù)組成員,滿足條件的成員組成一個新數(shù)組返回。它的參數(shù)是一個函數(shù),所有數(shù)組成員依次執(zhí)行該函數(shù),返回結(jié)果為 true 的成員組成一個新數(shù)組返回。
該方法不改變原數(shù)組。
[1, 2, 3, 4, 5].filter(function (elem) { return (elem > 3); }) // [4, 5] let arr = [0, 1, "a", false]; arr.filter(Boolean) // [1, "a"]
filter() 方法的參數(shù)函數(shù)可以接受三個參數(shù):當(dāng)前元素、當(dāng)前下標(biāo)、整個數(shù)組。
[1, 2, 3, 4, 5].filter(function (elem, index, arr) { return index % 2 === 0; }); // [1, 3, 5]
filter() 方法還可以接受第二個參數(shù),用來綁定參數(shù)函數(shù)內(nèi)部的 this 變量。
let obj = { MAX: 3 }; let myFilter = function (item) { if (item > this.MAX) return true; }; let arr = [2, 8, 3, 4, 1, 3, 2, 9]; arr.filter(myFilter, obj) // [8, 4, 9]13. some(),every()
這兩個方法類似“斷言”(assert),返回一個布爾值,表示判斷數(shù)組成員是否符合某種條件。
它們接受一個函數(shù)作為參數(shù),所有數(shù)組成員依次執(zhí)行該函數(shù)。該函數(shù)接受三個參數(shù):當(dāng)前元素、當(dāng)前下標(biāo)和整個數(shù)組。然后返回一個布爾值。
some() 方法是只要一個成員的返回值是 true,則整個 some() 方法的返回值就是 true,否則返回 false。
let arr = [1, 2, 3, 4, 5]; arr.some(function (elem, index, arr) { return elem >= 3; }); // true
every() 方法是所有成員的返回值都是 true,整個every() 方法才返回 true,否則返回 false。
let arr = [1, 2, 3, 4, 5]; arr.every(function (elem, index, arr) { return elem >= 3; }); // false
注意,對于空數(shù)組,some() 方法返回 false,every() 方法返回 true,回調(diào)函數(shù)都不會執(zhí)行。
function isEven(x) { return x % 2 === 0 } [].some(isEven) // false [].every(isEven) // true
some() 和 every() 方法還可以接受第二個參數(shù),用來綁定參數(shù)函數(shù)內(nèi)部的 this 變量。
14. reduce(),reduceRight()reduce() 方法和 reduceRight() 方法依次處理數(shù)組的每個成員,最終累計為一個值。它們的差別是,reduce 是從左到右處理(從第一個元素到最后一個元素),reduceRight 則是從右到左(從最后一個元素到第一個元素),其他完全一樣。
[1, 2, 3, 4, 5].reduce(function (a, b) { console.log(a, b); return a + b; }) // 15 // 1 2 // 3 3 // 6 4 // 10 5
reduce() 方法和 reduceRight() 方法的第一個參數(shù)都是一個函數(shù)。該函數(shù)接受以下四個參數(shù)。前兩個是必須的,后兩個是可選的。
累積變量,依次為上一輪的返回值,初始值默認(rèn)為數(shù)組的第一個元素,可通過參數(shù)傳入指定的初始變量。
當(dāng)前變量,默認(rèn)為數(shù)組的第二個元素,當(dāng)累積變量有指定初始值時,當(dāng)前變量為第一個元素。
當(dāng)前變量的下標(biāo),默認(rèn)為 1,當(dāng)累積變量有指定初始值時,下標(biāo)為 0。
原數(shù)組
reduce() 方法和 reduceRight() 方法的第二個參數(shù)是對累積變量指定初值。
[1, 2, 3, 4, 5].reduce(function (a, b) { return a + b; }, 10); // 25
指定累積變量相當(dāng)于設(shè)定了默認(rèn)值,對于處理空數(shù)組尤其有用。
function add(prev, cur) { return prev + cur; } [].reduce(add) // 報錯 [].reduce(add, 1) // 1 永遠(yuǎn)返回初始值,不會執(zhí)行函數(shù)
reduceRight() 是從右到左依次執(zhí)行函數(shù)。
function subtract(prev, cur) { return prev - cur; } [3, 2, 1].reduce(subtract) // 0 [3, 2, 1].reduceRight(subtract) // -4
應(yīng)用 由于這兩個方法會遍歷數(shù)組,所以實(shí)際上還可以用來做一些遍歷相關(guān)的操作。
找出字符長度最長的數(shù)組成員。
function findLongest(entries) { return entries.reduce(function (longest, entry) { return entry.length > longest.length ? entry : longest; }, ""); } findLongest(["aaa", "bb", "c"]) // "aaa"
將二維數(shù)組轉(zhuǎn)化為一維
[[0, 1], [2, 3], [4, 5]].reduce(function(a, b) { return a.concat(b); },[]) // [0, 1, 2, 3, 4, 5]
數(shù)組去重
let arr = [1,2,1,2,3,5,4,5,3,4,4,4,4]; let result = arr.sort().reduce((init, current)=>{ if(init.length===0 || init[init.length-1]!==current){ init.push(current); } return init; }, []) //[1,2,3,4,5]
按屬性對object分類
let people = [ { name: "Alice", age: 21 }, { name: "Max", age: 20 }, { name: "Jane", age: 20 } ]; function groupBy(objectArray, property) { return objectArray.reduce(function (acc, obj) { let key = obj[property]; if (!acc[key]) { acc[key] = []; } acc[key].push(obj); return acc; }, {}); } groupBy(people, "age"); // { // 20: [ // { name: "Max", age: 20 }, // { name: "Jane", age: 20 } // ], // 21: [{ name: "Alice", age: 21 }] // }
參考鏈接:Array.prototype.reduce()
15. indexOf(),lastIndexOf()indexOf() 方法返回參數(shù)在數(shù)組中第一次出現(xiàn)的位置,如果沒有出現(xiàn)則返回-1。
let arr = ["a", "b", "c"]; arr.indexOf("b") // 1 arr.indexOf("y") // -1
indexOf() 方法還可以接受第二個參數(shù),表示搜索的開始位置。
["a", "b", "c"].indexOf("a", 1) // -1
lastIndexOf() 方法返回參數(shù)在數(shù)組中最后一次出現(xiàn)的位置,如果沒有出現(xiàn)則返回-1。
let arr = [2, 5, 9, 2]; arr.lastIndexOf(2) // 3 arr.lastIndexOf(7) // -1
注意,這兩個方法不能用來搜索 NaN 的位置,即它們無法確定數(shù)組成員是否包含 NaN。這是因?yàn)檫@兩個方法內(nèi)部,使用嚴(yán)格相等運(yùn)算符(===)進(jìn)行比較,而 NaN 是唯一一個不等于自身的值。
[NaN].indexOf(NaN) // -1 [NaN].lastIndexOf(NaN) // -116. copyWithin()
copyWithin() 方法,在當(dāng)前數(shù)組內(nèi)部,將指定位置的成員復(fù)制到其他位置(會覆蓋原有成員),然后返回當(dāng)前數(shù)組。包含 start 不包含 end。
該方法會直接改變原數(shù)組。
Array.prototype.copyWithin(target, start, end)
接受三個參數(shù):
target(必需):從該位置開始替換數(shù)據(jù)。如果為負(fù)值,表示倒數(shù)。
start(可選):從該位置開始讀取數(shù)據(jù),默認(rèn)為 0。如果為負(fù)值,表示倒數(shù)。
end(可選):到該位置前停止讀取數(shù)據(jù),默認(rèn)等于數(shù)組長度。如果為負(fù)值,表示倒數(shù)。
[1, 2, 3, 4, 5].copyWithin(0, 3) // [4, 5, 3, 4, 5]
上面代碼表示將從下標(biāo) 3 到數(shù)組結(jié)束的元素(4 和 5),復(fù)制到從下標(biāo) 0 開始的位置,結(jié)果覆蓋了原來的 1 和 2。
[1, 2, 3, 4, 5].copyWithin(0, 3, 4) // [4, 2, 3, 4, 5] [1, 2, 3, 4, 5].copyWithin(0, -2, -1) // [4, 2, 3, 4, 5] [].copyWithin.call({length: 5, 3: 1}, 0, 3) // {0: 1, 3: 1, length: 5}17. find(),findIndex()
find() 方法用于找出第一個符合條件的數(shù)組元素。它的參數(shù)是一個回調(diào)函數(shù),所有數(shù)組元素依次執(zhí)行該回調(diào)函數(shù),直到找出第一個返回值為 true 的元素,然后返回該元素。如果沒有符合條件的元素,則返回 undefined。
[1, 4, -5, 10].find((n) => n < 0) // -5
find() 方法的回調(diào)函數(shù)可以接受三個參數(shù),依次為當(dāng)前元素、當(dāng)前下標(biāo)和原數(shù)組。
[1, 5, 10, 15].find(function(value, index, arr) { return value > 9; }) // 10
findIndex() 方法的用法與 find() 方法非常類似,返回第一個符合條件的數(shù)組元素的位置,如果所有元素都不符合條件,則返回 -1。
[1, 5, 10, 15].findIndex(function(value, index, arr) { return value > 9; }) // 2
這兩個方法都可以接受第二個參數(shù),用來綁定回調(diào)函數(shù)的 this 對象。
function f(v){ return v > this.age; } let person = {name: "John", age: 20}; [10, 12, 26, 15].find(f, person); // 26
另外,這兩個方法都可以可以借助 Object.is() 方法識別數(shù)組的 NaN,彌補(bǔ)了 indexOf() 方法的不足。
[NaN].indexOf(NaN) // -1 [NaN].findIndex(y => Object.is(NaN, y)) // 018. fill()
fill() 方法使用給定值,填充一個數(shù)組。
["a", "b", "c"].fill(7) // [7, 7, 7] new Array(3).fill(7) // [7, 7, 7]
fill() 方法還可以接受第二個和第三個參數(shù),用于指定填充的起始位置和結(jié)束位置。
["a", "b", "c"].fill(7, 1, 2) // ["a", 7, "c"]
注意,如果填充的類型為對象,那么被賦值的是同一個內(nèi)存地址的對象,而不是深拷貝對象。
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]]19. includes()
includes() 方法返回一個布爾值,表示某個數(shù)組是否包含給定的值,與字符串的includes() 方法類似。
[1, 2, 3].includes(2) // true [1, 2, 3].includes(4) // false [1, 2, NaN].includes(NaN) // true
該方法的第二個參數(shù)表示搜索的起始位置,默認(rèn)為0。如果第二個參數(shù)為負(fù)數(shù),則表示倒數(shù)的位置,如果這時它大于數(shù)組長度(比如第二個參數(shù)為-4,但數(shù)組長度為3),則會重置為從0開始。
[1, 2, 3].includes(3, 3); // false [1, 2, 3].includes(3, -1); // true
沒有該方法之前,我們通常使用數(shù)組的 indexOf() 方法,檢查是否包含某個值。
if (arr.indexOf(el) !== -1) { // ... }
indexOf() 方法內(nèi)部使用嚴(yán)格相等運(yùn)算符(===)進(jìn)行判斷,這會導(dǎo)致對 NaN 的誤判。includes() 使用的是不一樣的判斷算法,就沒有這個問題。
[NaN].indexOf(NaN) // -1 [NaN].includes(NaN) // true20. flat(),flatMap()
flat() 用于將多維數(shù)組變成一維數(shù)組。返回一個新數(shù)組。
該方法不改變原數(shù)組。
[1, 2, [3, 4]].flat() // [1, 2, 3, 4]
flat() 默認(rèn)只會“拉平”一層,如果想要“拉平”多層的嵌套數(shù)組,可以將 flat() 方法的參數(shù)寫成一個整數(shù),表示想要拉平的層數(shù),默認(rèn)為 1。
[1, 2, [3, [4, 5]]].flat() // [1, 2, 3, [4, 5]] [1, 2, [3, [4, 5]]].flat(2) // [1, 2, 3, 4, 5]
如果不管有多少層嵌套,都要轉(zhuǎn)成一維數(shù)組,可以用 Infinity 關(guān)鍵字作為參數(shù)。
[1, [2, [3]]].flat(Infinity) // [1, 2, 3]
如果原數(shù)組有空位,flat() 方法會跳過空位。
[1, 2, , 4, 5].flat() // [1, 2, 4, 5]
flatMap() 方法對原數(shù)組的每個元素執(zhí)行一個函數(shù)(相當(dāng)于執(zhí)行Array.prototype.map()),然后對返回值組成的數(shù)組執(zhí)行 flat() 方法。返回新數(shù)組。
該方法不改變原數(shù)組。
[2, 3, 4].flatMap((x) => [x, x * 2]) // [2, 4, 3, 6, 4, 8] // 相當(dāng)于 [[2, 4], [3, 6], [4, 8]].flat()
flatMap() 只能展開一層數(shù)組。
[1, 2, 3, 4].flatMap(x => [[x * 2]]) // [[2], [4], [6], [8]] // 相當(dāng)于 [[[2]], [[4]], [[6]], [[8]]].flat()
flatMap() 方法的參數(shù)是一個遍歷函數(shù),該函數(shù)可以接受三個參數(shù),分別是當(dāng)前數(shù)組元素、當(dāng)前數(shù)組元素的下標(biāo)(從零開始)、原數(shù)組。
flatMap() 方法還可以有第二個參數(shù),用來綁定遍歷函數(shù)里面的 this。
arr.flatMap(function callback(currentValue[, index[, array]]) { // ... }[, thisArg])鏈?zhǔn)绞褂?/b>
上面這些數(shù)組方法之中,有不少返回的還是數(shù)組,所以可以鏈?zhǔn)绞褂谩?/p>
var users = [ {name: "tom", email: "tom@example.com"}, {name: "peter", email: "peter@example.com"} ]; users .map(function (user) { return user.email; }) .filter(function (email) { return /^t/.test(email); }) .forEach(function (email) { console.log(email); }); // "tom@example.com"
參考鏈接:
Array對象
數(shù)組的擴(kuò)展
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/108951.html
摘要:數(shù)組學(xué)習(xí)記錄是的實(shí)例屬性。對數(shù)組元素進(jìn)行排序,并返回當(dāng)前數(shù)組。返回一個由所有數(shù)組元素組合而成的字符串。為數(shù)組中的每個元素執(zhí)行一次回調(diào)函數(shù)。返回一個數(shù)組迭代器對象,該迭代器會包含所有數(shù)組元素的鍵值對。 JavaScript數(shù)組學(xué)習(xí)記錄 Array.length Array.length 是Array的實(shí)例屬性。返回或設(shè)置一個數(shù)組中的元素個數(shù)。該值是一個無符號 32-bit 整數(shù),并且總是...
摘要:由一個問題引發(fā)的思考這個方法是從哪兒蹦出來的首先我們要清楚數(shù)組也是對象,而且是對象的實(shí)例也就是說,下面兩種形式是完全等價的只不過是一種字面量的寫法,在深入淺出面向?qū)ο蠛驮透拍钇恼吕铮覀兲岬竭^類會有一個屬性,而這個類的實(shí)例可以通過屬性訪 1.由一個問題引發(fā)的思考 let arr1 = [1, 2, 3] let arr2 = [4, 5, 6] arr1.c...
摘要:參數(shù)待檢查的已整理過的數(shù)組待計算的值每次迭代執(zhí)行的函數(shù)綁定的返回返回在中應(yīng)該插入的索引位置示例使用迭代器函數(shù)使用回調(diào)函數(shù)簡稱該方法類似,但其返回的是插入的最大的索引位置。 Lodash 中文文檔 (v3.10.1) - Array 方法 Translated by PeckZegOriginal Docs: Lodash v3.10.1 Docs 更新日志 2015-01-02 感謝 ...
摘要:總結(jié)使用訪問數(shù)組元素,使用訪問數(shù)組屬性,如。數(shù)組的長度保證大于每個元素的索引值,數(shù)組沒有元素,最大索引為,為為數(shù)組元素賦值,如果其索引大于等于現(xiàn)有數(shù)組長度,的屬性值將設(shè)置為如果設(shè)置的值小于數(shù)組長度時,會將索引大于的元素全部刪除。 數(shù)組 數(shù)組是值的有序集合,數(shù)組中每個值稱為元素,元素在數(shù)組中的位置稱為索引。JavaScript中的數(shù)組是一種特殊的對象: 類屬性class attribu...
摘要:自定義類的概述自定義類的概述代碼映射成現(xiàn)實(shí)事物的過程就是定義類的過程。自定義類的格式自定義類的格式使用類的形式對現(xiàn)實(shí)中的事物進(jìn)行描述。 01引用數(shù)據(jù)類型_類 * A: 數(shù)據(jù)類型 * a: java中的數(shù)據(jù)類型分為:基本類型和引用類型 * B: 引用類型的分類 * a: Java為我們提供好的類,比如說:Scanner,Random等。 * b: 我們自己創(chuàng)建的類...
摘要:常用的屬性和方法創(chuàng)建空創(chuàng)建給對象添加屬性給對象添加多個屬性給對象添加給對象添加返回屬性配置對象返回所有屬性名數(shù)組返回對象原型對象阻止對象擴(kuò)展凍結(jié)對象密封對象檢測是否可擴(kuò)展布爾值檢測是否凍結(jié)布爾值檢測是否密封布爾值對象原型對象對象實(shí)例的屬性和 常用Object的屬性和方法 創(chuàng)建空Object var o1 = {}; var o2 = Object.create(Object.prot...
閱讀 1566·2021-09-22 15:52
閱讀 3472·2021-09-22 14:59
閱讀 2852·2021-09-02 15:12
閱讀 980·2021-08-20 09:35
閱讀 1585·2019-08-30 14:09
閱讀 2717·2019-08-30 13:56
閱讀 1656·2019-08-26 18:27
閱讀 3370·2019-08-26 13:37