1. 程式人生 > >JavaScript 陣列方法總結

JavaScript 陣列方法總結

內建方法(Array.*)

from (將其他遍歷物件轉換為陣列)

Array.from() 方法從一個類似陣列或可迭代的物件中建立一個新的陣列例項。

描述

Array.from() 允許你從下面兩者來建立陣列:

  • 類陣列物件(擁有一個 length 屬性和若干索引屬性的任意物件)
  • 可遍歷物件(你可以從它身上迭代出若干個元素的物件,比如有 Map 和 Set 等)

Array.from() 方法有一個可選引數 mapFn,讓你可以在最後生成的陣列上再執行一次 map 方法後再返回。也就是說 Array.from(obj, mapFn, thisArg) 就相當於 Array.from(obj).map(mapFn, thisArg), 除非建立的不是可用的中間陣列。 這對一些陣列的子類,如 typed arrays 來說很重要, 因為中間陣列的值在呼叫 map() 時需要是適當的型別。

from() 的 length 屬性為 1 。

在 ES2015 中, Class 語法允許我們為內建型別(比如 Array)和自定義類新建子類(比如叫 SubArray)。這些子類也會繼承父類的靜態方法,比如 SubArray.from(),呼叫該方法後會返回子類 SubArray 的一個例項,而不是 Array 的例項。

語法

Array.from(arrayLike[, mapFn[, thisArg]])

引數
arrayLike: 陣列/ 類陣列,如 Array, Map, Set , weakMap等;

mapFn (可選):可選引數,如果指定了該引數,則最後生成的陣列會經過該函式的加工處理後再返回。

thisArg (可選):可選引數,執行 mapFn 函式時 this 的值。

返回值
一個新的 Array 例項

Array from a String

Array.from('foo'); 
// ["f", "o", "o"]

Array from a Set

let s = new Set(['foo', window]); 
Array.from(s); 
// ["foo", window]
Array from a Map
let m = new Map([[1, 2], [2, 4], [4, 8]]);
Array.from(m); 
// [[1, 2], [2, 4], [4, 8]]

Array from an Array-like object (arguments)

function f() {
  return Array.from(arguments);
}

f(1, 2, 3);

// [1, 2, 3]

Using arrow functions and Array.from

// Using an arrow function as the map function to
// manipulate the elements
Array.from([1, 2, 3], x => x + x);      
// [2, 4, 6]


// Generate a sequence of numbers
// Since the array is initialized with `undefined` on each position,
// the value of `v` below will be `undefined`
Array.from({length: 5}, (v, i) => i);
// [0, 1, 2, 3, 4]

規範

>= ES6


isArray(判斷是否陣列)

Array.isArray() 用於確定傳遞的值是否是一個 Array

描述
如果物件是 Array ,則返回true,否則為false。
有關更多詳細資訊,請參閱文章嚴格判定JavaScript物件是否為陣列

語法

Array.isArray(obj)

引數
obj: 需要檢測的值

Return
物件是Array 則為true,否則為false。

instanceof 和 isArray
當檢測Array例項時, Array.isArray 優於 instanceof,因為Array.isArray能檢測iframes.

var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
xArray = window.frames[window.frames.length-1].Array;
var arr = new xArray(1,2,3); // [1,2,3]

// Correctly checking for Array
Array.isArray(arr);  // true
// Considered harmful, because doesn't work though iframes
arr instanceof Array; // false

Example

// 下面的函式呼叫都返回 true
Array.isArray([]);
Array.isArray([1]);
Array.isArray(new Array());
// 鮮為人知的事實:其實 Array.prototype 也是一個數組。
Array.isArray(Array.prototype); 

// 下面的函式呼叫都返回 false
Array.isArray();
Array.isArray({});
Array.isArray(null);
Array.isArray(undefined);
Array.isArray(17);
Array.isArray('Array');
Array.isArray(true);
Array.isArray(false);
Array.isArray({ __proto__: Array.prototype });

規範
>= ES5


of(建立陣列)

Array.of() 方法建立一個具有可變數量引數的新陣列例項,而不考慮引數的數量或型別。

Array.of() 和 Array 建構函式之間的區別在於處理整數引數:Array.of(7) 建立一個具有單個元素 7 的陣列,而 Array(7) 建立一個包含 7 個 undefined 元素的陣列。

Array.of(7);       // [7] 
Array.of(1, 2, 3); // [1, 2, 3]

Array(7);          // [ , , , , , , ]
Array(1, 2, 3);    // [1, 2, 3]

描述
此函式是ECMAScript 2015標準的一部分。詳見 Array.of 和 Array.from proposalArray.of polyfill

語法

Array.of(element0[, element1[, …[, elementN]]])

