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