Array.prototype.entries

1. 语法

DANGER

arr.entries()

返回值:

一个新的 Array 迭代器对象。

2. 描述

entries() 方法返回一个新的 Array Iterator 对象,该对象包含数组中每个索引的键/值对。

个人在日常开发中常用场景:

  • 尚未使用过。

3. 示例

  • array iterator

    const arr = ['a', 'b', 'c'];
    const iterator = arr.entries();
    
    console.log(iterator); // Array Iterator {}
    
  • iterator.next

    const arr = ['a', 'b', 'c'];
    const iterator = arr.entries();
    
    console.log(iterator.next()); // Object { value: Array [0, "a"], done: false }
    console.log(iterator.next()); // Object { value: Array [1, "b"], done: false }
    console.log(iterator.next()); // Object { value: Array [2, "c"], done: false }
    console.log(iterator.next()); // Object { value: undefined, done: true }
    console.log(iterator.next()); // Object { value: undefined, done: true }
    
  • iterating with index and elements

    const a = ['a', 'b', 'c'];
    
    for (const [index, element] of a.entries()) {
      console.log(index, element);
    }
    
    // 0 'a' 
    // 1 'b' 
    // 2 'c'
    

Array.prototype.every

1. 语法

DANGER

arr.every(callback[, thisArg])

参数:

  • callback:回调函数;
    • element:当前值;
    • index:当前值的索引;
    • array:当前数组。
  • thisArg:执行 callback 时使用的 this 值。

返回值:

返回一个布尔值。

2. 描述

every() 方法为数组中的每个元素都执行一次 callback 函数,直到找到一个返回 false 的元素。如果找到一个这样的元素则立即返回 false,否则返回 true。

个人在日常开发中常用场景:

  • 多用于判断多种状态是否符合,传递给变量,交由 if 处理。

3. 示例

  • testing size of all array elements

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

    [12, 5, 8, 130, 44].every(x => x >= 10); // false
    [12, 54, 18, 130, 44].every(x => x >= 10); // true
    

Array.prototype.filter

1. 语法

DANGER

arr.filter(callback(element[, index[, array]])[, thisArg])

参数:

  • callback:回调函数;
    • element:当前值;
    • index:当前值的索引;
    • array:当前数组。
  • thisArg:执行 callback 时使用的 this 值。

返回值:

一个新的数组实例。

2. 描述

filter() 方法创建一个新数组, 其包含通过所提供函数实现的测试的所有元素。 通过回调函数返回 true 的元素会包含到新数组中。filter 遍历的元素范围在第一次调用 callback 时之前就已经确定了,之后添加元素不会被遍历到。

个人在日常开发中常用场景:

  • 所有需要被过滤的数据都会使用该方法。

3. 示例

  • filtering invalid values

    const arr = [1, 0, "", "2", false, undefined, null, {}, {a: "hi"}];
    arr.filter(a => a); // [1, "2", {  }, { a: "hi" }]
    
  • filtering out all small values

    function isBigEnough(value) {
      return value >= 10;
    }
    
    [12, 5, 8, 130, 44].filter(isBigEnough); // [12, 130, 44]
    
  • filtering invalid entries from JSON

    const arr = [
      { id: 15 },
      { id: -1 },
      { id: 0 },
      { id: 3 },
      { id: 12.2 },
      { },
      { id: null },
      { id: NaN },
      { id: 'undefined' }
    ];
    
    let invalidEntries = 0;
    
    function isNumber(obj) {
      return obj !== undefined && typeof(obj) === 'number' && !isNaN(obj);
    }
    
    function filterByID(item) {
      if (isNumber(item.id) && item.id !== 0) {
        return true;
      }
      invalidEntries++;
      return false;
    }
    
    arr.filter(filterByID);
    // Filtered Array [{ id: 15 }, { id: -1 }, { id: 3 }, { id: 12.2 }]
    //  invalidEntries 5
    
  • searching in array

    const fruits =  ['apple', 'banana', 'grapes', 'mango', 'orange'];
    
    function filterItems(arr, query) {
      return arr.filter(function(el) {
        return el.toLowerCase().indexOf(query.toLowerCase()) !== -1;
      });
    }
    
    filterItems(fruits, 'ap'); // ['apple', 'grapes']
    filterItems(fruits, 'an'); // ['banana', 'mango', 'orange']
    

Array.prototype.find

1. 语法

DANGER

arr.find(callback[, thisArg])

参数:

  • callback:回调函数;
    • element:当前值;
    • index:当前值的索引;
    • array:当前数组。
  • thisArg:执行 callback 时使用的 this 值。

