摘要:如果數(shù)組已經(jīng)為空,則不改變數(shù)組,并返回值。中所有在數(shù)組被修改時都遵從這個原則,以下不再重復方法會給原數(shù)組中的每個元素都按順序調(diào)用一次函數(shù)。每次執(zhí)行后的返回值沒有指定返回值則返回組合起來
1 ES3中的數(shù)組方法數(shù)組應該是我們在寫程序中應用到最多的數(shù)據(jù)結(jié)構(gòu)了,相比于無序的對象,有序的數(shù)組幫我們在處理數(shù)據(jù)時,實在是幫了太多的忙了。今天剛好看到一篇Array.include的文章,忽然發(fā)現(xiàn)經(jīng)過幾個ES3,ES5,ES6,ES7幾個版本的更迭,發(fā)現(xiàn)在代碼中用到了好多數(shù)組的方法,所以準備全部列出來,也是給自己加深印象
ES3兼容現(xiàn)在所有主流瀏覽器
ES3中的方法毫無疑問大家已經(jīng)爛熟在心了,不過中間有些細節(jié)可以回顧加深一下記憶,比如是否修改原數(shù)組返回新數(shù)組,執(zhí)行方法之后的返回值是什么,某些參數(shù)的意義是否搞混等等。熟悉的的可以直接快速瀏覽或者跳過。
1.1 join()方法Array.join()方法是將一個數(shù)組里面的所有元素轉(zhuǎn)換成字符串,然后再將他們連接起來返回一個新數(shù)組。可以傳入一個可選的字符串來分隔結(jié)果字符串中的所有元素。如果沒有指定分隔字符串,就默認使用逗號分隔。
let a = [1,2,3,4,5,6,7]; let b = a.join(); // b = "1,2,3,4,5,6,7"; let c = a.a.join(" "); // b = "1 2 3 4 5 6 7";
1.2 reverse()方法方法Array.join()恰好與String.split()相反,后者是通過將一個字符串分隔成幾個元素來創(chuàng)建數(shù)組
Array.reverse()方法將顛倒數(shù)組中元素的順序并返回一個顛倒后的數(shù)組。它在原數(shù)組上執(zhí)行這一操作,所以說并不是創(chuàng)建了一個新數(shù)組,而是在已存在的數(shù)組中對元素進行重排。
let a = [1,2,3,4,5,6,7]; a.reverse(); // a = [7,6,5,4,3,2,1]1.3 sort()方法
Array.sort()是在原數(shù)組上進行排序,返回排序后的數(shù)組。如果調(diào)用方法時不傳入?yún)?shù),那么它將按照字母順序?qū)?shù)組元素進行排序,說得更精確點,是按照字符編碼的順序進行排序。要實現(xiàn)這一點,首先應把數(shù)組的元素都轉(zhuǎn)換成字符串(如有必要),以便進行比較。
如果數(shù)組中有未定義的元素,這些元素將放在數(shù)組的末尾
let a = [1,12,23,14,,undefined,null,NaN,56,6,7,"a",{},[]]; a.sort(); //[[], 1, 12, 14, 23, 56, 6, 7, "NaN", {}, "a", null,undefined,undefined × 1] //返回的NaN已經(jīng)是一個字符串,說明在比較過程中將其轉(zhuǎn)化成了字符串進行比較
仔細看可以發(fā)現(xiàn),上面順序并沒有按照數(shù)字大小進行排序。如果想按照其他標準進行排序,就需要提供比較函數(shù)。該函數(shù)比較前后兩個值,然后返回一個用于說明這兩個值的相對順序的數(shù)字。比較函數(shù)應該具有兩個參數(shù) a 和 b,其返回值如下:
若 a 小于 b,在排序后的數(shù)組中 a 應該出現(xiàn)在 b 之前,則返回一個小于 0 的值。
若 a 等于 b,則返回 0。
若 a 大于 b,在排序后的數(shù)組中 a 應該出現(xiàn)在 b 之后,則返回一個大于 0 的值。
let a = [1,12,23,14,,undefined,null,NaN,56,6,7,"a",{},[]]; a.sort((a,b) => {return a - b}); //[null, Array(0), NaN, Object, 1, 6, 7, 12, 14, 23, 56, "a",undefined, undefined × 1]1.4 concat()方法
Array.concat() 方法用于連接兩個或多個參數(shù)(數(shù)組,字符串等),該方法不會改變現(xiàn)有的數(shù)組,而會返回連接多個參數(shù)的一個新數(shù)組。如果傳入的參數(shù)是數(shù)組,那么它將被展開,將元素添加到返回的數(shù)組中。但要注意,concat并不能遞歸的展開一個元素為數(shù)組的參數(shù)。
let a = [1,2,3]; let b = a.concat(4,5,[6,7,[9,10]]); // b = [1,2,3,4,5,6,7,[9,10]]];1.5 slice()方法
Array.slice() 方法可從已有的數(shù)組中返回指定的一個片段(slice),或者說是子數(shù)組。它是從原數(shù)組中截取了一個片段,并返回到了一個新數(shù)組。
Array.slice(a,b) 它有兩個參數(shù)a,b
參數(shù) | 描述 |
---|---|
a | 必選。規(guī)定從何處開始選取。如果是負數(shù),那么它規(guī)定從數(shù)組尾部開始算起的位置。也就是說,-1 指最后一個元素,-2 指倒數(shù)第二個元素,以此類推。 |
b | 可選。規(guī)定從何處結(jié)束選取。該參數(shù)是數(shù)組片斷結(jié)束處的數(shù)組下標。如果沒有指定該參數(shù),那么切分的數(shù)組包含從 start 到數(shù)組結(jié)束的所有元素。如果這個參數(shù)是負數(shù),那么它規(guī)定的是從數(shù)組尾部開始算起的元素。 |
let a = [1,2,3,4,5,7,8]; let b = a.slice(3); // [4, 5, 7, 8] let c = a.slice(3,5); // [4, 5] let d = a.slice(-5,-2); // [3, 4, 5] let d = a.slice(2,1); // []
請注意,該方法并不會修改數(shù)組,而是返回一個新的子數(shù)組。如果想刪除數(shù)組中的一段元素,應該使用下面這個方法 Array.splice()。
1.6 splice()方法Array.splice() 方法從數(shù)組中添加/刪除元素,然后返回被刪除的元素。它在原數(shù)組上修改數(shù)組,并不像slice和concat那樣創(chuàng)建新數(shù)組。注意,雖然splice和slice名字非常相似,但是執(zhí)行的卻是完全不同的操作。
參數(shù) | 描述 |
---|---|
index | 必選,整數(shù)。規(guī)定添加/刪除項目的位置,使用負數(shù)可從數(shù)組結(jié)尾處倒著尋找位置。 |
howmany | 可選,整數(shù)。要刪除的元素數(shù)量。如果設置為 0,則不會刪除元素。如果沒有選擇,則默認從index開始到數(shù)組結(jié)束的所有元素 |
item1, ..., itemX | 可選。向數(shù)組添加新的元素。 |
let a = [1,2,3,4,5,7,8]; let b = a.splice(3); // a = [1,2,3] b = [4, 5, 7, 8] ----------------------------------------------------------- let c = [1,2,3,4,5,7,8]; let d = c.splice(3,5); // c = [1,2] d = [3,4,5,7,8] ----------------------------------------------------------- let e = [1,2,3,4,5,7,8]; let f = e.splice(3,2,111,222,[1,2]); // e = [1, 2, 3, 111, 222,[1,2], 7, 8] f = [4,5]
大家要記住slice()和splice()兩個方法第二個參數(shù)代表的意義是不一樣的。雖然這很基礎(chǔ),可是有時候還是會弄混。
1.7 push()和pop()方法Array.push() 方法可向數(shù)組的末尾添加一個或多個元素,并返回新的長度。
Array.pop()方法用于刪除并返回數(shù)組的最后一個元素。如果數(shù)組已經(jīng)為空,則 pop() 不改變數(shù)組,并返回 undefined 值。
let a = [1,2,3,4,5]; let b = a.pop(); //a = [1,2,3,4] b = 5 let c = a.push(1,3,5); // a = [1,2,3,4,1,3,5] c = 7
上面兩個方法都是直接對原數(shù)組進行操作。通過上面兩個方法可以實現(xiàn)一個先進后出的棧。
1.8 unshift和shift()方法unshift,shift()的方法行為和push(),pop()非常相似,只不過他們是對數(shù)組的頭部元素進行插入和刪除。
Array.unshift() 方法可向數(shù)組的頭部添加一個或多個元素,并返回新的長度。
Array.shift()方法用于刪除并返回數(shù)組的第一個元素。如果數(shù)組已經(jīng)為空,則 pop() 不改變數(shù)組,并返回 undefined 值。
let a = [1,2,3,4,5]; let b = a.shift(); //a = [2,3,4,5] b = 1 let c = a.unshift(1,3,5); // a = [1,3,5,2,3,45] c = 71.9 toString()和toLocaleString()方法
和所有javascript的對象一樣,數(shù)組也有toString()方法,這個方法可以將數(shù)組的每一個元素轉(zhuǎn)化成字符串(如果必要的話,就調(diào)用元素的toString()方法),然后輸出字符串的列表,字符串之間用逗號隔開。(用我的話來理解,其實就是遍歷數(shù)組元素調(diào)用每個元素自身的toString()方法,然后用逗號連接)
toString()的返回值和沒有參數(shù)的join()方法返回的字符串相同
let a = let e = [1,undefined,null,Boolean,{},[],function(){console.log(1);}]; let b = a.toString(); // b = "1,,,function Boolean() { [native code] },[object Object],,function (){console.log(1);}"
注意,輸出的結(jié)果中,返回的數(shù)組值周圍沒有括號。
toLocaleString方法是toString()方法的本地化版本。它是使用地區(qū)特定的分隔符把生成的字符串連接起來,形成一個字符串。
雖然是兩個方法,但是一般元素兩個方法的輸出結(jié)果卻基本是一樣的,去網(wǎng)上找了相關(guān)文章,發(fā)現(xiàn)只有兩種情況比較有區(qū)分,一個是時間,一個是4位數(shù)字以上的數(shù)字,舉例如下
let a = 1111; let b = a.toLocaleString(); // b = "1,111" let c = a.toString(); // c = "1111"; ------------------------------------------------------- let date = new Date(); let d = date.toString(); // d = "Sun Sep 03 2017 21:52:18 GMT+0800 (中國標準時間)" let e = date.toLocaleString(); //e = "2017/9/3 下午9:52:18"
好吧,這個api和數(shù)組關(guān)系不大。。。主要還是和數(shù)組中元素自身有關(guān)。啊哈哈,尷尬。
1.10 valueOf()Array.valueOf()方法在日常中用的比較少,該方法繼承與Object。javascript中許多內(nèi)置對象都針對自身重寫了該方法,數(shù)組Array.valueOf()直接返回自身。
let a = [1,"1",{},[]]; let b = a.valueOf(); a === b; // true
2 ES5中的數(shù)組方法好啦,關(guān)于ES3的方法就不詳細描述了,我相信大家基本上都已經(jīng)完全是爛熟于心的那種,唯一可能需要加強記憶的就是一些參數(shù)含義,返回數(shù)據(jù)這些了。
ES5中的數(shù)組方法在各大瀏覽器的兼容性
Opera 11+
Firefox 3.6+
Safari 5+
Chrome 8+
Internet Explorer 9+
2.Array在ES5新增的方法中接受兩個參數(shù),第一個參數(shù)都是function類型,必選,默認有傳參,這些參數(shù)分別是:
currentValue : 數(shù)組當前項的值
index : 數(shù)組當前項的索引
array : 數(shù)組對象本身
第二個參數(shù)是當執(zhí)行回調(diào)函數(shù)時指向的this(參考對象),不提供默認為window,嚴格模式下為undefined。
以forEach舉例
語法
array.forEach(callback, thisArg) array.forEach(callback(currentValue, index, array){ //do something }, thisArg)
例子:
//demo,注意this指向 //我這個demo沒有用箭頭函數(shù)來測試 let a = ["a", "b", "c"]; a.forEach(function(currentValue, index, array){ this.info(currentValue, index, array); },{info:function(value,index,array){ console.log(`當前值${value},下標${index},數(shù)組${array}`)} }); function info(value,index,array){ console.log(`外放方法 : 當前值${value},下標${index},數(shù)組${array}`)} } // 當前值a,下標0,數(shù)組a,b,c // 當前值b,下標1,數(shù)組a,b,c // 當前值c,下標2,數(shù)組a,b,c
3.ES5中的所有關(guān)于遍歷的方法按升序為數(shù)組中含有效值的每一項執(zhí)行一次callback函數(shù),那些已刪除(使用delete方法等情況)或者未初始化的項將被跳過(但不包括那些值為 undefined 的項)(例如在稀疏數(shù)組上)。
例子:數(shù)組哪些項被跳過了
function logArrayElements(element, index, array) { console.log(`a[${index}] = ${element}`); } let xxx; //定義未賦值 let a = [1,2,"", ,undefined,xxx,3]; delete a[1]; // 移除 2 a.forEach(logArrayElements); // a[0] = 1 // 注意索引1被跳過了,因為在數(shù)組的這個位置沒有項 被刪除了 // a[2] = "" // 注意索引3被跳過了,因為在數(shù)組的這個位置沒有項,可以理解成沒有被初始化 // a[4] = undefined // a[5] = undefined // a[6] = 3
好了,上面3點基本上是ES5中所有方法的共性,下面就不重復述說了。開始正文解析每個方法的不同了
2.1 forEach()Array.forEach() 為每個數(shù)組元素執(zhí)行callback函數(shù);不像map() 或者reduce() ,它總是返回 undefined值,并且不可鏈式調(diào)用。典型用例是在一個鏈的最后執(zhí)行副作用。
注意: 沒有辦法中止或者跳出 forEach 循環(huán),除了拋出一個異常。如果你需要跳出函數(shù),推薦使用Array.some。如果可以,新方法 find() 或者findIndex() 也可被用于真值測試的提早終止。
例子:如果數(shù)組在迭代時被修改了
下面的例子輸出"one", "two", "three"。當?shù)竭_包含值"two"的項時,整個數(shù)組添加了一個項在第一位,這導致所有的元素下移一個位置。此時在下次執(zhí)行回調(diào)中,因為元素 "two"符合條件,結(jié)果一直增加元素,直到遍歷次數(shù)完畢。forEach()不會在迭代之前創(chuàng)建數(shù)組的副本。
let a = ["one", "two", "three"]; let b = a.forEach((value,index,arr) => { if (value === "two") { a.unshift("zero"); } return "new" + value }); // one,0,["one", "two", "three"] // two,1,["one", "two", "three"] // two,2,["zero", "one", "two", "three"] // two,3,["zero","zero", "one", "two", "three"]
看完例子可以發(fā)現(xiàn),使用 forEach 方法處理數(shù)組時,數(shù)組元素的范圍是在callback方法第一次調(diào)用之前就已經(jīng)確定了。在 forEach 方法執(zhí)行的過程中:原數(shù)組中新增加的元素將不會被 callback 訪問到;若已經(jīng)存在的元素被改變或刪除了,則它們的傳遞到 callback 的值是 forEach 方法遍歷到它們的那一個索引時的值。
2.2 map()ES5中所有API在數(shù)組被修改時都遵從這個原則,以下不再重復
Array.map 方法會給原數(shù)組中的每個元素都按順序調(diào)用一次callback函數(shù)。callback每次執(zhí)行后的返回值(沒有指定返回值則返回undefined)組合起來形成一個新數(shù)組。
例子:返回每個元素的平方根的數(shù)組
let a = [1,4,9]; let b = a.map((value) => { return Math.sqrt(value); //如果沒有return,則默認返回undefined }); // b= [1,2,3]2.3 filter()
Array.filter()為數(shù)組中的每個元素調(diào)用一次 callback 函數(shù),并利用所有使得 callback 返回 true 或 等價于 true 的值 的元素創(chuàng)建一個新數(shù)組。那些沒有通過 callback 測試的元素會被跳過,不會被包含在新數(shù)組中
例子:數(shù)組去重
let a = [1,2,3,4,32,6,79,0,1,1,8]; let b = a.filter((value,index,arr) => { return arr.indexOf(value) === index; }); // b = [1, 2, 3, 4, 32, 6, 79, 0, 8]2.4 some()
Array.some 為數(shù)組中的每一個元素執(zhí)行一次 callback 函數(shù),直到找到一個使得 callback 返回一個“真值”(即可轉(zhuǎn)換為布爾值 true 的值)。如果找到了這樣一個值,some 將會立即返回 true。否則,some 返回 false。callback 只會在那些”有值“的索引上被調(diào)用,不會在那些被刪除或從來未被賦值的索引上調(diào)用。
例子:查看數(shù)組內(nèi)是否含有大于0的元素
let a = [-1,4,9]; let b = a.some((value) => { return value > 0; //如果沒有return,則默認返回undefined,將無法告訴some判斷 }); // b = true
2.5 every()some方法可以理解成擁有跳出功能的forEach()函數(shù),可以用在在一些需要中斷函數(shù)的地方
Array.every() 方法為數(shù)組中的每個元素執(zhí)行一次 callback 函數(shù),直到它找到一個使 callback 返回 false(表示可轉(zhuǎn)換為布爾值 false 的值)的元素。如果發(fā)現(xiàn)了一個這樣的元素,every 方法將會立即返回 false。否則,callback 為每一個元素返回 true,every 就會返回 true。callback 只會為那些已經(jīng)被賦值的索引調(diào)用。不會為那些被刪除或從來沒被賦值的索引調(diào)用。
例子:檢測所有數(shù)組元素的大小,是否都大于0
let a = [-1,4,9]; let b = a.every((value) => { return value > 0; //如果沒有return,則默認返回undefined }); // b = false2.6 indexOf()
Array.indexOf()使用嚴格相等(strict equality,即===)進行判斷searchElement與數(shù)組中包含的元素之間的關(guān)系。
Array.indexOf()提供了兩個參數(shù),第一個searchElement代表要查詢的元素,第二個代表fromIndex表示從哪個下標開始查找,默認為0。
語法
arr.indexOf(searchElement) arr.indexOf(searchElement, fromIndex = 0)
Array.indexOf()會返回首個被找到的元素在數(shù)組中的索引位置; 若沒有找到則返回 -1
例子:
let array = [2, 5, 9]; array.indexOf(2); // 0 array.indexOf(7); // -1 array.indexOf(9, 2); // 2 array.indexOf(2, -1); // -1 array.indexOf(2, -3); // 02.7 lastIndexOf()
Array.lastIndexOf()就不細說了,其實從名字大家也可以看出來,indexOf是正向順序查找,lastIndexOf是反向從尾部開始查找,但是返回的索引下標仍然是正向的順序索引
。
語法
arr.lastIndexOf(searchElement, fromIndex = arr.length - 1)
需要注意的是,只是查找的方向相反,fromIndex和返回的索引都是正向順序的,千萬不要搞混了(感覺我這么一說,大家可能搞混了,捂臉)。
例子:各種情況下的的indexOf
var array = [2, 5, 9, 2]; var index = array.lastIndexOf(2); // index = 3 index = array.lastIndexOf(7); // index = -1 index = array.lastIndexOf(2, 3); // index = 3 index = array.lastIndexOf(2, 2); // index = 0 index = array.lastIndexOf(2, -2); // index = 0 index = array.lastIndexOf(2, -1); // index = 32.8 reduce()
Array.reduce() 為數(shù)組中的每一個元素依次執(zhí)行回調(diào)函數(shù),最后返回一個函數(shù)累計處理的結(jié)果。
語法
array.reduce(function(accumulator, currentValue, currentIndex, array), initialValue)
reduce的回調(diào)函數(shù)中的參數(shù)與前面的不同,多了第一個參數(shù),是上一次的返回值
accumulator : 上一次調(diào)用回調(diào)返回的值,或者是提供的初始值(initialValue)
currentValue : 數(shù)組當前項的值
currentIndex : 數(shù)據(jù)當前項的索引。第一次遍歷時,如果提供了 initialValue ,從0開始;否則從1開始
array : 調(diào)用 reduce 的數(shù)組
initialValue : 可選項,其值用于第一次調(diào)用 callback 的第一個參數(shù)。如果沒有設置初始值,則將數(shù)組中的第一個元素作為初始值。空數(shù)組調(diào)用reduce時沒有設置初始值將會報錯。
例子:數(shù)組求和
let sum = [0, 1, 2, 3].reduce(function (o,n) { return o + n; }); // sum = 6
對了,當回調(diào)函數(shù)第一次執(zhí)行時,accumulator 和 currentValue 的取值有兩種情況:
調(diào)用 reduce 時提供initialValue,accumulator 取值為 initialValue ,currentValue 取數(shù)組中的第一個值;
沒有提供 initialValue ,accumulator 取數(shù)組中的第一個值,currentValue 取數(shù)組中的第二個值。
例子:reduce數(shù)組去重
[1,2,3,4,5,6,78,4,3,2,21,1].reduce(function(accumulator,currentValue){ if(accumulator.indexOf(currentValue) > -1){ return accumulator; }else{ accumulator.push(currentValue); return accumulator; } },[])
2.9 reduceRight()方法注意 :如果數(shù)組為空并且沒有提供initialValue, 會拋出TypeError 。如果數(shù)組僅有一個元素并且沒有提供initialValue, 或者有提供initialValue但是數(shù)組為空,那么此唯一值將被返回并且callback不會被執(zhí)行。
Array.reduceRight() 為數(shù)組中的每一個元素依次執(zhí)行回調(diào)函數(shù),方向相反,從右到左,最后返回一個函數(shù)累計處理的結(jié)果。
因為這個方法和reduce方法基本是一模一樣的,除了方法相反,所以就不詳細的再寫一遍了
2.10 isArray()方法之所以將這個方法放在最后,是因為這個方法和前面的不太一致,是用于確定傳遞的值是否是一個 Array,使用方法也很簡單
例子
let a = Array.isArray([1,2,3]); //true let b = Array.isArray(document.getElementsByTagName("body")); //類數(shù)組也為false
不過感覺除非是臨時判斷,不然一般也不會用這個方法去判斷,一般還是下面這種萬金油型的吧。
Object.prototype.toString.call([]).slice(8, -1) === "Array";//true
3 ES6中的數(shù)組方法好啦,關(guān)于ES5的方法基本上就講到這里了,感覺自己在深入去看了一些文章之后,還是有一些額外的收獲的。比如對reduce這個平時不常用的方法了解更加深刻了,感覺之前很多遍歷收集數(shù)據(jù)的場景其實用reduce更加方便。
3.1 ...方法——concat方法的增強不同于es5主要以遍歷方法為主,es6的方法是各式各樣的,不過必須要說一句,在性能上,es6的效率基本上是最低的。
英文名字叫做Spread syntax,中文名字叫做擴展運算符。這個方法我不知道怎么描述,感覺更像是原有concat()方法的增強,可以配合著解構(gòu)一起使用,大家還是直接看例子感受以下吧
例子:簡單拷貝數(shù)組
//如果是ES5 let c = [7,8,9].concat(a); //如果是ES6 let a = [1,23,4,5,6]; let b = [7,8,9,...a]; // b = [7, 8, 9, 1, 23, 4, 5, 6] ---------------------------------------------------------- //淺拷貝 let c = [{a : 1}]; let d = [...c] d[0].a = 2 c[0].a // 2
可以看到這個方法對于引用類型仍然是淺復制,所以對于數(shù)組的深拷貝還是需要用額外的方法,可以看我另外一篇文章
3.2 of()方法Array.of()方法可以將傳入?yún)?shù)以順序的方式返回成一個新數(shù)組的元素。
let a = Array.of(1, 2, 3); // a = [1, 2, 3]
其實,剛看到這個api和他的用途,還是比較懵逼的,因為看上去這個方法就是直接將傳入的參數(shù)變成一個數(shù)組之外,就沒有任何區(qū)別了,那么我為什么不直接用以前的寫法去實現(xiàn)類似的效果呢,比如 let = [1,2,3];而且看上去也更加直接。然后我去翻了下最新的ECMAScript草案,其中有這么一句話
The of function is an intentionally generic factory method; it does not require that its this value be the Array constructor. Therefore it can be transferred to or inherited by other constructors that may be called with a single numeric argument.
自己理解了一下,其實大概意思就是說為了彌補Array構(gòu)造函數(shù)傳入單個函數(shù)的不足,所以出了一個of這個更加通用的方法,舉個例子
let a = new Array(1);//a = [undefined × 1] let b = new Array(1,2);// b = [1,2]
大家可以注意到傳入一個參數(shù)和傳入兩個參數(shù)的結(jié)果,完全是不一樣的,這就很尷尬了。而為了避免這種尷尬,es6則出了一種通用的of方法,不管你傳入了幾個參數(shù),都是一種相同類型的輸出結(jié)果。
不過我好奇的是,如果只傳入幾個參數(shù),為什么不直接let a = [1,2,3];效率和直觀性也更加的高。如果要創(chuàng)建一個長度的數(shù)組,我肯定還是選let a = new Array(10000),這種形式,實在沒有感覺到Array.of的實用場景,希望大家可以給我點指導。
3.2 from()方法Array.from()方法從一個類似數(shù)組(擁有一個 length 屬性和若干索引屬性的任意對象)或可迭代的對象(String, Array, Map, Set和 Generator)中創(chuàng)建一個新的數(shù)組實例。
我們先查看Array.from()的語法
語法
Array.from(arrayLike, mapFn, thisArg)
從語法中,我們可以看出Array.from()最基本的功能是將一個類數(shù)組的對象轉(zhuǎn)化成數(shù)組,然后通過第二個和第三個參數(shù)可以對轉(zhuǎn)化成功后的數(shù)組再次執(zhí)行一次遍歷數(shù)據(jù)map方法,也就是Array.from(obj).map(mapFn, thisArg)。
對了額外說一句,這個方法的性能很差,和直接的for循環(huán)的性能對比了一下,差了百倍不止。
例子 :將一串數(shù)字字符串轉(zhuǎn)化為數(shù)組
let a = Array.from("242365463432",(value) => return value * 2); //a = [4, 8, 4, 6, 12, 10, 8, 12, 6, 8, 6, 4]3.4 copyWithin()方法
Array.copyWithin方法,在當前數(shù)組內(nèi)部,將指定位置的成員淺復制到其他位置(會覆蓋原有成員),然后返回當前數(shù)組。也就是說,使用這個方法,會修改當前數(shù)組。
這個方法有點復雜,光看描述可能大家未必能輕易理解,大家可以先看下語法,再看demo配合理解,而且自己沒有想到這個方法合適的應用場景。網(wǎng)上也沒又看到相關(guān)使用場景。但是講道理,這個方法設計出來,肯定是經(jīng)過深思熟慮的,如果大家有想到,歡迎評論給我,謝謝。
語法
arr.copyWithin(target, start, end) //arr.copyWithin(目標索引, 源開始索引, 結(jié)束源索引)
例子
// 將3-4號位復制到0號位 [1, 2, 3, 4, 5].copyWithin(0, 3, 4); // [4, 2, 3, 4, 5] // 將2-5號位復制到0號位 [1, 2, 3, 4, 5].copyWithin(0, 2, 5); //[3, 4, 5, 4, 5] // 將1-4號位復制到4號位 [1, 2, 3, 4, 5].copyWithin(4, 1, 4); //[1, 2, 3, 4, 2]
復制遵循含頭不含尾原則
第一個是常規(guī)的例子,大家可以對比看第二個可以發(fā)現(xiàn),這個方法是先淺復制了數(shù)組一部分暫時存儲起來,然后再從目標索引處開始一個個覆蓋后面的元素,直到這段復制的數(shù)組片段全部粘貼完。
再看第三個例子,可以發(fā)現(xiàn)當復制的數(shù)據(jù)片段從目標索引開始粘貼時,如果超過了長度,它將停止粘貼,這說明它不會改變數(shù)據(jù)的 length,但是會改變數(shù)據(jù)本身的內(nèi)容。
Array.copyWithin可以理解成復制以及粘貼序列這兩者是為一體的操作;即使復制和粘貼區(qū)域重疊,粘貼的序列也會有拷貝來的值。
3.5 find() 和 findIndex()方法Array.find()方法返回數(shù)組中滿足提供的測試函數(shù)的第一個元素的值。否則返回 undefined。
Array.findIndex() 方法返回數(shù)組中滿足提供的測試函數(shù)的第一個元素的值的索引。否則返回 -1。
這兩個方法其實使用非常相似,使用場景有點像ES5中Array.some,都是在找到第一個滿足條件的時候,跳出循環(huán),區(qū)別的是,三種返回的值完全不一樣,我想這也許是為什么要在ES6中增加這兩個API的原因吧,可以理解成是數(shù)組的方法的補足。
例子:三個方法各自的返回值
let a = [1,2,3,4,5].find((item)=>{return item > 3}); // a = 4 返回第一個符合結(jié)果的值 let b = [1,2,3,4,5].findIndex((item)=>{return item > 3}); // b = 3 返回第一個符合結(jié)果的下標 let c = [1,2,3,4,5].some((item)=>{return item > 3}); // c = true 返回是否有符合條件的Boolean值 -----------------不滿足條件-------------------- let a = [1,2,3,4,5].find((item)=>{return item > 6}); // a = undefined let b = [1,2,3,4,5].findIndex((item)=>{return item > 6}); // b = -1 let c = [1,2,3,4,5].some((item)=>{return item > 6}); // c = false
注意:find()和findIndex()方法無法判斷NaN,可以說是內(nèi)部用 ===判斷,不同于ES7中的include方法。不過這個判斷方式是另外一個話題,不在本文詳述了,感興趣的同學可以去查一下。
其實還可以發(fā)現(xiàn),Array.find() 方法只是返回第一個符合條件的元素,它的增強版是es5中Array.filter()方法,返回所有符合條件的元素到一個新數(shù)組中。可以說是當用find方法時考慮跟多的是跳出吧。
我感覺這4個方法配合相應的回調(diào)函數(shù)基本上可以完全覆蓋大多數(shù)需要數(shù)組判斷的場景了,大家覺得呢?
3.5 fill方法Array.fill()方法用一個固定值填充一個數(shù)組中從起始索引到終止索引內(nèi)的全部元素,返回原數(shù)組
這個方法的使用也非常簡單,大家基本上看個語法和demo就能懂了。需要注意的是,這個方法是返回數(shù)組本身,還有一點就是,類數(shù)組不能調(diào)用這個方法,剛剛自己去改了MDN上面的文檔。
語法
arr.fill(value) arr.fill(value, startIndex) arr.fill(value, startIndex, endIndex)
例子
let a = new Array(10); a.fill(1); // a = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; let b = [1,2,34,5,6,7,8].fill(3,4); //b = [1, 2, 34, 5, 3, 3, 3]; let c = [1,2,34,5,6,7,8].fill(3,2,5); // c = [1, 2, 3, 3, 3, 7, 8];
3.6 entries(),keys(),values()方法個人感覺這個方法初始化數(shù)組挺有用的,自己每次測試數(shù)據(jù)時,只要new Array(10000).fill(1),比以前遍歷直觀方便多了
Array.entries()將數(shù)組轉(zhuǎn)化成一個中包含每個索引的鍵/值對的Array Iterator對象
Array.keys()將數(shù)組轉(zhuǎn)化成一個中包含每個索引的鍵的Array Iterator對象
Array.values()將數(shù)組轉(zhuǎn)化成一個中包含每個索引的值的Array Iterator對象。
Array.values()方法chrome瀏覽器并不支持,
之所以將這三個方法放在一起是有原因的額,大家可以看這三個方法其實都是一個數(shù)組轉(zhuǎn)化為一種新的數(shù)據(jù)類型——返回新的Array Iterator對象,唯一區(qū)別的是轉(zhuǎn)化之后的元素不一樣。跟他們的名字一樣,entries()方法轉(zhuǎn)化為全部的鍵值對,key()方法轉(zhuǎn)化為鍵,value()保留值。
例子:觀察各個迭代器遍歷輸出的東西
Array.entries()
let a = [1,2,3].entries(); for(let i of a){console.log(i);} //[0, 1] //[1, 2] //[2, 3]
Array.keys()
let b = [1,2,3].keys(); for(let i of b){console.log(i);} //0 //1 //2
Array.values()
let c = [1,2,3].values(); for(let i of c){console.log(i);} //1 //2 //3
4 ES7中的數(shù)組方法 4.1 includes()方法關(guān)于迭代器這個東西,自己說不上什么,因為自己沒有親自用過,如果大家有什么見解課可以評論給我,我來補充和學習一下
Array.includes方法返回一個布爾值,表示某個數(shù)組是否包含給定的值,如果包含,則返回true,否則返回false,與字符串的includes方法類似。
這個方法大家可以看作是ES5中Array.indexOf的語義增強版,“includes”這個是否包含的意思,直接返回Boolean值,比起原來的indexOf是否大于-1,顯得更加直觀,我就是判斷有沒有包含哪個值
語法,使用方法和indexof一模一樣
arr.includes(searchElement) arr.includes(searchElement, fromIndex)
例子
let array = [2, 5, 9]; array.includes(2); // true array.includes(7); // false array.includes(9, 2); // true array.includes(2, -1); // false array.includes(2, -3); // true
方法還真是tmd多啊,感覺基本上應該是更新完了,前后兩星期花了我4天時間吧,還是挺累的。不過收貨還是很多,比如知道了ES5的方法基本上都有第二個this指向的參數(shù),重新認識了reduce方法,感覺自己之前很多場景用reduce更好,重新熟悉了一些ES6的方法可以試用有些場景
如果能看到最后的,感覺你也是夠累的,哈哈哈。
既然這么累,點顆星吧
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/88489.html
摘要:不幸的是,這種方法在中失效,因為他們從中錯誤的去掉了第一個空成員。假設競走的比賽結(jié)果需要保存到數(shù)組中。目的就是將競賽者與他們的記錄時間交替的放在數(shù)組中。結(jié)論我希望我列出的這幾條應用足以說明與是最佳搭檔。 原文地址:http://javascriptweblog.wordpress.com/2010/11/08/javascripts-dream-team-in-praise-of-sp...
摘要:我想自己可以嘗試一下寫一個低配版的模塊加載器來應付一下我這個單頁網(wǎng)站,當然只是大致模仿了主要功能。是這樣處理的模塊依賴,同時依賴,這種情況下的模塊函數(shù)被調(diào)用時,被傳入的是,所以需要自己在里面手動一下。 Contents 前言 回顧RequireJs的基本用法 實現(xiàn)原理 使用方法 總結(jié) 前言 前段時間一直想用單頁開發(fā)技術(shù)寫一個自己的個人網(wǎng)站(使用es2015),寫了一部分之后,發(fā)現(xiàn)單...
摘要:它的關(guān)鍵能力,是模塊及依賴管理。其次,保持局部變量風格。我們很習慣通過和這樣的全局變量來訪問這樣的庫,但如果使用,它們都應只作為局部變量這里的就只存在于這個文件的代碼范圍內(nèi)獨立的作用域。 引言 1. manually 以前,我新開一個網(wǎng)頁項目,然后想到要用jQuery,我會打開瀏覽器,然后找到jQuery的官方網(wǎng)站,點擊那個醒目的Download jQuery按鈕,下載到.js文件,然...
摘要:有時候你寫一個方法,里面一堆循環(huán),循環(huán)里一堆自己看看都覺得死了其實人家自帶的方法已經(jīng)寫了,你用一下就好了。好了,撩一張圖。 有時候你寫一個方法,里面一堆for循環(huán),for循環(huán)里一堆if else自己看看都覺得low死了其實人家js自帶的方法已經(jīng)寫了,你用一下就好了。 因為我寫erp的么,然后就會用到金額,金額的話一般保留兩位小數(shù),然后用千分位顯示,你打算怎么寫,先用小數(shù)點區(qū)分小數(shù)位和整...
摘要:模塊化編程首先,我想說說模塊化編程這個概念當我不清楚這個概念的時候,其實說什么模塊化編程多好多好都是懵逼的而我一直不覺得有多好,其實也是因為我從開始寫,就一直都在模塊化編程啊我們寫一個文件然后我們在文件中引入然后調(diào)用方法哈哈這樣已經(jīng)是模塊化 模塊化編程 首先,我想說說模塊化編程這個概念當我不清楚這個概念的時候,其實說什么模塊化編程多好多好都是懵逼的而我一直不覺得有多好,其實也是因為我從...
閱讀 890·2021-10-25 09:44
閱讀 1262·2021-09-23 11:56
閱讀 1183·2021-09-10 10:50
閱讀 3131·2019-08-30 15:53
閱讀 2134·2019-08-30 13:17
閱讀 617·2019-08-29 18:43
閱讀 2491·2019-08-29 12:57
閱讀 855·2019-08-26 12:20