引數
elementN
任意個引數,將按順序成為返回陣列中的元素。

返回值
新的 Array 例項。

example

Array.of(1);         // [1]
Array.of(1, 2, 3);   // [1, 2, 3]
Array.of(undefined); // [undefined]

相容處理

if (!Array.of) {
  Array.of = function() {
    return Array.prototype.slice.call(arguments);
  };
}

規範

>= es6


原型方法(Array.prototype.*)

concat(合併陣列)

concat() 方法用於合併兩個或多個數組。此方法不會更改現有陣列,而是返回一個新陣列。

let arr1 = ["a", "b", "c"];
let arr2 = ["d", "e", "f"];

let arr3 = arr1.concat(arr2);

console.log(arr3);
// results in a new array 
// [ "a", "b", "c", "d", "e", "f" ]

console.log(arr1);
// ["a", "b", "c"]

console.log(arr2);
// ["d", "e", "f"]

描述
concat 方法將建立一個新的陣列,然後將呼叫它的物件(this 指向的物件)中的元素以及所有引數中的陣列型別的引數中的元素以及非陣列型別的引數本身按照順序放入這個新陣列,並返回該陣列.

concat 方法並不修改呼叫它的物件(this 指向的物件) 和引數中的各個陣列本身的值,而是將他們的每個元素拷貝一份放在組合成的新陣列中.原陣列中的元素有兩種被拷貝的方式:

  • 物件引用(非物件直接量):concat 方法會複製物件引用放到組合的新數組裡,原陣列和新陣列中的物件引用都指向同一個實際的物件,所以,當實際的物件被修改時,兩個陣列也同時會被修改.
  • 字串和數字(是原始值,而不是包裝原始值的 String 和 Number 物件): concat 方法會複製字串和數字的值放到新數組裡.

語法

var new_array = old_array.concat(value1[, value2[, …[, valueN]]])

引數

valueN:需要與原數組合並的陣列或非陣列值。

Return

新的 Array 例項。

規範
>= es3


copyWithin(淺複製陣列內容)

copyWithin() 方法淺複製陣列的一部分到同一陣列中的另一個位置,並返回它,而不修改其大小。

描述
引數target,start和end 必須為整數。

如果start為負,則其指定的索引位置等同於length+start,length為陣列的長度。end也是如此。

copyWithin方法不要求其this值必須是一個數組物件;除此之外,copyWithin是一個可變方法,它可以改變this物件本身,並且返回它,而不僅僅是它的拷貝。

copyWithin 就像 C 和 C++ 的 memcpy 函式一樣,且它是用來移動 Array 或者 TypedArray 資料的一個高效能的方法。複製以及貼上序列這兩者是為一體的操作;即使複製和貼上區域重疊,貼上的序列也會有拷貝來的值。

copyWithin 函式是設計為通用的,其不要求其 this 值必須是一個數組物件。

The copyWithin 是一個可變方法,它不會改變 this 的 length,但是會改變 this 本身的內容,且需要時會建立新的屬性。

["alpha", "beta", "copy", "delta"].copyWithin(1, 2, 3);
// 0:"alpha" 1:"beta" 2:"copy" 3:"delta"
// ["alpha", "copy", "copy", "delta"]
// 0:"alpha" 1:"copy" 2:"copy" 3:"delta"

// target === 1:"beta"
// start === 2:"copy", 
// end === 3:"delta"

// 1:"beta" => 1:"copy"

['alpha', 'bravo', 'charlie', 'delta'].copyWithin(2, 0);

// results in ["alpha", "bravo", "alpha", "bravo"]

語法

arr.copyWithin(target)

arr.copyWithin(target, start)

arr.copyWithin(target, start, end)

arr.copyWithin(目標索引, [源開始索引], [結束源索引])

引數
target
0 為基底的索引,複製序列到該位置。如果是負數,target 將從末尾開始計算。
如果 target 大於等於 arr.length,將會不發生拷貝。如果 target 在 start 之後,複製的序列將被修改以符合 arr.length。

start
0 為基底的索引,開始複製元素的起始位置。如果是負數,start 將從末尾開始計算。
如果 start 被忽略,copyWithin 將會從0開始複製。

end
0 為基底的索引,開始複製元素的結束位置。copyWithin 將會拷貝到該位置,但不包括 end 這個位置的元素。如果是負數, end 將從末尾開始計算。
如果 end 被忽略,copyWithin 將會複製到 arr.length。

Return
改變了的陣列。

example

[1, 2, 3, 4, 5].copyWithin(-2);
// [1, 2, 3, 1, 2]

[1, 2, 3, 4, 5].copyWithin(0, 3);
// [4, 5, 3, 4, 5]

