Javascripts數組原生方法集合

數組應該是咱們在寫程序中應用到最多的數據結構了,相比於無序的對象,有序的數組幫咱們在處理數據時,實在是幫了太多的忙了。今天恰好看到一篇Array.include的文章,突然發現通過幾個ES3,ES5,ES6,ES7幾個版本的更迭,發如今代碼中用到了好多數組的方法,因此準備所有列出來,也是給本身加深印象javascript

1 ES3中的數組方法

  • ES3兼容如今全部主流瀏覽器java

ES3中的方法毫無疑問你們已經爛熟在心了,不過中間有些細節能夠回顧加深一下記憶,好比是否修改原數組返回新數組,執行方法以後的返回值是什麼,某些參數的意義是否搞混等等。熟悉的的能夠直接快速瀏覽或者跳過。git

1.1 join()方法

Array.join()方法是將一個數組裏面的全部元素轉換成字符串,而後再將他們鏈接起來返回一個新數組。能夠傳入一個可選的字符串來分隔結果字符串中的全部元素。若是沒有指定分隔字符串,就默認使用逗號分隔。es6

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";

方法Array.join()剛好與String.split()相反,後者是經過將一個字符串分隔成幾個元素來建立數組github

1.2 reverse()方法

Array.reverse()方法將顛倒數組中元素的順序並返回一個顛倒後的數組。它在原數組上執行這一操做,因此說並非建立了一個新數組,而是在已存在的數組中對元素進行重排。chrome

let a  = [1,2,3,4,5,6,7];
a.reverse();    // a =  [7,6,5,4,3,2,1]

1.3 sort()方法

Array.sort()是在原數組上進行排序,返回排序後的數組。若是調用方法時不傳入參數,那麼它將按照字母順序對數組元素進行排序,說得更精確點,是按照字符編碼的順序進行排序。要實現這一點,首先應把數組的元素都轉換成字符串(若有必要),以便進行比較。api

若是數組中有未定義的元素,這些元素將放在數組的末尾數組

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 = 7

1.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

好啦,關於ES3的方法就不詳細描述了,我相信你們基本上都已經徹底是爛熟於心的那種,惟一可能須要增強記憶的就是一些參數含義,返回數據這些了。


2 ES5中的數組方法

  1. 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 方法遍歷到它們的那一個索引時的值。

ES5中全部API在數組被修改時都聽從這個原則,如下再也不重複

2.2 map()

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

some方法能夠理解成擁有跳出功能的forEach()函數,能夠用在在一些須要中斷函數的地方

2.5 every()

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 = false

2.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); // 0

2.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 = 3

2.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;
    }
},[])

注意 :若是數組爲空而且沒有提供initialValue, 會拋出TypeError 。若是數組僅有一個元素而且沒有提供initialValue, 或者有提供initialValue可是數組爲空,那麼此惟一值將被返回而且callback不會被執行。

2.9 reduceRight()方法

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

好啦,關於ES5的方法基本上就講到這裏了,感受本身在深刻去看了一些文章以後,仍是有一些額外的收穫的。好比對reduce這個平時不經常使用的方法瞭解更加深入了,感受以前不少遍歷收集數據的場景其實用reduce更加方便。


3 ES6中的數組方法

不一樣於es5主要以遍歷方法爲主,es6的方法是各式各樣的,不過必需要說一句,在性能上,es6的效率基本上是最低的。

3.1 ...方法——concat方法的加強

英文名字叫作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];

我的感受這個方法初始化數組挺有用的,本身每次測試數據時,只要new Array(10000).fill(1),比之前遍歷直觀方便多了

3.6 entries(),keys(),values()方法

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的方法能夠試用有些場景

若是能看到最後的,感受你也是夠累的,哈哈哈。
既然這麼累,點顆星吧

相關文章
相關標籤/搜索