JavaScript 数组方法总结

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hulk_oh/article/details/77505111

内置方法(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官方文档

猜你喜欢

转载自blog.csdn.net/hulk_oh/article/details/77505111