Array.prototype.concat()

concat()方法用于合并两个或多个数组。此方法不更改现有数组,而是返回一个新数组

  • 语法

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

其中参数可以为数组或值

1
2
3
4
5
6
7
let arr1 = [1, 2, 3];
let arr2 = [4, 5, 6];

console.log(arr1.concat(arr2, 'a', 'b'));
// [ 1, 2, 3, 4, 5, 6, 'a', 'b' ]
console.log(arr1);
// [ 1, 2, 3 ]

需要注意,concat()中的拷贝是浅拷贝

1
2
3
4
5
6
7
8
9
10
11
12
13
14
let arr1 = [1, 2, {a: 3}];
let arr2 = [4, 5, {b: 6}];

let newArr = arr1.concat(arr2);
console.log(newArr);
// [ 1, 2, { a: 3 }, 4, 5, { b: 6 } ]
newArr[2].a = 2018;
newArr[5].b = 2019;
console.log(newArr);
// [ 1, 2, { a: 2018 }, 4, 5, { b: 2019 } ]
console.log(arr1);
// [ 1, 2, { a: 2018 } ]
console.log(arr2);
// [ 4, 5, { b: 2019 } ]
  • 实现

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Array.prototype.myConcat = function () {
    var arr = this.slice(0);
    arguments.length && [].forEach.call(arguments, x => {
    if (x instanceof Array) {
    x.forEach(y => {
    arr.push(y);
    });
    } else {
    arr.push(x);
    }
    });
    return arr;
    };

Array.prototype.join()

join()方法将一个数组(或一个类数组对象)的所有元素连接成一个字符串并返回这个字符串

如果数组只有一个项目,那么将返回该项目而不使用分隔符

  • 语法

    1
    arr.join([separator])
1
2
3
4
5
6
let arr = ['a', 'b', 'c'];

console.log(arr.join());
// abc
console.log(arr.join('+'))
// a+b+c
  • 实现

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    Array.prototype.myJoin = function (separator) {
    var separator = separator === undefined ? ',' : separator.toString();
    var result = '';
    if (!this) {
    return result;
    }
    if (this.length === 1) {
    return this[0].toString();
    } else {
    for (var i = 0; i < this.length - 1; i++) {
    result += (this[i].toString() + separator);
    }
    result += this[i].toString();
    return result;
    }
    };

Array.prototype.pop()

pop()方法从数组中删除最后一个元素,并返回该元素的值

  • 语法

    1
    arr.pop()

此方法会更改原数组的长度

1
2
3
4
5
6
7
8
let arr = [1, 2, 3];

console.log(arr.pop());
// 3
console.log(arr[2])
// undefined
console.log(arr)
// [ 1, 2 ]
  • 实现

    1
    2
    3
    Array.prototype.myPop = function () {
    return this.splice(this.length - 1, 1)[0];
    };

Array.prototype.push()

push()方法将一个或多个元素添加到数组的末尾,并返回该数组的新长度

  • 语法

    1
    arr.push(element1[, ...[, elementN]])

push()方法会改变原数组

1
2
3
4
5
6
7
let arr = [1, 2, 3];

let test = ['a', 'b'];
console.log(arr.push(test, { key: 'asd' }));
// 5
console.log(arr);
// [ 1, 2, 3, [ 'a', 'b' ], { key: 'asd' } ]
  • 实现

    1
    2
    3
    4
    Array.prototype.myPush = function () {
    this.splice.apply(this, [this.length, 0].concat([].slice.apply(arguments)));
    return this.length;
    };

Array.prototype.reverse()

reverse()方法将数组中元素的位置颠倒,并返回该数组

  • 语法

    1
    arr.reverse()

该方法会改变原数组

1
2
3
4
5
6
let arr = [1, 2, 3];

console.log(arr.reverse());
// [ 3, 2, 1 ]
console.log(arr);
// [ 3, 2, 1 ]
  • 实现

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Array.prototype.myReverse = function () {
    var left = 0,
    right = this.length - 1,
    temp;
    while (left < right) {
    temp = this[left];
    this[left] = this[right];
    this[right] = temp;
    left++;
    right--;
    }
    return this;
    };

Array.prototype.shift()

shift()方法从数组中删除第一个元素,并返回该元素的值

  • 语法

    1
    arr.shift()

此方法更改原数组,如果原数组为空,则返回undefined

1
2
3
4
5
6
7
8
9
10
let arr = [['a', 'b'], 1, 2, 3];

let first = arr.shift();

console.log(arr);
// [ 1, 2, 3 ]
console.log(first);
// [ 'a', 'b' ]
console.log([].shift());
// undefined
  • 实现

    1
    2
    3
    Array.prototype.myShift = function () {
    return this.splice(0, 1)[0];
    };

Array.prototype.slice()

slice()方法返回一个新的数组对象,这一对象是一个由beginend决定的原数组的浅拷贝(包括 begin,不包括end)