返回值:

返回一个满足回调函数的值,否则返回 undefined。

2. 描述

描述即返回值。

个人在日常开发中常用场景:

  • 返回对象组成的数组中的对应对象。

3. 示例

  • find an object in an array by one of its properties

    const inventory = [
        {name: 'apples', quantity: 2},
        {name: 'bananas', quantity: 0},
        {name: 'cherries', quantity: 5}
    ];
    
    inventory.find(fruit => fruit.name === 'cherries'); //  { name: 'cherries', quantity: 5 }
    
  • find a prime number in an array

    function isPrime(element, index, array) {
      var start = 2;
      while (start <= Math.sqrt(element)) {
        if (element % start++ < 1) {
          return false;
        }
      }
      return element > 1;
    }
    
    [4, 6, 8, 12].find(isPrime); // undefined
    [4, 5, 8, 12].find(isPrime); // 5
    

Array.prototype.findIndex

1. 语法

DANGER

arr.findIndex(callback[, thisArg])

参数:

  • callback:回调函数;
    • element:当前值;
    • index:当前值的索引;
    • array:当前数组。
  • thisArg:执行 callback 时使用的 this 值。

返回值:

返回对应值的下标,否则返回 -1。

2. 描述

描述即返回值。

个人在日常开发中常用场景:

  • 较少使用该方法,首先考虑能否使用 includes,若不支持才会考虑该项。

3. 示例

参考 find 的示例即可。

Array.prototype.forEach

1. 语法

DANGER

arr.forEach(callback[, thisArg])

参数:

  • callback:回调函数;
    • currentValue:当前值;
    • index:当前值的索引;
    • array:当前数组。
  • thisArg:执行 callback 时使用的 this 值。

返回值:

undefined。

2. 描述

forEach 方法按升序为数组中含有效值的每一项执行一次 callback 函数,那些已删除或未初始化的项将被跳过(例如稀疏数组)。

如之前的方法一致,forEach 遍历的范围在第一次调用 callback 前就会确定。调用 callback 后添加到数组中的项不会被 callback 访问到。但是,如果已经存在的值被改变,则传递给 callback 的值是 forEach 遍历到它们那一刻的值。参见下方示例。

你无法终止跳出 forEach 循环,除了抛出一个异常。如果你需要这样做,使用 forEach 方法是错误的,请使用其余循环方法。

个人在日常开发中常用场景:

  • 所有使用 for 循环的场景(今天才改正过来……)。
  • 不需要终止 for 循环的场景。

3. 示例

  • no opeartion for uninitialized values(sparse arrays)

    // 跳过无效值
    const arraySparse = [1, 3,,7];
    let numCallbackRuns = 0;
    
    arraySparse.forEach(el => {
      console.log(el);
      // 1
    	// 3
    	// 7
      numCallbackRuns++;
    });
    
    console.log("numCallbackRuns: ", numCallbackRuns); // numCallbackRuns: 3
    
  • printing the contents of an array

    function logArrayElements(elements, index, array) {
      console.log('a[' + index + '] = ' + element);
    }
    [2, 5, , 9].forEach(logArrayElements);
    // a[0] = 2
    // a[1] = 5
    // a[3] = 9
    
  • using thisArg

    function Counter() {
      this.sum = 0;
      this.count = 0;
    }
    
    Counter.prototype.add = function(array) {
      array.forEach(entry => {
        this.sum += entry;
        ++this.count;
      }, this);
    }
    
    const obj = new Counter();
    obj.add([2, 5, 9]);
    obj.count;
    // 3 
    obj.sum;
    // 16
    
  • an object copy function

    function copy(obj) {
      const copy = Object.create(Object.getPrototypeOf(obj));
      const propNames = Object.getOwnPropertyNames(obj);
      
      propNames.forEach(name => {
        const desc = Object.getOwnPropertyDescriptor(obj, name);
        Object.defineProperty(copy, name, desc);
      });
      
      return copy;
    }
    
    const obj1 = { a: 1, b: 2 };
    const obj2 = copy(obj1); // obj2 looks like obj1 now
    
  • if the array is modified during iteration, other elements might be skipped

    let words = ['one', 'two', 'three', 'four'];
    words.forEach(word => {
      console.log(word);
      if (word === 'two') {
        words.shift();
      }
    });
    
    // one
    // two
    // four
    
  • flatten an array

    function flatten(arr) {
      const result = [];
      
      arr.forEach(i => {
        Array.isArray(i) ? result.push(...flatten(i)) : result.push(i);
      });
      
      return result;
    }
    
    const problem = [1, 2, 3, [4, 5, [6, 7], 8, 9]];
    flatten(problem); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
    

