1.Array及API

151 阅读7分钟

本章介绍 Array 对象的使用和API。

1.创建数组

  • 使用Array的构造函数:

    // new 操作符 var colors = new Array(); var colors = new Array(20); // length 为 20 var colors = new Array('red', 'blue', 'green');

    // 省略 new 操作符 var colors = Array(3); var names = Array('Greg');

  • 使用数组字面量:

    var colors = ['red', 'blue', 'green']; var names = [];

2.检测数组

  • instanceof操作符

    if (value instanceof Array) { ... }

  • Array.isArray()方法

    if (Array.isArray(value)) { ... }

3.栈(Stack)方法(后进先出, Last-In-First-Out)

push() 和 pop()

  • push() 方法可以接受任意多个参数,添加到数组的尾部,并返回修改后的数组的长度。

  • pop() 方法则从数组尾部移除最后一项,减少数组的length值,然后返回移除的项。

    var colors = new Array();
    var count = colors.push('red', 'green');
    
    count = colors.push('black');
    console.log(count); // 3
    
    var item = colors.pop();
    console.log(item); // 'black'console.log(colors.length); // 2
    

4.队列(Queue)方法(先进先出, First-In-First-Out)

push() 和 shift()

  • shift() 方法,移除数组第一项,数组的length值 -1,然后返回移除的项。

    var colors = new Array();
    var count = colors.push('red', 'green');
    console.log(count); // 2
    
    count = colors.push('black');
    console.log(count); // 3
    count = colors.push('black');
    
    var item = colors.shift();
    console.log(item); // 'red'
    console.log(colors.length); // 2
    
  • unshift()方法,与shift()用途相反,从数组首部 添加 任意多个项,并返回新的长度。

    var colors = new Array();
    var count = colors.unshift('red', 'green'); // 2
    
    count = colors.unshift('black'); // 3
    
    var item = colors.pop(); // 'green'
    console.log(colors.length); // 2
    

5.重排序方法

reverse()和sort()

  • reverse()方法会反转数组项的顺序,仅反转顺序,没有排序。

    var vals = [1, 2, 3, 4, 5];
    vals.reverse(); // [5, 4, 3, 2, 1]
    
  • sort()方法更加灵活,在默认情况下,sort()方法会按升序(小到大)排列数组项。
    为了实现排序,sort()方法会调用每项的toString()方法,然后比较他们的字符串,来确定如何排序。

    var vals = [0,1,5,10,15];
    vals.sort(); // [0, 1, 10, 15, 5], 比较字符串时, '10'位于 '5'的前面
    

sort()方法可以接收一个比较函数,以便指定值的先后顺序。

// 升序排序
function compareAsc(val1, val2) {
    if (val1 < val2) {
        return -1;    
    } else if (val1 > val2) {
        return 1;
    } else {
        return 0;
    }
}

// 降序排序
function compareDesc(val1, val2) {
    if (val1 < val2) {
        return 1;    
    } else if (val1 > val2) {
        return -1;
    } else {
        return 0;
    }
}

var vals = [0, 1, 5, 10, 15];
vals.sort(compareAsc); // [0, 1, 5, 10, 15]
vals.sort(compareDesc); // [15, 10, 5, 1, 0]

// 对于数值类型或者 valueOf() 方法返回数值类型的对象,下面的比较函数更简单。
vals.sort((x, y) => x-y); // [0, 1, 5, 10, 15]
vals.sort((x, y) => y-x); // [15, 10, 5, 1, 0]

6.操作方法

concat()方法可以基于当前数组创建一个全新数组。

不传参时,复制当前数组并返回副本。

传参是一或多个数组,则该方法会将这些数组中的每项都添加到结果数组中。

传参不是数组,这些值就会被简单的添加到结果数组尾部。

var colors = ['red', 'green', 'blue'];
var colors2 = colors.concat('yellow', ['black', 'brown']);

console.log(colors2); // ['red', 'green', 'blue', 'yellow', 'black', 'brown'];

slice()方法,能基于当前数组中的一或多个项创建一个全新数组。

接收一个或两个参数,开始位置,结束位置。

只有开始位置时,从开始位置直到末尾返回。