[1, 2, 3, 4, 5].copyWithin(0, 3, 4);
// [4, 2, 3, 4, 5]

[1, 2, 3, 4, 5].copyWithin(-2, -3, -1);
// [1, 2, 3, 3, 4]

[].copyWithin.call({length: 5, 3: 1}, 0, 3);
// {0: 1, 3: 1, length: 5}

// ES2015 Typed Arrays are subclasses of Array
var i32a = new Int32Array([1, 2, 3, 4, 5]);

i32a.copyWithin(0, 2);
// Int32Array [3, 4, 5, 4, 5]

// On platforms that are not yet ES2015 compliant: 
[].copyWithin.call(new Int32Array([1, 2, 3, 4, 5]), 0, 3, 4);
// Int32Array [4, 2, 3, 4, 5]

相容處理

if (!Array.prototype.copyWithin) {
  Array.prototype.copyWithin = function(target, start/*, end*/) {
    // Steps 1-2.
    if (this == null) {
      throw new TypeError('this is null or not defined');
    }

    var O = Object(this);

    // Steps 3-5.
    var len = O.length >>> 0;

    // Steps 6-8.
    var relativeTarget = target >> 0;

    var to = relativeTarget < 0 ?
      Math.max(len + relativeTarget, 0) :
      Math.min(relativeTarget, len);

    // Steps 9-11.
    var relativeStart = start >> 0;

    var from = relativeStart < 0 ?
      Math.max(len + relativeStart, 0) :
      Math.min(relativeStart, len);

    // Steps 12-14.
    var end = arguments[2];
    var relativeEnd = end === undefined ? len : end >> 0;

    var final = relativeEnd < 0 ?
      Math.max(len + relativeEnd, 0) :
      Math.min(relativeEnd, len);

    // Step 15.
    var count = Math.min(final - from, len - to);

    // Steps 16-17.
    var direction = 1;

    if (from < to && to < (from + count)) {
      direction = -1;
      from += count - 1;
      to += count - 1;
    }

    // Step 18.
    while (count > 0) {
      if (from in O) {
        O[to] = O[from];
      } else {
        delete O[to];
      }

      from += direction;
      to += direction;
      count--;
    }

    // Step 19.
    return O;
  };
}

規範

>=es6


entries(返回一個新的Array Iterator物件)

entries() 方法返回一個新的Array Iterator物件,該物件包含陣列中每個索引的鍵/值對。

var arr = ["a", "b", "c"];
var iterator = arr.entries();
// undefined

console.log(iterator);
// Array Iterator {}

console.log(iterator.next().value); 
// [0, "a"]
console.log(iterator.next().value); 
// [1, "b"]
console.log(iterator.next().value); 
// [2, "c"]

語法

arr.entries()

Return
一個新的 Array 迭代器物件。

example

var arr = ["a", "b", "c"];
var iterator = arr.entries();
// undefined

for (let e of iterator) {
    console.log(e);
}

// [0, "a"] 
// [1, "b"] 
// [2, "c"]

規範
>=es6


every(檢測是否所有元素都通過 檢測函式)

every() 方法測試陣列的所有元素是否都通過了指定函式的測試。

描述
every 方法為陣列中的每個元素執行一次 callback 函式,直到它找到一個使 callback 返回 false(表示可轉換為布林值 false 的值)的元素。如果發現了一個這樣的元素,every 方法將會立即返回 false。否則,callback 為每一個元素返回 true,every 就會返回 true。callback 只會為那些已經被賦值的索引呼叫。不會為那些被刪除或從來沒被賦值的索引呼叫。

callback 被呼叫時傳入三個引數:元素值,元素的索引,原陣列。

如果為 every 提供一個 thisArg 引數,在該引數為呼叫 callback 時的 this 值。如果省略該引數,則 callback 被呼叫時的 this 值,在非嚴格模式下為全域性物件,在嚴格模式下傳入 undefined。

every 不會改變原陣列。

every 遍歷的元素範圍在第一次呼叫 callback 之前就已確定了。在呼叫 every 之後新增到陣列中的元素不會被 callback 訪問到。如果陣列中存在的元素被更改,則他們傳入 callback 的值是 every 訪問到他們那一刻的值。那些被刪除的元素或從來未被賦值的元素將不會被訪問到。

every acts like the “for all” quantifier in mathematics. In particular, for an empty array, it returns true. (It is vacuously true that all elements of the empty set satisfy any given condition.)

語法

arr.every(callback[, thisArg])

引數

callback
用來測試每個元素的函式。

thisArg
執行 callback 時使用的 this 值。

Return
Boolean

example