Array.prototype.keys

1. 语法

DANGER

arr.keys()

返回值:

一个新的 Array 迭代器对象。

2. 描述

keys() 方法返回一个包含数组中每个索引键的 Array Iterator 对象。

个人在日常开发中常用场景:

  • 尚未使用过。

3. 示例

  • key iterator doesn't ignore holes

    const arr = ['a', , 'c'];
    const sparseKeys = Object.keys(arr); // ['0', '2']
    const denseKeys = [...arr.keys()]; // [0, 1, 2]
    
  • generate an array of the specified length

    const specifiedArray = len => [...new Array(len).keys()];
    
    specifiedArray(4); // [0, 1, 2, 3]
    

Array.prototype.map

1. 语法

DANGER

arr.map(callback[, thisArg])

参数:

  • callback:回调函数;
    • currentValue:当前值;
    • index:当前值的索引;
    • array:当前数组。
  • thisArg:执行 callback 时使用的 this 值。

返回值:

一个新的数组,每个元素都是回调函数的结果。

2. 描述

描述即返回值。

个人在日常开发中常用场景:

  • 常用于映射修改后端传递的数据。

3. 示例

  • mapping an array of numbers to an array of square roots

    const numbers = [1, 4, 9];
    numbers.map(num => Math.sqrt(num)); // [1, 2, 3]
    
  • using map to reformat objects in an array

    const kvArray = [{key: 1, value: 10}, {key: 2, value: 20}, {key: 3, value: 30}];
    kvArray.map(obj =>  ({[obj.key]: obj.value})); // [{1: 10}, {2: 20}, {3: 30}]
    
  • mapping an array of numbers using a function containing an argument

    const numbers = [1, 4, 9];
    numbers.map(num => num * 2); // [2, 8, 18]
    
  • using map generically

    const map = Array.prototype.map;
    map.call('Hello World', x => x.charCodeAt(0)); // [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]
    
  • using map generically querySelectorAll

    const elems = document.querySelectorAll('select option:checked');
    Array.prototype.map.call(elems, obj => obj.value);
    
  • tricky use case

    ["1", "2", "3"].map(parseInt); // [1, NaN, NaN]
    
    
    function returnInt(element) {
      return parseInt(element, 10);
    }
    ['1', '2', '3'].map(returnInt); // [1, 2, 3]
    
  • mapping array have undefined

    const numbers = [1, 2, 3, 4];
    numbers.map((num, index) => {
    	if (index < 3) {
    		return num; //  [1, 2, 3, undefined]
    	}
    });
    

Array.prototype.reduce

1. 语法

DANGER

arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])

参数:

  • callback:回调函数;

    • accumulator:累计器累计回调的返回值;
    • currentValue:当前值;
    • index:当前值的索引;
    • array:当前数组。
  • initialValue:作为第一次调用 callback 函数的第一个参数的值,默认值为数组中的第一个元素,空数组会导致报错。

返回值:

函数累计处理的结果。

2. 描述

描述即返回值。

个人在日常开发中常用场景:

  • 累计数据时。