原始数组不会被改变

  • 语法

    1
    arr.slice([begin[, end]])
    • begin

      提取起始处的索引,从该索引开始提取原数组元素,默认为 0

      如果该参数为负数,则表示从原数组中的倒数第几个元素开始提取

      如果begin大于原数组的长度,则会返回空数组

    • end

      提取终止处的索引,在该索引处结束提取原数组元素,默认为 0

      如果该参数为负数,则它表示在原数组中的倒数第几个元素结束抽取

      如果end被省略,则会一直提取到原数组末尾;如果end大于数组的长度,会一直提取到原数组末尾

1
2
3
4
5
6
7
8
let arr = [1, 2, 3, 4, 5];

console.log(arr.slice(1, 3));
// [ 2, 3 ]
console.log(arr.slice(2));
// [ 3, 4, 5 ]
console.log(arr.slice(0, -2));
// [ 1, 2, 3 ]
  • 实现

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    Array.prototype.mySlice = function (begin, end) {
    let len = this.length;

    // 处理 begin 不存在或者为负的情况
    let start = begin || 0;
    start = (start >= 0) ? start : Math.max(0, len + start);

    // 处理 end 不存在或者为负的情况
    end = end || len;
    let upTo = (typeof end === 'number') ? Math.min(end, len) : len;
    if (end < 0) {
    upTo = len + end;
    }

    let size = upTo - start,
    clonedArr = [];
    if (size > 0) {
    for (let i = 0; i < size; i++) {
    clonedArr[i] = this[start + i];
    }
    }
    return clonedArr;
    }

Array.prototype.splice()

splice()方法通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容

  • 语法

    1
    array.splice(start[, deleteCount[, item1[, item2[, ...]]]])
    • start​:指定修改的开始位置(从0计数

      如果超出了数组的长度,则从数组末尾开始添加内容;如果是负值,则表示从数组末位开始的第几位;如果负数的绝对值大于数组的长度,则表示开始位置为第0位

    • deleteCount 可选整数,表示要移除的数组元素的个数

      如果deleteCount大于start之后的元素的总数,则从start后面的元素都将被删除(含第start位)

      如果deleteCount被省略了,或者它的值大于等于array.length - start,那么start之后数组的所有元素都会被删除

      如果deleteCount是 0 或者负数,则不移除元素,这种情况下,至少应添加一个新元素。

    • item1, item2, … 可选

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
let arr = [1, 2, 3, 4, 5];

console.log(arr.splice(1, 1));
// [ 2 ]
console.log(arr);
// [ 1, 3, 4, 5 ]
--------------------------------------------------
let arr = [1, 2, 3, 4, 5];

console.log(arr.splice(1));
// [ 2, 3, 4, 5 ]
console.log(arr);
// [ 1 ]
--------------------------------------------------
let arr = [1, 2, 3, 4, 5];

console.log(arr.splice(1, 1, 'a'));
// [ 2 ]
console.log(arr);
// [ 1, 'a', 3, 4, 5 ]

此方法会改变原数组

  • 实现

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    Array.prototype.mySplice = function (start, deleteCount) {
    let len = this.length,
    insertCount = Math.max(arguments.length - 2, 0),
    result = [];

    // 处理 start 不存在或者为负的情况
    start = start || 0;
    start = (start >= 0) ? Math.min(start, len) : Math.max(0, len + start);

    // 处理 deleteCount 不存在或者为负的情况
    deleteCount = (typeof deleteCount === 'number') ? deleteCount : len;
    deleteCount = Math.max(Math.min(deleteCount, len - start), 0);

    let delta = insertCount - deleteCount, // 数组总长度的增加值
    shiftCount = len - start - deleteCount, // 需要移动的部分的长度
    newLength = len + delta; // 新数组的长度

    for (let i = 0; i < deleteCount; i++) {
    let temp = this[start + i];
    if (temp !== undefined) {
    result[i] = temp;
    }
    }

    // 向后移动未删除部分数组
    if (delta <= 0) {
    let k = start + insertCount;
    while (shiftCount) {
    this[k] = this[k - delta];
    k += 1;
    shiftCount -=1;
    }
    this.length = newLength;
    } else {
    let k = 1;
    while (shiftCount) {
    this[newLength - k] = this[len - k];
    k += 1;
    shiftCount -= 1;
    }
    this.length = newLength;
    }

    // 插入新元素
    if (insertCount > 0) {
    for (let i = 0; i < insertCount; i++) {
    this[start + i] = arguments[i + 2];
    }
    }

    return result;
    }

Array.prototype.unshift()

unshift()方法将一个或多个元素添加到数组的开头,并返回该数组的新长度

  • 语法

    1
    arr.unshift(element1[, ...[, elementN]])

该方法修改原有数组

如果传入多个参数,它们会被以块的形式插入到对象的开始位置,它们的顺序和被作为参数传入时的顺序一致

1
2
3
4
5
6
7
8
9
10
let arr = [1, 2, 3];

console.log(arr.unshift('a'));
// 4
console.log(arr);
// [ 'a', 1, 2, 3 ]
console.log(arr.unshift('q', 'w'));
// 6
console.log(arr);
// [ 'q', 'w', 'a', 1, 2, 3 ]
  • 实现

    1
    2
    3
    4
    Array.prototype.myUnShift = function () {
    this.splice.apply(this, [0, 0].concat([].slice.apply(arguments)));
    return this.length;
    }