function isBigEnough(element, index, array) {
  return (element >= 10);
}
var passed = [12, 5, 8, 130, 44].every(isBigEnough);
// passed is false
passed = [12, 54, 18, 130, 44].every(isBigEnough);
// passed is true

相容處理

if (!Array.prototype.every)
{
  Array.prototype.every = function(fun /*, thisArg */)
  {
    'use strict';

    if (this === void 0 || this === null)
      throw new TypeError();

    var t = Object(this);
    var len = t.length >>> 0;
    if (typeof fun !== 'function')
        throw new TypeError();

    var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
    for (var i = 0; i < len; i++)
    {
      if (i in t && !fun.call(thisArg, t[i], i, t))
        return false;
    }

    return true;
  };
}

規範
>= es5


fill(填充陣列)

fill() 方法用一個固定值填充一個數組中從起始索引到終止索引內的全部元素。

var numbers = [1, 2, 3]
numbers.fill(1);

// results in [1, 1, 1]

描述

具體要填充的元素區間是 [start, end) , 一個半開半閉區間.

fill 方法接受三個引數 value, start 以及 end. start 和 end 引數是可選的, 其預設值分別為 0 和 this 物件的 length 屬性值.

如果 start 是個負數, 則開始索引會被自動計算成為 length+start, 其中 length 是 this 物件的 length 屬性值. 如果 end 是個負數, 則結束索引會被自動計算成為 length+end.

fill 方法故意被設計成通用方法, 也就是說它不需要 this 值必須是個陣列物件, 類陣列物件也是可以呼叫該方法的 .

fill 方法是個可變方法, 它會改變呼叫它的 this 物件本身, 然後返回它, 而並不是返回一個副本.

語法

arr.fill(value)
arr.fill(value, start)
arr.fill(value, start, end)

引數

value
用來填充陣列元素的值。

start 可選
起始索引,預設值為0。

end 可選
終止索引,預設值為 this.length。

Return
修改後的陣列。

example

[1, 2, 3].fill(4)            // [4, 4, 4]
[1, 2, 3].fill(4, 1)         // [1, 4, 4]
[1, 2, 3].fill(4, 1, 2)      // [1, 4, 3]
[1, 2, 3].fill(4, 1, 1)      // [1, 2, 3]
[1, 2, 3].fill(4, -3, -2)    // [4, 2, 3]
[1, 2, 3].fill(4, NaN, NaN)  // [1, 2, 3]
Array(3).fill(4);            // [4, 4, 4]
[].fill.call({length: 3}, 4) // {0: 4, 1: 4, 2: 4, length: 3}

相容處理

if (!Array.prototype.fill) {
  Object.defineProperty(Array.prototype, 'fill', {
    value: function(value) {

      // Steps 1-2.
      if (this == null) {
        throw new TypeError('this is null or not defined');
      }

      var O = Object(this);

      // Steps 3-5.
      var len = O.length >>> 0;

      // Steps 6-7.
      var start = arguments[1];
      var relativeStart = start >> 0;

      // Step 8.
      var k = relativeStart < 0 ?
        Math.max(len + relativeStart, 0) :
        Math.min(relativeStart, len);

      // Steps 9-10.
      var end = arguments[2];
      var relativeEnd = end === undefined ?
        len : end >> 0;

      // Step 11.
      var final = relativeEnd < 0 ?
        Math.max(len + relativeEnd, 0) :
        Math.min(relativeEnd, len);

      // Step 12.
      while (k < final) {
        O[k] = value;
        k++;
      }

      // Step 13.
      return O;
    }
  });
}

規範

>=es6


filter(返回一個通過檢測函式的新陣列)

filter() 方法建立一個新陣列, 其包含通過所提供函式實現的測試的所有元素。

描述

filter 為陣列中的每個元素呼叫一次 callback 函式,並利用所有使得 callback 返回 true 或 等價於 true 的值 的元素建立一個新陣列。callback 只會在已經賦值的索引上被呼叫,對於那些已經被刪除或者從未被賦值的索引不會被呼叫。那些沒有通過 callback 測試的元素會被跳過,不會被包含在新陣列中。

callback 被呼叫時傳入三個引數:

  1. 元素的值
  2. 元素的索引
  3. 被遍歷的陣列

如果為 filter 提供一個 thisArg 引數,則它會被作為 callback 被呼叫時的 this 值。否則,callback 的 this 值在非嚴格模式下將是全域性物件,嚴格模式下為 undefined。
The thisvalue ultimately observable by callback is determined according to the usual rules for determining thethis seen by a function.

filter 不會改變原陣列。