开始、结束位置都指定,从开始位置到结束位置之间(不包括结束位置)的项。

var colors = ['red', 'green', 'blue', 'yellow', 'purple'];
var colors2 = colors.slice(1); //['green', 'blue', 'yellow', 'purple']
var colors2 = colors.slice(1, 4); //['green', 'blue', 'yellow']

splice()方法,可以说是最强大的数组方法了,它有很多种用途:

参数

start​

指定修改的开始位置(从0计数)。如果超出了数组的长度,则从数组末尾开始添加内容;如果是负值,则表示从数组末位开始的第几位(从-1计数,这意味着-n是倒数第n个元素并且等价于array.length-n);如果负数的绝对值大于数组的长度,则表示开始位置为第0位。

deleteCount 可选

整数,表示要移除的数组元素的个数。如果 deleteCount 大于 start 之后的元素的总数,则从 start 后面的元素都将被删除(含第 start 位)。如果 deleteCount 被省略了,或者它的值大于等于array.length - start(也就是说,如果它大于或者等于start之后的所有元素的数量),那么start之后数组的所有元素都会被删除。如果 deleteCount 是 0 或者负数,则不移除元素。这种情况下,至少应添加一个新元素。

item1, item2,... 可选
要添加进数组的元素,从start位置开始。如果不指定,则 splice() 将只删除数组元素。

  • 删除:可以删除任意数量的项,只要指定2个参数-要删除的第一项的位置和删除的数量。例如:splice(0, 2)会删除数组中的前两项。
  • 插入:可向指定位置插入任意数量的项,只需要提供3个参数--开始位置、0(删除数量)和要插入的项,可以是多个。
    例如:splice(2, 0, 'red', 'green')会从index为2的项开始插入字符串red和green,index 2 为 red,index 3 为 green,index 4为原来index 2的项。
  • 替换:可向指定位置插入任意数量的项,且同时删除任意数量的项。
    只需指定3个参数--开始位置、删除数量和要插入的任意数量的项。
    例如:splice(2, 1, 'red', 'green') 会删除当前数组index为2的项,然后再从index为2的项后开始插入字符串red和green。

splice()方法始终都会返回一个数组,该数组中包含从原数组中删除的项,没删就返回空数组。

var colors = ['red', 'green', 'blue'];
var removed = colors.splice(0, 1); // 删除第一项
console.log(colors); // ['green', 'blue']
console.log(removed); // ['red']

removed = colors.splice(1, 0, 'yellow', 'orange'); //index 1开始插入两项
console.log(colors); // ['green', ‘yellow’, 'orange', 'blue']
console.log(removed); //[]

removed = colors.splice(1, 1, 'red', 'purple'); // 删除index 1项,并在index 1处插入两项
console.log(colors); // ['green', 'red', 'purple', 'orange', 'blue']

7.位置方法

indexof()和lastIndexOf(),在查找元素时,使用的是全等 ‘===‘ 操作符。

参数

searchElement

要查找的元素

`

fromIndex

`可选

开始查找的位置。

var numbers = [1, 2, 3, 4, 5, 4, 3, 2 ,1];
console.log(numbers.indexOf(4)); // 3
console.log(numbers.lastIndexOf(4)); // 5

console.log(numbers.indexOf(4, 4)); // 5
console.log(numbers.lastIndexOf(4, 4)); // 3

var person = { name: 'Nicholas' };
var people = [{ name : 'Nicholas' }];

var morePeople = [person];

console.log(people.indexOf(person)); // -1, 引用不相等
console.log(morePeople.indexOf(person)); // 0, 值和引用都相等

8.迭代方法

ECMAScript5为数组定义了5个迭代方法。每个方法都接收两个参数:1.在每项上运行的函数 2.(可选)运行在该函数的作用域对象--影响this的值。