3. 示例

  • sum all the values of an array

    [0, 1, 2, 3].reduce((accumulator, currentValue) => accumulator + currentValue, 0); // 6
    
  • sum of values in an object array

    const initialValue = 0;
    [{x: 1}, {x: 2}, {x: 3}].reduce((accumulator, currentValue) => accumulator + currentValue.x, initialValue); // 6
    
  • flatten an array of arrays

    [[0, 1], [2, 3], [4, 5]].reduce(( accumulator, currentValue ) => accumulator.concat(currentValue), []); // [0, 1, 2, 3, 4, 5]
    
  • counting instances of values in an object

    const names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];
    names.reduce( (allNames, name) => { 
      if (name in allNames) {
        allNames[name]++;
      }
      else {
        allNames[name] = 1;
      }
      return allNames;
    }, {}); // { 'Alice': 2, 'Bob': 1, 'Tiff': 1, 'Bruce': 1 }
    
  • grouping objects by a property

    const people = [
      { name: 'Alice', age: 21 },
      { name: 'Max', age: 20 },
      { name: 'Jane', age: 20 } 
    ];
    
    function groupBy(objectArray, property) {
      return objectArray.reduce((acc, obj) => {
        const key = obj[property];
        if (!acc[key]) {
          acc[key] = [];
        }
        acc[key].push(obj);
        return acc;
      }, {});
    }
    
    groupBy(people, 'age');
    // { 
    //   20: [
    //     { name: 'Max', age: 20 }, 
    //     { name: 'Jane', age: 20 }
    //   ], 
    //   21: [{ name: 'Alice', age: 21 }] 
    // }
    
  • bonding arrays contained in an array of objects using the spread operator and initialValue

    const friends = [{
      name: 'Anna',
      books: ['Bible', 'Harry Potter'],
      age: 21
    }, {
      name: 'Bob',
      books: ['War and peace', 'Romeo and Juliet'],
      age: 26
    }, {
      name: 'Alice',
      books: ['The Lord of the Rings', 'The Shining'],
      age: 18
    }];
    
    friends.reduce(function(accumulator, currentValue) {
      return [...accumulator, ...currentValue.books];
    }, ['Alphabet']); // ["Alphabet", "Bible", "Harry Potter", "War and peace", "Romeo and Juliet", "The Lord of the Rings", "The Shining"]
    
  • remove duplicate items in array

    const myArray = ['a', 'b', 'a', 'b', 'c', 'e', 'e', 'c', 'd', 'd', 'd', 'd'];
    myArray.reduce((accumulator, currentValue) => {
      if (accumulator.indexOf(currentValue) === -1) {
        accumulator.push(currentValue);
      }
      return accumulator;
    }, []); // ["a", "b", "c", "e", "d"]
    
  • running promises in sequence

    function runPromiseInSequence(arr, input) {
      return arr.reduce((promiseChain, currentFunction) => promiseChain.then(currentFunction), Promise.resolve(input));
    }
    
    // promise function 1
    function p1(a) {
      return new Promise((resolve, reject) => {
        resolve(a * 5);
      });
    }
    
    // promise function 2
    function p2(a) {
      return new Promise((resolve, reject) => {
        resolve(a * 2);
      });
    }
    
    // function 3  - will be wrapped in a resolved promise by .then()
    function f3(a) {
     return a * 3;
    }
    
    // promise function 4
    function p4(a) {
      return new Promise((resolve, reject) => {
        resolve(a * 4);
      });
    }
    
    const promiseArr = [p1, p2, f3, p4];
    runPromiseInSequence(promiseArr, 10)
      .then(console.log);   // 1200
    
  • function composition enabling piping

    const double = x => x + x;
    const triple = x => 3 * x;
    const quadruple = x => 4 * x;
    
    const pipe = (...functions) => input => functions.reduce((acc, fn) => fn(acc), input);
    
    const multiply6 = pipe(double, triple);
    const multiply9 = pipe(triple, triple);
    const multiply16 = pipe(quadruple, quadruple);
    const multiply24 = pipe(double, triple, quadruple);
    
    multiply6(6); // 36
    multiply9(9); // 81
    multiply16(16); // 256
    multiply24(10); // 240
    

Array.prototype.reduceRight

1. 语法

DANGER

arr.reduceRight(callback[, initialValue])

参数:

  • callback:回调函数;

    • previousValue:上一次调用回调的返回值,或提供的 initialValue;

    • currentValue:当前值;

    • index:当前值的索引;

    • array:当前数组。

  • initialValue:作为第一次调用 callback 函数的第一个参数的值,默认值为数组中的第一个元素,空数组会导致报错。

返回值:

函数累计处理的结果。

2. 描述

基本与 reduce 一致,从右到左。

个人在日常开发中常用场景:

  • 尚未使用过。

3. 示例

参考 reduce 即可。

Array.prototype.some

1. 语法

DANGER

arr.some(callback(element[, index[, array]])[, thisArg])

参数:

  • callback:回调函数;
    • element:当前元素;
    • index:当前元素的索引;
    • array:当前数组。
  • thisArg:执行 callback 时使用的 this 值。

返回值:

如果回调函数返回至少一个数组元素的 truthy 值,则返回 true;否则为 false。

2. 描述

描述即返回值。

个人在日常开发中常用场景:

  • 常用多种元素判断。