filter 遍歷的元素範圍在第一次呼叫 callback 之前就已經確定了。在呼叫 filter 之後被新增到陣列中的元素不會被 filter 遍歷到。如果已經存在的元素被改變了,則他們傳入 callback 的值是 filter 遍歷到它們那一刻的值。被刪除或從來未被賦值的元素不會被遍歷到。

語法

var new_array = arr.filter(callback[, thisArg])

引數

callback
用來測試陣列的每個元素的函式。呼叫時使用引數 (element, index, array)。
返回true表示保留該元素(通過測試),false則不保留。

thisArg
可選。執行 callback 時的用於 this 的值。

Return
一個新的通過測試的元素的集合的陣列{Array}

example

function isBigEnough(element) {
  return element >= 10;
}
var filtered = [12, 5, 8, 130, 44].filter(isBigEnough);
// filtered is [12, 130, 44]

相容處理

if (!Array.prototype.filter)
{
  Array.prototype.filter = function(fun /* , thisArg*/)
  {
    "use strict";

    if (this === void 0 || this === null)
      throw new TypeError();

    var t = Object(this);
    var len = t.length >>> 0;
    if (typeof fun !== "function")
      throw new TypeError();

    var res = [];
    var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
    for (var i = 0; i < len; i++)
    {
      if (i in t)
      {
        var val = t[i];

        // NOTE: Technically this should Object.defineProperty at
        //       the next index, as push can be affected by
        //       properties on Object.prototype and Array.prototype.
        //       But that method's new, and collisions should be
        //       rare, so use the more-compatible alternative.
        if (fun.call(thisArg, val, i, t))
          res.push(val);
      }
    }

    return res;
  };
}

規範

>= es5


find(尋找某個條件的元素)

find() 方法返回陣列中滿足提供的測試函式的第一個元素的值。否則返回 undefined。

function isBigEnough(element) {
  return element >= 15;
}

[12, 5, 8, 130, 44].find(isBigEnough); // 130

另請參見 findIndex() 方法,它返回陣列中找到的元素的索引,而不是其值。

如果你需要找到一個元素的位置或者一個元素是否存在於陣列中,使用Array.prototype.indexOf()Array.prototype.includes()。

描述

find 方法對陣列中的每一項元素執行一次 callback 函式,直至有一個 callback 返回 true。當找到了這樣一個元素後,該方法會立即返回這個元素的值,否則返回 undefined。注意 callback 函式會為陣列中的每個索引呼叫即從 0 到 lengh - 1,而不僅僅是那些被賦值的索引,這意味著對於稀疏陣列來說,該方法的效率要低於那些只遍歷有值的索引的方法。

callback 函式帶有3個引數:當前元素的值、當前元素的索引,以及陣列本身。

如果提供了 thisArg 引數,那麼它將作為每次 callback 函式執行時的上下文物件,否則上下文物件為 undefined。

find 方法不會改變陣列。

在第一次呼叫 callback 函式時會確定元素的索引範圍,因此在 find 方法開始執行之後新增到陣列的新元素將不會被 callback 函式訪問到。如果陣列中一個尚未被callback函式訪問到的元素的值被callback函式所改變,那麼當callback函式訪問到它時,它的值是將是根據它在陣列中的索引所訪問到的當前值。被刪除的元素仍舊會被訪問到。

語法

arr.find(callback[, thisArg])

引數
callback
在陣列每一項上執行的函式,接收 3 個引數:

element
當前遍歷到的元素。

index
當前遍歷到的索引。

array
陣列本身。

thisArg 可選
可選,指定 callback 的 this 引數。

Return
當某個元素通過 callback 的測試時,返回陣列中的一個值,否則返回 undefined。

example
用物件的屬性查詢數組裡的物件

var inventory = [
    {name: 'apples', quantity: 2},
    {name: 'bananas', quantity: 0},
    {name: 'cherries', quantity: 5}
];

function findCherries(fruit) { 
    return fruit.name === 'cherries';
}

console.log(inventory.find(findCherries)); // { name: 'cherries', quantity: 5 }

尋找陣列中的質數

function isPrime(element, index, array) {
  var start = 2;
  while (start <= Math.sqrt(element)) {
    if (element % start++ < 1) {
      return false;
    }
  }
  return element > 1;
}

console.log([4, 6, 8, 12].find(isPrime)); // undefined, not found
console.log([4, 5, 8, 12].find(isPrime)); // 5

當在回撥中刪除陣列中的一個值時,當訪問到這個位置時,其傳入的值時 undefiend:

// Declare array with no element at index 2, 3 and 4
var a = [0,1,,,,5,6];

// Shows all indexes, not just those that have been assigned values
a.find(function(value, index) {
  console.log('Visited index ' + index + ' with value ' + value); 
});