第一个参数,函数会接收3个参数:item,index和数组本身array。

  • every():对数组中每项都运行指定函数,若该函数对每项都返回true,则最终结果返回true。

    const isBelowThreshold = (currentValue) => currentValue < 40;
    const array1 = [1, 30, 39, 29, 10, 13];
    console.log(array1.every(isBelowThreshold));
    // expected output: true
    
    [12, 5, 8, 130, 44].every(x => x >= 10); // false
    [12, 54, 18, 130, 44].every(x => x >= 10); // true
    
  • filter(): 对数组中每项都运行指定函数,返回指定函数结果为true的项,最终结果返回满足条件的元素组成的数组。

    const words = ['spray', 'god', 'elite', 'exuberant', 'destruction', 'present'];
    
    const result = words.filter(word => word.length > 6);
    
    console.log(result);
    // expected output: Array ["exuberant", "destruction", "present"]
    
    function isBigEnough(element) {  return element >= 10;}var filtered = [12, 5, 8, 130, 44].filter(isBigEnough);// filtered is [12, 130, 44]
    
  • forEach(): 对数组每项都运行指定函数,没有返回值,本质上与for循环一样。

    const array1 = ['a', 'b', 'c'];
    
    array1.forEach(element => console.log(element));
    
    // expected output: "a"
    // expected output: "b"
    // expected output: "c"
    
    /**
    将for循环转换为forEach
    */
    const items = ['item1', 'item2', 'item3'];const copy = [];// beforefor (let i=0; i<items.length; i++) {  copy.push(items[i]);}// afteritems.forEach(function(item){  copy.push(item);});
    
  • map(): 对数组的每项都运行指定函数,返回每次函数调用的结果所组成的数组。

    const array1 = [1, 4, 9, 16];
    
    // pass a function to map
    const map1 = array1.map(x => x * 2);
    
    console.log(map1);
    // expected output: Array [2, 8, 18, 32]
    
    var numbers = [1, 4, 9];
    var roots = numbers.map(Math.sqrt);
    // roots的值为[1, 2, 3], numbers的值仍为[1, 4, 9]
    
  • some(): 对数组的每项都运行指定函数, 若该函数对原数组的任意一项返回true,则最终结果返回true。

    const array = [1, 2, 3, 4, 5];
    
    // checks whether an element is even
    const even = (element) => element % 2 === 0;
    
    console.log(array.some(even));
    // expected output: true
    
    function isBiggerThan10(element, index, array) {
      return element > 10;
    }
    
    [2, 5, 8, 1, 4].some(isBiggerThan10);  // false
    [12, 5, 8, 1, 4].some(isBiggerThan10); // true
    
    var fruits = ['apple', 'banana', 'mango', 'guava'];
    
    function checkIsInArray(arr, val) {
      return arr.some(arrVal => val === arrVal);
    }
    
    checkIsInArray(fruits, 'kela');   // false
    checkIsInArray(fruits, 'banana'); // true
    

以上方法都不会修改原数组。

9.归并方法

reduce()和reduceRight(),这两个方法都会迭代数组的所有元素,构建一个最终返回的值。

reduce()是从数组的第一个元素开始,逐个遍历到最后。

reduceRight()是从数组的最后一个元素开始,逐个遍历到第一个元素。

参数

callback

一个回调函数,用于操作数组中的每个元素,它可接受四个参数:前一个值(prev),当前值(current),index和数组对象本身

initialValue (可选)

归并基础的初始值。

// 求一个数组中所有值的和var sum = [0, 1, 2, 3].reduce(function(a, b) {
  return a + b;
});
// sum is 6

let initialValue = 0
let sum = [{x: 1}, {x: 2}, {x: 3}].reduce(function (previousValue, currentValue) {
    return previousValue + currentValue.x
}, initialValue)

console.log(sum) // logs 6


// 扁平化(flatten)一个二维数组var flattened = [[0, 1], [2, 3], [4, 5]].reduceRight(function(a, b) {
    return a.concat(b);
}, []);
// flattened is [4, 5, 2, 3, 0, 1]

let flattened = [[0, 1], [2, 3], [4, 5]].reduce(
  function(previousValue, currentValue) {
    return previousValue.concat(currentValue)
  },
  []
)
// flattened is [0, 1, 2, 3, 4, 5]

// 箭头函数版本
let flattened = [[0, 1], [2, 3], [4, 5]].reduce(
  ( previousValue, currentValue ) => previousValue.concat(currentValue),
  []
)


更多详情请查阅:
developer.mozilla.org/zh-CN/docs/…