3. 示例

  • testing array elements using arrow functions

    [2, 5, 8, 1, 4].some(x => x > 10); // false
    [12, 5, 8, 1, 4].some(x => x > 10); // true
    
  • checking whether a value exists using an arrow function

    const fruits = ['apple', 'banana', 'mango', 'guava'];
    function checkAvailability(arr, val) {
      return arr.some(arrVal => val === arrVal);
    }
    
    checkAvailability(fruits, 'kela');   // false
    checkAvailability(fruits, 'banana'); // true
    
  • converting any value to Boolean

    const TRUTHY_VALUES = [true, 'true', 1];
    
    function getBoolean(value) {
      'use strict';
      
      if (typeof value === 'string') {
        value = value.toLowerCase().trim();
      }
      
      return TRUTHY_VALUES.some(t => t === value);
    }
    
    getBoolean(false);   // false
    getBoolean('false'); // false
    getBoolean(1);       // true
    getBoolean('true');  // true
    

Array.prototype.values

1. 语法

DANGER

arr.values()

返回值:

返回一个新的 Array Iterator 对象。

2. 描述

描述即返回值。

个人在日常开发中常用场景:

  • 尚未使用过。

3. 示例

  • iteration using for...of loop

    const arr = ['a', 'b', 'c'];
    const iterator = arr.values();
    
    for (let letter of iterator) {
      console.log(letter); // "a" "b" "c"
    }
    

Array.prototype.flat

1. 语法

DANGER

arr.flat(depth)

参数:

  • depth:指定要提取嵌套数组的结构深度,默认值为 1,Infinity 表示无限层级。

返回值:

一个包含将数组与子数组中所有元素的新数组。

2. 描述

flat() 方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。方法很美丽,但是兼容性很差,所以提供了替代方案。

个人在日常开发中常用场景:

  • 尚未使用过。

3. 示例

  • flattening nested arrays

    const arr = [1, 2, [3, 4]];
    arr.flat();  // [1, 2, 3, 4]
    
    const  arr = [1, 2, [3, 4, [5, 6]]];
    arr.flat(); // [1, 2, 3, 4, [5, 6]]
    
    const arr = [1, 2, [3, 4, [5, 6]]];
    arr.flat(2); // [1, 2, 3, 4, 5, 6]
    
  • flattening and array holes

    const arr = [1, 2, , 4, 5];
    arr.flat(); // [1, 2, 4, 5]
    

4. 替代方案

使用 reduce 和 concat:

  • flat single level array

    const arr = [1, 2, [3, 4]];
    arr.reduce((acc, val) => acc.concat(val), []); // [1, 2, 3, 4]
    [].concat(...arr); // [1, 2, 3, 4]
    
  • enable deep level flatten use recursion with reduce and concat

    const arr = [1,2,3,[1,2,3,4, [2,3,4]]];
    
    function flattenDeep(arr) {
      return arr.reduce((acc, val) => Array.isArray(val) ? acc.concat(flattenDeep(val)) : acc.concat(val), []);
    }
    
    flattenDeep(arr); // [1, 2, 3, 1, 2, 3, 4, 2, 3, 4]
    
  • non recursive flatten deep using a stack

    let arr = [1,2,3,[1,2,3,4, [2,3,4]]];
    function flatten(input) {
      const stack = [...input];
      const res = [];
      
      while (stack.length) {
        const next = stack.pop();
        if (Array.isArray(next)) {
          stack.push(...next);
        } else {
          res.push(next);
        }
      }
      
      return res.reverse();
    }
    flatten(arr); // [1, 2, 3, 1, 2, 3, 4, 2, 3, 4]
    

Array.prototype.flatMap

1. 语法

DANGER

arr.flatMap(function callback(currentValue[, index[, array]]) {

​ // return element for new_array

}[, thisArg])

参数:

  • callback:回调函数;
    • currentValue:当前值;
    • index:当前值的索引;
    • array:当前数组。
  • thisArg:执行 callback 时使用的 this 值。

返回值:

一个新的数组,其中每个元素都是回调函数的结果,并且结构深度 depth 值为 1。

2. 描述

相当于执行 map 方法后,对返回值组成的数组执行 flat 方法。

个人在日常开发中常用场景:

  • 尚未使用过。

3. 示例

  • map and flatMap

    const arr = [1, 2, 3, 4];
    
    arr.map(x => [x * 2]); // [[2], [4], [6], [8]]
    arr.flatMap(x => [x * 2]); // [2, 4, 6, 8]
    arr.flatMap(x => [[x * 2]]); // [[2], [4], [6], [8]]
    
  • a list of sentences

    let arr = ["今天天气不错", "", "早上好"];
    
    arr.map(s => s.split("")); // [["今", "天", "天", "气", "不", "错"],[""],["早", "上", "好"]]
    
    arr.flatMap(s => s.split('')); // ["今", "天", "天", "气", "不", "错", "早", "上", "好"]