// Shows all indexes, including deleted
a.find(function(value, index) {

  // Delete element 5 on first iteration
  if (index == 0) {
    console.log('Deleting a[5] with value ' + a[5]);
    delete a[5];
  }
  // Element 5 is still visited even though deleted
  console.log('Visited index ' + index + ' with value ' + value); 
});

相容處理

// https://tc39.github.io/ecma262/#sec-array.prototype.find
if (!Array.prototype.find) {
  Object.defineProperty(Array.prototype, 'find', {
    value: function(predicate) {
     // 1. Let O be ? ToObject(this value).
      if (this == null) {
        throw new TypeError('"this" is null or not defined');
      }

      var o = Object(this);

      // 2. Let len be ? ToLength(? Get(O, "length")).
      var len = o.length >>> 0;

      // 3. If IsCallable(predicate) is false, throw a TypeError exception.
      if (typeof predicate !== 'function') {
        throw new TypeError('predicate must be a function');
      }

      // 4. If thisArg was supplied, let T be thisArg; else let T be undefined.
      var thisArg = arguments[1];

      // 5. Let k be 0.
      var k = 0;

      // 6. Repeat, while k < len
      while (k < len) {
        // a. Let Pk be ! ToString(k).
        // b. Let kValue be ? Get(O, Pk).
        // c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)).
        // d. If testResult is true, return kValue.
        var kValue = o[k];
        if (predicate.call(thisArg, kValue, k, o)) {
          return kValue;
        }
        // e. Increase k by 1.
        k++;
      }

      // 7. Return undefined.
      return undefined;
    }
  });
}

規範
>=es6


findIndex(尋找符合檢測函式條件的元素下標)

findIndex()方法返回陣列中滿足提供的測試函式的第一個元素的索引。否則返回-1。

function isBigEnough(element) {
  return element >= 15;
}

[12, 5, 8, 130, 44].findIndex(isBigEnough); // 3

另請參見 find() 方法,它返回陣列中找到的元素的值,而不是其索引。

描述

findIndex() 方法對陣列中的每一個元素執行一次回撥函式直至有一個回撥函式返回真值 。如果找到了一個這樣的元素, 則 findIndex 將會立刻返回這個元素的索引。否則 findIndex 將會返回 -1。不像其他的陣列方法如some那樣,該方法的callback總是被呼叫,即使該索引在陣列中並不存在(譯者注:既對於被刪除或空位置的索引處仍然呼叫callback)。

回撥函式呼叫時有三個引數:元素的值,元素的索引,以及被遍歷的陣列。

如果一個 thisArg 引數被提供給 findIndex, 它將會被當作 this 使用在每次回撥函式被呼叫的時候。如果沒有被提供,將會使用undefined。

findIndex 不會修改所呼叫的陣列。

在第一次呼叫callback函式時會確定元素的索引範圍,因此在findIndex方法開始執行之後新增到陣列的新元素將不會被callback函式訪問到。如果陣列中一個尚未被callback函式訪問到的元素的值被callback函式所改變,那麼當callback函式訪問到它時,它的值是將是根據它在陣列中的索引所訪問到的當前值。被刪除的元素不會被訪問到。

語法

arr.findIndex(callback[, thisArg])

引數
callback
針對陣列中的每個元素, 都會執行該回調函式, 執行時會自動傳入下面三個引數:

element
當前元素.

index
當前元素的索引.

array
呼叫findIndex的陣列.

thisArg
可選的。執行 callback 時作為 this物件 的值.

example
示例1: 查詢陣列中首個質數元素的索引
下面的示例演示瞭如何查詢一個數組中首個質數元素的索引, 找不到則返回 -1.

function isPrime(element, index, array) {
    var start = 2;
    while (start <= Math.sqrt(element)) {
        if (element % start++ < 1) return false;
    }
    return (element > 1);
}

console.log( [4, 6, 8, 12].findIndex(isPrime) ); // -1, 沒找到質數元素
console.log( [4, 6, 7, 12].findIndex(isPrime) ); // 2

相容處理

if (!Array.prototype.findIndex) {
  Array.prototype.findIndex = function(predicate) {
    if (this === null) {
      throw new TypeError('Array.prototype.findIndex called on null or undefined');
    }
    if (typeof predicate !== 'function') {
      throw new TypeError('predicate must be a function');
    }
    var list = Object(this);
    var length = list.length >>> 0;
    var thisArg = arguments[1];
    var value;

    for (var i = 0; i < length; i++) {
      value = list[i];
      if (predicate.call(thisArg, value, i, list)) {
        return i;
      }
    }
    return -1;
  };
}

規範
>= es6


forEach(遍歷陣列,無法推出迴圈)

forEach() 方法對陣列的每個元素執行一次提供的函式。

let a = ['a', 'b', 'c'];

a.forEach(function(element) {
    console.log(element);
});

// a
// b
// c

描述

forEach 方法按升序為陣列中含有效值的每一項執行一次callback 函式,那些已刪除(使用delete方法等情況)或者未初始化的項將被跳過(但不包括那些值為 undefined 的項)(例如在稀疏陣列上)。

callback 函式會被依次傳入三個引數:

陣列當前項的值
陣列當前項的索引
陣列物件本身
如果給forEach傳遞了thisArg引數,當呼叫時,它將被傳給callback 函式,作為它的this值。否則,將會傳入 undefined 作為它的this值。callback函式最終可觀察到this值,這取決於 函式觀察到this的常用規則。

forEach 遍歷的範圍在第一次呼叫 callback 前就會確定。呼叫forEach 後新增到陣列中的項不會被 callback 訪問到。如果已經存在的值被改變,則傳遞給 callback 的值是 forEach 遍歷到他們那一刻的值。已刪除的項不會被遍歷到。如果已訪問的元素在迭代時被刪除了(例如使用 shift()) ,之後的元素將被跳過 - 參見下面的示例。

forEach() 為每個陣列元素執行callback函式;不像map() 或者reduce() ,它總是返回 undefined值,並且不可鏈式呼叫。典型用例是在一個鏈的最後執行副作用。

注意: 沒有辦法中止或者跳出 forEach 迴圈,除了丟擲一個異常。如果你需要這樣,使用forEach()方法是錯誤的,你可以用一個簡單的迴圈作為替代。如果您正在測試一個數組裡的元素是否符合某條件,且需要返回一個布林值,那麼可使用 Array.every 或 Array.some。如果可用,新方法 find() 或者findIndex() 也可被用於真值測試的提早終止。

語法

array.forEach(callback(currentValue, index, array){
    //do something
}, this)

array.forEach(callback[, thisArg])

引數
callback
為陣列中每個元素執行的函式,該函式接收三個引數:

currentValue(當前值)
陣列中正在處理的當前元素。

index(索引)
陣列中正在處理的當前元素的索引。

array
forEach()方法正在操作的陣列。

thisArg可選
可選引數。當執行回撥 函式時用作this的值(參考物件)。

Return
undefined.

example

打印出陣列的內容
下面的程式碼會為每一個數組元素輸出一行記錄:

function logArrayElements(element, index, array) {
    console.log("a[" + index + "] = " + element);
}

// 注意索引2被跳過了,因為在陣列的這個位置沒有項
[2, 5, ,9].forEach(logArrayElements);

// a[0] = 2
// a[1] = 5
// a[3] = 9

[2, 5,"" ,9].forEach(logArrayElements);
// a[0] = 2
// a[1] = 5
// a[2] = 
// a[3] = 9

[2, 5, undefined ,9].forEach(logArrayElements);
// a[0] = 2
// a[1] = 5
// a[2] = undefined
// a[3] = 9


let xxx;
// undefined

[2, 5, xxx ,9].forEach(logArrayElements);
// a[0] = 2
// a[1] = 5
// a[2] = undefined
// a[3] = 9

使用thisArg
舉個勉強的例子,從每個陣列中的元素值中更新一個物件的屬性:

function Counter() {
    this.sum = 0;
    this.count = 0;
}

Counter.prototype.add = function(array) {
    array.forEach(function(entry) {
        this.sum += entry;
        ++this.count;
    }, this);
    //console.log(this);
};

var obj = new Counter();
obj.add([1, 3, 5, 7]);

obj.count; 
// 4 === (1+1+1+1)
obj.sum;
// 16 === (1+3+5+7)

因為thisArg引數 (this) 傳給了forEach(),每次呼叫時,它都被傳給callback函式,作為它的this值。

注意:如果使用箭頭函式表示式傳入函式引數,thisArg 引數會被忽略,因為箭頭函式在詞法上綁定了this值。

物件複製函式
下面的程式碼會建立一個給定物件的副本。 建立物件的副本有不同的方法,以下是隻是一種方法,並解釋了Array.prototype.forEach() 是如何使用ECMAScript 5 Object.* 元屬性(meta property )函式工作的。

function copy(obj) {
  var copy = Object.create(Object.getPrototypeOf(obj));
  var propNames = Object.getOwnPropertyNames(obj);

  propNames.forEach(function(name) {
    var desc = Object.getOwnPropertyDescriptor(obj, name);
    Object.defineProperty(copy, name, desc);
  });

  return copy;
}

var obj1 = { a: 1, b: 2 };
var obj2 = copy(obj1); // obj2 looks like obj1 now

如果陣列在迭代時被修改了,則其他元素會被跳過。

下面的例子輸出”one”, “two”, “four”。當到達包含值”two”的項時,整個陣列的第一個項被移除了,這導致所有剩下的項上移一個位置。因為元素 “four”現在在陣列更前的位置,”three”會被跳過。 forEach()不會在迭代之前建立陣列的副本。

var words = ["one", "two", "three", "four"];
words.forEach(function(word) {
  console.log(word);
  if (word === "two") {
    words.shift();
  }
});
// one
// two
// four

相容處理

forEach 是在第五版本里被新增到 ECMA-262 標準的;這樣它可能在標準的其他實現中不存在,你可以在你呼叫 forEach 之前 插入下面的程式碼,在本地不支援的情況下使用 forEach()。該演算法是 ECMA-262 第5版中指定的演算法。演算法假定Object和TypeError擁有它們的初始值。callback.call 等價於Function.prototype.call()。

// Production steps of ECMA-262, Edition 5, 15.4.4.18
// Reference: http://es5.github.io/#x15.4.4.18
if (!Array.prototype.forEach) {

  Array.prototype.forEach = function(callback, thisArg) {

    var T, k;

    if (this == null) {
      throw new TypeError(' this is null or not defined');
    }

    // 1. Let O be the result of calling toObject() passing the
    // |this| value as the argument.
    var O = Object(this);

    // 2. Let lenValue be the result of calling the Get() internal
    // method of O with the argument "length".
    // 3. Let len be toUint32(lenValue).
    var len = O.length >>> 0;

    // 4. If isCallable(callback) is false, throw a TypeError exception. 
    // See: http://es5.github.com/#x9.11
    if (typeof callback !== "function") {
      throw new TypeError(callback + ' is not a function');
    }

    // 5. If thisArg was supplied, let T be thisArg; else let
    // T be undefined.
    if (arguments.length > 1) {
      T = thisArg;
    }

    // 6. Let k be 0
    k = 0;

    // 7. Repeat, while k < len
    while (k < len) {

      var kValue;

      // a. Let Pk be ToString(k).
      //    This is implicit for LHS operands of the in operator
      // b. Let kPresent be the result of calling the HasProperty
      //    internal method of O with argument Pk.
      //    This step can be combined with c
      // c. If kPresent is true, then
      if (k in O) {

        // i. Let kValue be the result of calling the Get internal
        // method of O with argument Pk.
        kValue = O[k];

        // ii. Call the Call internal method of callback with T as
        // the this value and argument list containing kValue, k, and O.
        callback.call(T, kValue, k, O);
      }
      // d. Increase k by 1.
      k++;
    }
    // 8. return undefined
  };
}

規範

>=es5


includes(是否包括指定的值)

傳送門

indexOf(搜尋是否有對應的值,返回下標)

傳送門

join(將陣列的所有元素連線到一個字串中,不改變原來陣列)

傳送門

keys(返回一個迭代器,包含陣列中的索引)

傳送門

lastIndexOf(逆向查詢元素下標)

傳送門

map(創造一個新陣列,該結果為函式返回的結果集合)

傳送門

pop(方法從陣列中刪除最後一個元素,並返回該元素的值)

傳送門

push(一個或多個元素新增到陣列的末尾,並返回陣列的新長度)

傳送門

reduce(累加器)

傳送門

reduceRight(反向累加器)

傳送門

reverse(反轉陣列)

傳送門

shift(刪除第一個元素)

傳送門

slice(方法返回一個從開始到結束(不包括結束)選擇的陣列的一部分淺拷貝到一個新陣列)

傳送門

some(陣列中元素是否通過函式測試)

傳送門

sort(排序,預設是按照unicode碼點)

傳送門

splice(刪除/新增陣列元素)

傳送門

unshift(新增一個或多個元素到陣列開頭)

傳送門

>=ES1標準方法

Array.concat
Array.join
Array.pop
Array.reverse
Array.push
Array.shift
Array.slice
Array.sort
Array.splice
Array.unshift

>=ES5標準方法

Array.isArray
Array.every
Array.filter
Array.forEach
Array.includes
Array.indexOf
Array.lastIndexOf
Array.map
Array.reduce
Array.reduceRight
Array.some

>=ES6標準方法

Array.from
Array.of
Array.copyWithin
Array.entries
Array.fill
Array.find
Array.findIndex
Array.keys

>=IE9相容方法

Array.isArray
Array.concat
Array.every
Array.filter
Array.forEach
Array.indexOf
Array.join
Array.lastIndexOf
Array.map
Array.pop
Array.push
Array.reverse
Array.shift
Array.slice
Array.some
Array.sort
Array.splice
Array.unshift

參考

mozilla官方文件