Skip to content

ES3 方法

1. concat

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

语法

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

参数

valueN 可选

数组和/或值,将被合并到一个新的数组中。如果省略了所有 valueN 参数,则 concat 会返回调用此方法的现存数组的一个浅拷贝。

  • 如果不传参数,返回浅拷贝的数组。修改新数组会影响原数组。
js
const array1 = [{ a: 1 }, 'b', 'c'];
const array2 = array1.concat();

array2[0].a = 2;

console.log(array1);
console.log(array2);

// [Object { a: 2 }, "b", "c"]
// [Object { a: 2 }, "b", "c"]
const array1 = [{ a: 1 }, 'b', 'c'];
const array2 = array1.concat();

array2[0].a = 2;

console.log(array1);
console.log(array2);

// [Object { a: 2 }, "b", "c"]
// [Object { a: 2 }, "b", "c"]
  • 如果传参数,返回新数组。修改新数组会影响原数组。
js
const array1 = [{ a: 1 }, 'b', 'c'];
const array2 = array1.concat('c', 'd', 'e');

array2[0].a = 2;

console.log(array1);
console.log(array2);

// [{ a: 2 }, "b", "c"]
// [{ a: 2 }, "b", "c", "c", "d", "e"]
const array1 = [{ a: 1 }, 'b', 'c'];
const array2 = array1.concat('c', 'd', 'e');

array2[0].a = 2;

console.log(array1);
console.log(array2);

// [{ a: 2 }, "b", "c"]
// [{ a: 2 }, "b", "c", "c", "d", "e"]

concat 方法无论传参与否,返回的都是浅拷贝的数组。

返回值

新的 Array 实例。

描述

concat 方法创建一个新的数组,它由被调用的对象中的元素组成,每个参数的顺序依次是该参数的元素(如果参数是数组)或参数本身(如果参数不是数组)。它不会递归到嵌套数组参数中。

concat 方法不会改变 this 或任何作为参数提供的数组,而是返回一个浅拷贝,它包含与原始数组相结合的相同元素的副本。 原始数组的元素将复制到新数组中,如下所示:

  • 对象引用(而不是实际对象):concat 将对象引用复制到新数组中。 原始数组和新数组都引用相同的对象。 也就是说,如果引用的对象被修改,则更改对于新数组和原始数组都是可见的。 这包括也是数组的数组参数的元素。
  • 数据类型如字符串,数字和布尔(不是StringNumberBoolean 对象):concat 将字符串和数字的值复制到新数组中。

数组/值在连接时保持不变。此外,对于新数组的任何操作(仅当元素不是对象引用时)都不会对原始数组产生影响,反之亦然。

示例

连接两个数组

以下代码将两个数组合并为一个新数组:

js
var alpha = ['a', 'b', 'c'];
var numeric = [1, 2, 3];

alpha.concat(numeric);
// ["a", "b", "c", 1, 2, 3]
var alpha = ['a', 'b', 'c'];
var numeric = [1, 2, 3];

alpha.concat(numeric);
// ["a", "b", "c", 1, 2, 3]

连接三个数组

以下代码将三个数组合并为一个新数组:

js
var num1 = [1, 2, 3],
    num2 = [4, 5, 6],
    num3 = [7, 8, 9];

var nums = num1.concat(num2, num3);

console.log(nums);
// [1, 2, 3, 4, 5, 6, 7, 8, 9]
var num1 = [1, 2, 3],
    num2 = [4, 5, 6],
    num3 = [7, 8, 9];

var nums = num1.concat(num2, num3);

console.log(nums);
// [1, 2, 3, 4, 5, 6, 7, 8, 9]

将值连接到数组

以下代码将三个值连接到数组:

js
var alpha = ['a', 'b', 'c'];

var alphaNumeric = alpha.concat(1, [2, 3]);

console.log(alphaNumeric);
// ['a', 'b', 'c', 1, 2, 3]
var alpha = ['a', 'b', 'c'];

var alphaNumeric = alpha.concat(1, [2, 3]);

console.log(alphaNumeric);
// ['a', 'b', 'c', 1, 2, 3]

合并嵌套数组

js
var num1 = [[1]];
var num2 = [2, [3]];
var num3 = [5, [6]];

var nums = num1.concat(num2);

console.log(nums);
// [[1], 2, [3]]
var num1 = [[1]];
var num2 = [2, [3]];
var num3 = [5, [6]];

var nums = num1.concat(num2);

console.log(nums);
// [[1], 2, [3]]

合并嵌套数组。

js
var nums2 = num1.concat(4, num3);

console.log(nums2)
// results is [[1], 4, 5, [6]]
var nums2 = num1.concat(4, num3);

console.log(nums2)
// results is [[1], 4, 5, [6]]

可以连续合并多个数组。

js
num1[0].push(4);

console.log(nums);
// results is [[1, 4], 2, [3]]
num1[0].push(4);

console.log(nums);
// results is [[1, 4], 2, [3]]

修改原数组会改变浅拷贝的新数组。

2. join

join() 方法将一个数组(或一个类数组对象)的所有元素连接成一个字符串并返回这个字符串。如果数组只有一个项目,那么将返回该项目而不使用分隔符。

语法

arr.join([separator])

参数

separator 可选

指定一个字符串来分隔数组的每个元素。

如果需要,将分隔符转换为字符串。

如果缺省该值,数组元素用逗号(,)分隔。

如果separator是空字符串(""),则所有元素之间都没有任何字符。

返回值

一个所有数组元素连接的字符串。如果 arr.length 为0,则返回空字符串。

描述

所有的数组元素被转换成字符串,再用一个分隔符将这些字符串连接起来。

如果一个元素为 undefinednull,它会被转换为空字符串。

js
var arr = [null, undefined];

console.log(arr.join());
// ,
var arr = [null, undefined];

console.log(arr.join());
// ,
js
var arr = [null, undefined];

console.log(arr.join(''));
// 空串
var arr = [null, undefined];

console.log(arr.join(''));
// 空串

示例

使用四种不同的分隔符连接数组元素

js
var a = ['Wind', 'Rain', 'Fire'];
var val1 = a.join();      // "nd,Rain,Fire"
var val2 = a.join(', ');  // "Wind, Rain, Fire"
var val3 = a.join(' + '); // "Wind + Rain + Fire"
var val4 = a.join('');    // "WindRainFire"
var a = ['Wind', 'Rain', 'Fire'];
var val1 = a.join();      // "nd,Rain,Fire"
var val2 = a.join(', ');  // "Wind, Rain, Fire"
var val3 = a.join(' + '); // "Wind + Rain + Fire"
var val4 = a.join('');    // "WindRainFire"

连接类数组对象

js
function f (a, b, c) {
  var s = Array.prototype.join.call(arguments);
  console.log(s); // "1,a,true"
}

f(1, 'a', true);
function f (a, b, c) {
  var s = Array.prototype.join.call(arguments);
  console.log(s); // "1,a,true"
}

f(1, 'a', true);

也可以这样写,效果同上。

js
function f (a, b, c) {
  var s = [].join.call(arguments);
  console.log(s); // "1,a,true"
}

f(1, 'a', true);
function f (a, b, c) {
  var s = [].join.call(arguments);
  console.log(s); // "1,a,true"
}

f(1, 'a', true);

3. pop

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

语法

arr.pop()

无参数

返回值

从数组中删除的元素(当数组为空时返回 undefined)。

描述

pop 方法从一个数组中删除并返回最后一个元素。

pop 方法有意具有通用性。该方法和 call()apply() 一起使用时,可应用在类似数组的对象上。

pop 方法根据 length 属性来确定最后一个元素的位置。

如果不包含 length 属性或 length 属性不能被转成一个数值,会将 length 置为0,并返回undefined

js
var nums = {
  '0': 1,
  '1': 2,
}

console.log([].pop.call(nums)); // undefined
console.log(nums); // {0: 1, 1: 2, length: 0}
var nums = {
  '0': 1,
  '1': 2,
}

console.log([].pop.call(nums)); // undefined
console.log(nums); // {0: 1, 1: 2, length: 0}
js
var nums = {
  '0': 1,
  '1': 2,
  'length': undefined
}

console.log([].pop.call(nums)); // undefined
console.log(nums); // {0: 1, 1: 2, length: 0}
var nums = {
  '0': 1,
  '1': 2,
  'length': undefined
}

console.log([].pop.call(nums)); // undefined
console.log(nums); // {0: 1, 1: 2, length: 0}
js
var nums = {
  '0': 1,
  '1': 2,
  'length': '1'
}

console.log([].pop.call(nums)); // 1
console.log(nums); // {1: 2, length: 0}
var nums = {
  '0': 1,
  '1': 2,
  'length': '1'
}

console.log([].pop.call(nums)); // 1
console.log(nums); // {1: 2, length: 0}
js
var nums = {
  '0': 1,
  '1': 2,
  'length': 1
}

console.log([].pop.call(nums)); // 1
console.log(nums); // {1: 2, length: 0}
var nums = {
  '0': 1,
  '1': 2,
  'length': 1
}

console.log([].pop.call(nums)); // 1
console.log(nums); // {1: 2, length: 0}
js
var nums = {
  '0': 1,
  '1': 2,
  'length': '-1'
}

console.log([].pop.call(nums)); // undefined
console.log(nums); // {0: 1, 1: 2, length: 0}
var nums = {
  '0': 1,
  '1': 2,
  'length': '-1'
}

console.log([].pop.call(nums)); // undefined
console.log(nums); // {0: 1, 1: 2, length: 0}
js
var nums = {
  '0': 1,
  '1': 2,
  'length': true
}

console.log([].pop.call(nums)); // 1
console.log(nums); // {1: 2, length: 0}
var nums = {
  '0': 1,
  '1': 2,
  'length': true
}

console.log([].pop.call(nums)); // 1
console.log(nums); // {1: 2, length: 0}
js
var nums = {
  '0': 1,
  '1': 2,
  'length': 5
}

console.log([].pop.call(nums)); // undefined
console.log(nums); // {1: 2, length: 4}
var nums = {
  '0': 1,
  '1': 2,
  'length': 5
}

console.log([].pop.call(nums)); // undefined
console.log(nums); // {1: 2, length: 4}

示例

删除数组最后一个元素

js
var arr = ["angel", "clown", "mandarin", "surgeon"];

var popped = arr.pop();

console.log(arr); // ["angel", "clown", "mandarin"]
console.log(popped); // surgeon
var arr = ["angel", "clown", "mandarin", "surgeon"];

var popped = arr.pop();

console.log(arr); // ["angel", "clown", "mandarin"]
console.log(popped); // surgeon

4. shift

shift() 方法从数组中删除第一个元素,并返回该元素的值。此方法更改数组的长度。

语法

arr.shift()

无参数

返回值

从数组中删除的元素; 如果数组为空则返回 undefined

描述

shift 方法移除索引为 0 的元素(即第一个元素),并返回被移除的元素,其他元素的索引值随之减 1。

如果 length 属性的值为 0 (长度为 0),则返回 undefined

shift 方法并不局限于数组:这个方法能够通过 callapply 方法作用于类似数组的对象上。

但是对于没有 length 属性(从0开始的一系列连续的数字属性的最后一个)的对象,调用该方法可能没有任何意义。

Array.prototype.pop() 有着和 shift 相似的行为, 但是是作用在数组的最后一个元素上的。

js
let arr = [1, 2, 3];

console.log(arr.shift()); // 1
console.log(arr); // [2, 3]
let arr = [1, 2, 3];

console.log(arr.shift()); // 1
console.log(arr); // [2, 3]
js
let arr = [];

console.log(arr.shift()); // undefined
let arr = [];

console.log(arr.shift()); // undefined

shift 方法同样可以操作类数组。

js
let obj = {
  '0': 1,
  '1': 2
}

console.log([].shift.call(obj)); // undefined
console.log(obj); // {0: 1, 1: 2, length: 0}
let obj = {
  '0': 1,
  '1': 2
}

console.log([].shift.call(obj)); // undefined
console.log(obj); // {0: 1, 1: 2, length: 0}
js
let obj = {
  '0': 1,
  '1': 2,
  length: 1
}

console.log([].shift.call(obj)); // 1
console.log(obj); // {1: 2, length: 0}
let obj = {
  '0': 1,
  '1': 2,
  length: 1
}

console.log([].shift.call(obj)); // 1
console.log(obj); // {1: 2, length: 0}

示例

移除数组中的一个元素

js
var arr = ['angel', 'clown', 'mandarin', 'surgeon'];

console.log(arr); // ["angel", "clown", "mandarin", "surgeon"]

var shifted = arr.shift();
console.log(shifted); // angel

console.log(arr); // ["clown", "mandarin", "surgeon"]
var arr = ['angel', 'clown', 'mandarin', 'surgeon'];

console.log(arr); // ["angel", "clown", "mandarin", "surgeon"]

var shifted = arr.shift();
console.log(shifted); // angel

console.log(arr); // ["clown", "mandarin", "surgeon"]

while 循环中使用 shift()

shift() 方法经常用于 while loop 的环境中.。下例中每个循环将要从一个数组中移除下一项元素,直至它成为空数组。

js
var names = ["Andrew", "Edward", "Paul", "Chris" ,"John"];

while((i = names.shift()) !== undefined) {
  console.log(i);
}
// Andrew Edward Paul Chris John
var names = ["Andrew", "Edward", "Paul", "Chris" ,"John"];

while((i = names.shift()) !== undefined) {
  console.log(i);
}
// Andrew Edward Paul Chris John

5. push

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

语法

arr.push(element1, ..., elementN)

参数

elementN

被添加到数组末尾的元素。

返回值

当调用该方法时,新的 length 属性值将被返回。

描述

push方法将值追加到数组中。

push 方法具有通用性。该方法和 call()apply() 一起使用时,可应用在类似数组的对象上。

push 方法根据 length 属性来决定从哪里开始插入给定的值。

如果 length 不能被转成一个数值,则插入的元素索引为 0,包括 length 不存在时。当 length 不存在时,将会创建它。

唯一的原生类数组(array-like)对象是 Strings,尽管如此,它们并不适用该方法,因为字符串是不可改变的。

js
let obj = {
  '0': 1,
  '1': 2
}

[].push.call(obj); // 报错 Uncaught SyntaxError: Unexpected token ']'

console.log(obj);
let obj = {
  '0': 1,
  '1': 2
}

[].push.call(obj); // 报错 Uncaught SyntaxError: Unexpected token ']'

console.log(obj);
js
let obj = {
  '0': 1,
  '1': 2
}

[].push.call(obj); // 报错 Uncaught TypeError: {(intermediate value)(intermediate value)} is not a function

console.log(obj);
let obj = {
  '0': 1,
  '1': 2
}

[].push.call(obj); // 报错 Uncaught TypeError: {(intermediate value)(intermediate value)} is not a function

console.log(obj);

产生上述问题的原因是 JS 解析报错。比如同时存在连续的符号,如 {} ()、{} [],所以这也可以说明 ";" 的重要性。

js
let obj = {
  '0': 1,
  '1': 2
}

console.log([].push.call(obj, 3)); // 1

console.log(obj); // {0: 3, 1: 2, length: 1}
let obj = {
  '0': 1,
  '1': 2
}

console.log([].push.call(obj, 3)); // 1

console.log(obj); // {0: 3, 1: 2, length: 1}
js
let obj = {
  '0': 1,
  '1': 2
}

var push = ([]).push;

push.call(obj, 3);

console.log(obj); // {0: 3, 1: 2, length: 1}
let obj = {
  '0': 1,
  '1': 2
}

var push = ([]).push;

push.call(obj, 3);

console.log(obj); // {0: 3, 1: 2, length: 1}
js
let obj = {
  '0': 1,
  '1': 2
}

Array.prototype.push.call(obj, 3);

console.log(obj); // {0:3, 1: 2, length: 1}
let obj = {
  '0': 1,
  '1': 2
}

Array.prototype.push.call(obj, 3);

console.log(obj); // {0:3, 1: 2, length: 1}
js
let obj = {
  '0': 1,
  '1': 2,
  length: 3
}

Array.prototype.push.call(obj, 3);

console.log(obj); // {0:3, 1: 2, 3: 3 length: 4}
let obj = {
  '0': 1,
  '1': 2,
  length: 3
}

Array.prototype.push.call(obj, 3);

console.log(obj); // {0:3, 1: 2, 3: 3 length: 4}

call 和 apply 对于 push 方法的用法类似。

示例

添加元素到数组

js
var sports = ["soccer", "baseball"];
var total = sports.push("football", "swimming");

console.log(sports); // ["soccer", "baseball", "football", "swimming"]
console.log(total); // 4
var sports = ["soccer", "baseball"];
var total = sports.push("football", "swimming");

console.log(sports); // ["soccer", "baseball", "football", "swimming"]
console.log(total); // 4

合并两个数组

合并数组时存在参数上限, 参数个数上限:65536

js
var vegetables = ['parsnip', 'potato'];
var moreVegs = ['celery', 'beetroot'];

Array.prototype.push.apply(vegetables, moreVegs);

console.log(vegetables); // ['parsnip', 'potato', 'celery', 'beetroot']
var vegetables = ['parsnip', 'potato'];
var moreVegs = ['celery', 'beetroot'];

Array.prototype.push.apply(vegetables, moreVegs);

console.log(vegetables); // ['parsnip', 'potato', 'celery', 'beetroot']

像数组一样使用对象

js
var obj = {
  length: 0,
  addElem: function (elem) {
    [].push.call(this, elem);
  }
}

obj.addElem(1);
obj.addElem({});

console.log(obj); //{0: 1, 1: {…}, length: 2, addElem: ƒ}
console.log(obj.length); // 2
var obj = {
  length: 0,
  addElem: function (elem) {
    [].push.call(this, elem);
  }
}

obj.addElem(1);
obj.addElem({});

console.log(obj); //{0: 1, 1: {…}, length: 2, addElem: ƒ}
console.log(obj.length); // 2

注意,尽管 obj 不是数组,但是 push 方法成功地使 obj 的 length 属性增长了,就像我们处理一个实际的数组一样。

6. unshift

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

语法

arr.unshift(element1, ..., elementN)

参数

elementN

要添加到数组开头的元素或多个元素。

返回值

当一个对象调用该方法时,返回其 length 属性值。

描述

unshift 方法会在调用它的类数组对象的开始位置插入给定的参数。

unshift 特意被设计成具有通用性;这个方法能够通过 callapply 方法作用于类数组对象上。

不过对于没有 length 属性(代表从0开始的一系列连续的数字属性的最后一个)的对象,调用该方法可能没有任何意义。

js
let obj = {
  '0': 1,
  '1': 2
};

[].unshift.call(obj, 3); 

console.log(obj); // {0: 3, 1: 2, length: 1}
let obj = {
  '0': 1,
  '1': 2
};

[].unshift.call(obj, 3); 

console.log(obj); // {0: 3, 1: 2, length: 1}
js
let obj = {};

[].unshift.call(obj, 3); 

console.log(obj); // {0: 3, length: 1}
let obj = {};

[].unshift.call(obj, 3); 

console.log(obj); // {0: 3, length: 1}

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

于是,传入多个参数调用一次 unshift ,和传入一个参数调用多次 unshift (例如,循环调用),它们将得到不同的结果。例如:

js
let arr = [4,5,6];
arr.unshift(1,2,3);
console.log(arr); // [1, 2, 3, 4, 5, 6]
let arr = [4,5,6];
arr.unshift(1,2,3);
console.log(arr); // [1, 2, 3, 4, 5, 6]
js
let arr = [4,5,6];
arr.unshift(1);
arr.unshift(2);
arr.unshift(3);
console.log(arr); // [3, 2, 1, 4, 5, 6]
let arr = [4,5,6];
arr.unshift(1);
arr.unshift(2);
arr.unshift(3);
console.log(arr); // [3, 2, 1, 4, 5, 6]

示例

js
let arr = [1, 2];

arr.unshift(0); // [0, 1, 2]

arr.unshift(-2, -1); // [-2, -1, 0, 1, 2]

arr.unshift([-4, -3]); // [[-4, -3], -2, -1, 0, 1, 2]

arr.unshift([-7, -6], [-5]); // [ [-7, -6], [-5], [-4, -3], -2, -1, 0, 1, 2 ]
let arr = [1, 2];

arr.unshift(0); // [0, 1, 2]

arr.unshift(-2, -1); // [-2, -1, 0, 1, 2]

arr.unshift([-4, -3]); // [[-4, -3], -2, -1, 0, 1, 2]

arr.unshift([-7, -6], [-5]); // [ [-7, -6], [-5], [-4, -3], -2, -1, 0, 1, 2 ]

7. slice => [begin, end)

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

语法

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

参数

begin 可选

提取起始处的索引(从 0 开始),从该索引开始提取原数组元素。

如果该参数为负数,则表示从原数组中的倒数第几个元素开始提取,slice(-2) 表示提取原数组中的倒数第二个元素到最后一个元素(包含最后一个元素)。

如果省略 begin,则 slice 从索引 0 开始。如果 begin 超出原数组的索引范围,则会返回空数组。

end 可选

提取终止处的索引(从 0 开始),在该索引处结束提取原数组元素。

slice 会提取原数组中索引从 beginend 的所有元素(包含 begin,但不包含 end)。

slice(1,4) 会提取原数组中从第二个元素开始一直到第四个元素的所有元素 (索引为 1, 2, 3的元素)。

如果该参数为负数, 则它表示在原数组中的倒数第几个元素结束抽取。 slice(-2,-1) 表示抽取了原数组中的倒数第二个元素到最后一个元素(不包含最后一个元素,也就是只有倒数第二个元素)。

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

返回值

一个含有被提取元素的新数组。

描述

slice 不会修改原数组,只会返回一个浅复制了原数组中的元素的一个新数组。原数组的元素会按照下述规则拷贝:

  • 如果该元素是个对象引用 (不是实际的对象),slice 会拷贝这个对象引用到新的数组里。两个对象引用都引用了同一个对象。如果被引用的对象发生改变,则新的和原来的数组中的这个元素也会发生改变。

    js
    let arr = [ {a: 1}, 2, 3 ];
    let newArr = arr.slice(0, 1);
    
    console.log(JSON.stringify(arr)); // '[{"a":1},2,3]'
    newArr[0].a = 2;
    console.log(JSON.stringify(arr)); // '[{"a":2},2,3]'
    let arr = [ {a: 1}, 2, 3 ];
    let newArr = arr.slice(0, 1);
    
    console.log(JSON.stringify(arr)); // '[{"a":1},2,3]'
    newArr[0].a = 2;
    console.log(JSON.stringify(arr)); // '[{"a":2},2,3]'
  • 对于字符串、数字及布尔值来说(不是 StringNumber 或者 Boolean 对象),slice 会拷贝这些值到新的数组里。在别的数组里修改这些字符串或数字或是布尔值,将不会影响另一个数组。

如果向两个数组任一中添加了新元素,则另一个不会受到影响。

示例

返回现有数组的一部分

js
var fruits = ['Banana', 'Orange', 'Lemon', 'Apple', 'Mango'];
var citrus = fruits.slice(1, 3);

console.log(citrus); // ["Orange", "Lemon"]
var fruits = ['Banana', 'Orange', 'Lemon', 'Apple', 'Mango'];
var citrus = fruits.slice(1, 3);

console.log(citrus); // ["Orange", "Lemon"]

使用 slice

js
let arr = [ {a: 1}, 2, 3 ];
let newArr = arr.slice(0, 1);

console.log(JSON.stringify(arr)); // '[{"a":1},2,3]'
newArr[0].a = 2;
console.log(JSON.stringify(arr)); // '[{"a":2},2,3]'
let arr = [ {a: 1}, 2, 3 ];
let newArr = arr.slice(0, 1);

console.log(JSON.stringify(arr)); // '[{"a":1},2,3]'
newArr[0].a = 2;
console.log(JSON.stringify(arr)); // '[{"a":2},2,3]'

转化类数组

slice 方法可以用来将一个类数组(Array-like)对象/集合转换成一个新数组。你只需将该方法绑定到这个对象上。

一个函数中的 arguments 就是一个类数组对象的例子。

js
function test () {
  return Array.prototype.slice.call(arguments);
}

var arr = test(2, 3, 4);

console.log(arr); // [2, 3, 4]
function test () {
  return Array.prototype.slice.call(arguments);
}

var arr = test(2, 3, 4);

console.log(arr); // [2, 3, 4]

除了使用 Array.prototype.slice.call(``arguments``),你也可以简单的使用 [].slice.call(arguments) 来代替。

js
function test () {
  return [].slice.call(arguments);
}

var arr = test(2, 3, 4);

console.log(arr); // [2, 3, 4]
function test () {
  return [].slice.call(arguments);
}

var arr = test(2, 3, 4);

console.log(arr); // [2, 3, 4]

另外,你可以使用 bind 来简化该过程。

js
const originSlice = Array.prototype.slice;
const slice = Function.prototype.call.bind(originSlice);

function test () {
  return slice(arguments);
}

var arr = test(2, 3, 4);

console.log(arr); // [2, 3, 4]
const originSlice = Array.prototype.slice;
const slice = Function.prototype.call.bind(originSlice);

function test () {
  return slice(arguments);
}

var arr = test(2, 3, 4);

console.log(arr); // [2, 3, 4]

8. splice => [ start, deleteCount, ... ]

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

语法

array.splice(start[, deleteCount[, item1[, item2[, ...]]]])

参数

start

指定修改的开始位置(从0计数)。

如果超出了数组的长度,则从数组末尾开始添加内容;

如果是负值,则表示从数组末位开始的第几位(从-1计数,这意味着-n是倒数第n个元素并且等价于 array.length - n);

如果负数的绝对值大于数组的长度,则表示开始位置为第0位;

js
let arr = [1, 2, 3];

arr.splice(1);

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

arr.splice(1);

console.log(arr); // [1]
js
let arr = [1, 2, 3];

arr.splice(-1);

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

arr.splice(-1);

console.log(arr); // [1, 2]
js
let arr = [1, 2, 3];

arr.splice(-5);

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

arr.splice(-5);

console.log(arr); // []

deleteCount 可选

整数,表示要移除的数组元素的个数。

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

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

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

js
let arr = [1, 2, 3];

arr.splice(1, 0);
console.log(arr); // [1, 2, 3]

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

arr.splice(1, 0);
console.log(arr); // [1, 2, 3]

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

arr.splice(1, 1);

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

arr.splice(1, 1);

console.log(arr); // [1, 3]
js
let arr = [1, 2, 3];

arr.splice(1, 10);

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

arr.splice(1, 10);

console.log(arr); // [1]
js
let arr = [1, 2, 3];

arr.splice(0);

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

arr.splice(0);

console.log(arr); // []

item1, item2, ... 可选

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

js
let arr = [1, 2, 3];

var removeArr = arr.splice(1, 10, 5, 6, 7);

console.log(arr); // [1, 5, 6, 7]
console.log(removeArr); // [2, 3]
let arr = [1, 2, 3];

var removeArr = arr.splice(1, 10, 5, 6, 7);

console.log(arr); // [1, 5, 6, 7]
console.log(removeArr); // [2, 3]
js
let arr = [1, 2, 3];

var removeArr = arr.splice(1, -1, 5, 6, 7);

console.log(arr); // [1, 5, 6, 7, 2, 3]
console.log(removeArr); // []
let arr = [1, 2, 3];

var removeArr = arr.splice(1, -1, 5, 6, 7);

console.log(arr); // [1, 5, 6, 7, 2, 3]
console.log(removeArr); // []

返回值

由被删除的元素组成的一个数组。

如果只删除了一个元素,则返回只包含一个元素的数组。

如果没有删除元素,则返回空数组。

描述

如果添加进数组的元素个数不等于被删除的元素个数,数组的长度会发生相应的改变。

示例

从第 2 位开始删除 0 个元素,插入 "drum"

js
var arr = ["angel", "clown", "mandarin", "sturgeon"];
var removed = arr.splice(2, 0, "drum");

console.log(removed); // []
console.log(arr); // ["angel", "clown", "drum", "mandarin", "sturgeon"]
var arr = ["angel", "clown", "mandarin", "sturgeon"];
var removed = arr.splice(2, 0, "drum");

console.log(removed); // []
console.log(arr); // ["angel", "clown", "drum", "mandarin", "sturgeon"]

从第 2 位开始删除 0 个元素,插入 "drum" 和 ”guitor“

js
var arr = ["angel", "clown", "mandarin", "sturgeon"];
var removed = arr.splice(2, 0, "drum", "guitar");

console.log(removed); // []
console.log(arr); // ["angel", "clown", "drum", "guitar", "mandarin", "sturgeon"]
var arr = ["angel", "clown", "mandarin", "sturgeon"];
var removed = arr.splice(2, 0, "drum", "guitar");

console.log(removed); // []
console.log(arr); // ["angel", "clown", "drum", "guitar", "mandarin", "sturgeon"]

从第 3 位开始删除 1 个元素

js
var arr = ['angel', 'clown', 'drum', 'mandarin', 'sturgeon'];
var removed = arr.splice(3, 1);

console.log(removed); // ['mandarin']
console.log(arr); // ['angel', 'clown', 'drum', 'sturgeon']
var arr = ['angel', 'clown', 'drum', 'mandarin', 'sturgeon'];
var removed = arr.splice(3, 1);

console.log(removed); // ['mandarin']
console.log(arr); // ['angel', 'clown', 'drum', 'sturgeon']

从第 2 位开始删除 1 个元素,插入 "trumpet"

js
var arr = ['angel', 'clown', 'drum', 'mandarin', 'sturgeon'];
var removed = arr.splice(2, 1, 'trumpet');

console.log(removed); // ['drum']
console.log(arr); // ['angel', 'clown', 'trumpet', 'mandarin', 'sturgeon']
var arr = ['angel', 'clown', 'drum', 'mandarin', 'sturgeon'];
var removed = arr.splice(2, 1, 'trumpet');

console.log(removed); // ['drum']
console.log(arr); // ['angel', 'clown', 'trumpet', 'mandarin', 'sturgeon']

从第 0 位开始删除 2 个元素,插入 "parrot"、“anemone” 和 “blue”

js
var arr = ['angel', 'clown', 'drum', 'mandarin', 'sturgeon'];
var removed = arr.splice(0, 2, 'parrot', 'anemone', 'blue');

console.log(removed); // ['drum']
console.log(arr); // ['parrot', 'anemone', 'blue', 'drum', 'mandarin', 'sturgeon']
var arr = ['angel', 'clown', 'drum', 'mandarin', 'sturgeon'];
var removed = arr.splice(0, 2, 'parrot', 'anemone', 'blue');

console.log(removed); // ['drum']
console.log(arr); // ['parrot', 'anemone', 'blue', 'drum', 'mandarin', 'sturgeon']

从第 2 位开始删除 2 个元素

js
var arr = ['parrot', 'anemone', 'blue', 'trumpet', 'sturgeon'];
var removed = arr.splice(arr.length - 3, 2);

console.log(removed); // ['blue', 'trumpet']
console.log(arr); // ['parrot', 'anemone', 'sturgeon']
var arr = ['parrot', 'anemone', 'blue', 'trumpet', 'sturgeon'];
var removed = arr.splice(arr.length - 3, 2);

console.log(removed); // ['blue', 'trumpet']
console.log(arr); // ['parrot', 'anemone', 'sturgeon']
js
var arr = ['parrot', 'anemone', 'blue', 'trumpet', 'sturgeon'];
var removed = arr.splice(2, 2);

console.log(removed); // ['blue', 'trumpet']
console.log(arr); // ['parrot', 'anemone', 'sturgeon']
var arr = ['parrot', 'anemone', 'blue', 'trumpet', 'sturgeon'];
var removed = arr.splice(2, 2);

console.log(removed); // ['blue', 'trumpet']
console.log(arr); // ['parrot', 'anemone', 'sturgeon']

从倒数第 2 位开始删除 1 个元素

js
var arr = ['angel', 'clown', 'mandarin', 'sturgeon'];
var removed = arr.splice(-2, 1);

console.log(removed); // ['mandarin']
console.log(arr); // ['angel', 'clown', 'sturgeon']
var arr = ['angel', 'clown', 'mandarin', 'sturgeon'];
var removed = arr.splice(-2, 1);

console.log(removed); // ['mandarin']
console.log(arr); // ['angel', 'clown', 'sturgeon']

从第 2 位开始删除所有元素

js
var arr = ['angel', 'clown', 'mandarin', 'sturgeon'];
var removed = arr.splice(2);

console.log(removed); // ['mandarin', 'sturgeon']
console.log(arr); // ['angel', 'clown']
var arr = ['angel', 'clown', 'mandarin', 'sturgeon'];
var removed = arr.splice(2);

console.log(removed); // ['mandarin', 'sturgeon']
console.log(arr); // ['angel', 'clown']

9. reverse

reverse() 方法将数组中元素的位置颠倒,并返回该数组。数组的第一个元素会变成最后一个,数组的最后一个元素变成第一个。该方法会改变原数组。

语法

arr.reverse()

无参数

返回值

颠倒后的数组。

描述

reverse 方法颠倒数组中元素的位置,改变了数组,并返回该数组的引用。

reverse方法是特意类化的;此方法可被 calledapplied于类似数组对象。

对象如果不包含反映一系列连续的、基于零的数值属性中的最后一个长度的属性,则该对象可能不会以任何有意义的方式运行。

js
let arr = [1, 2, 3];
let reversed = arr.reverse();

console.log(arr); // [3, 2, 1]
console.log(reversed); // [3, 2, 1]
let arr = [1, 2, 3];
let reversed = arr.reverse();

console.log(arr); // [3, 2, 1]
console.log(reversed); // [3, 2, 1]
js
let obj = {
  '0': 1,
  '1': 2
};

let reversed = [].reverse.call(obj);

console.log(obj); // {0: 1, 1: 2}
console.log(reversed); // {0: 1, 1: 2}
let obj = {
  '0': 1,
  '1': 2
};

let reversed = [].reverse.call(obj);

console.log(obj); // {0: 1, 1: 2}
console.log(reversed); // {0: 1, 1: 2}
js
let obj = {
  '0': 1,
  '1': 2,
  length: 2
};

let reversed = [].reverse.call(obj);

console.log(obj); // {0: 2, 1: 1, length: 2}
console.log(reversed); // {0: 2, 1: 1, length: 2}
let obj = {
  '0': 1,
  '1': 2,
  length: 2
};

let reversed = [].reverse.call(obj);

console.log(obj); // {0: 2, 1: 1, length: 2}
console.log(reversed); // {0: 2, 1: 1, length: 2}
js
let obj = {
  '0': 1,
  '1': 2,
  length: 1
};

let reversed = [].reverse.call(obj);

console.log(obj); // {0: 1, 1: 2, length: 1}
console.log(reversed); // {0: 1, 1: 2, length: 1}
let obj = {
  '0': 1,
  '1': 2,
  length: 1
};

let reversed = [].reverse.call(obj);

console.log(obj); // {0: 1, 1: 2, length: 1}
console.log(reversed); // {0: 1, 1: 2, length: 1}

示例

颠倒数组中的元素

js
const a = [1, 2, 3];

console.log(a); // [1, 2, 3]

a.reverse();

console.log(a); // [3, 2, 1]
const a = [1, 2, 3];

console.log(a); // [1, 2, 3]

a.reverse();

console.log(a); // [3, 2, 1]

颠倒类数组中的元素

js
const a = {0: 1, 1: 2, 2: 3, length: 3};

console.log(a); // {0: 1, 1: 2, 2: 3, length: 3}

Array.prototype.reverse.call(a);

console.log(a); // {0: 3, 1: 2, 2: 1, length: 3}
const a = {0: 1, 1: 2, 2: 3, length: 3};

console.log(a); // {0: 1, 1: 2, 2: 3, length: 3}

Array.prototype.reverse.call(a);

console.log(a); // {0: 3, 1: 2, 2: 1, length: 3}

10. sort

sort() 方法用原地算法对数组的元素进行排序,并返回数组。

默认排序顺序是在将元素转换为字符串,然后比较它们的UTF-16代码单元值序列时构建的

由于它取决于具体实现,因此无法保证排序的时间和空间复杂性。

语法

arr.sort([compareFunction])

参数

compareFunction 可选

用来指定按某种顺序进行排列的函数。如果省略,元素按照转换为的字符串的各个字符的 Unicode 位点进行排序。

  • firstEl

    第一个用于比较的元素。

  • secondEl

    第二个用于比较的元素。

返回值

排序后的数组。请注意,数组已原地排序,并且不进行复制。

描述

如果没有指明 compareFunction ,那么元素会按照转换为的字符串的诸个字符的 Unicode 位点进行排序。

例如 "Banana" 会被排列到 "cherry" 之前。

数字按由小到大排序时,9 出现在 80 之前,但因为(没有指明 compareFunction),比较的数字会先被转换为字符串,所以在Unicode顺序上 "80" 要比 "9" 要靠前。

js
let arr = [9, 80];
let sortArr = arr.sort();

console.log(arr); // [80, 9]
console.log(sortArr); // [80, 9]
let arr = [9, 80];
let sortArr = arr.sort();

console.log(arr); // [80, 9]
console.log(sortArr); // [80, 9]

如果指明了 compareFunction ,那么数组会按照调用该函数的返回值排序。即 a 和 b 是两个将要被比较的元素:

  • 如果 compareFunction(a, b) 小于 0 ,那么 a 会被排列到 b 之前;

  • 如果 compareFunction(a, b) 等于 0 , a 和 b 的相对位置不变。

    备注: ECMAScript 标准并不保证这一行为,而且也不是所有浏览器都会遵守(例如 Mozilla 在 2003 年之前的版本);

  • 如果 compareFunction(a, b) 大于 0 , b 会被排列到 a 之前。

  • compareFunction(a, b) 必须总是对相同的输入返回相同的比较结果,否则排序的结果将是不确定的。

所以,比较函数格式如下:

js
function compare(a, b) {
  if (a < b ) { // 按某种排序标准进行比较, a 小于 b
    return -1;
  }
  if (a > b ) {
    return 1;
  }
  // a must be equal to b
  return 0;
}
function compare(a, b) {
  if (a < b ) { // 按某种排序标准进行比较, a 小于 b
    return -1;
  }
  if (a > b ) {
    return 1;
  }
  // a must be equal to b
  return 0;
}

要比较数字而非字符串,比较函数可以简单的以 a 减 b,如下的函数将会将数组升序排列

js
function compareNumbers(a, b) {
  return a - b;
}
function compareNumbers(a, b) {
  return a - b;
}

sort 方法可以使用 函数表达式 方便地书写:

js
var numbers = [4, 2, 5, 1, 3];
numbers.sort(function(a, b) {
  return a - b;
});
console.log(numbers); // [1, 2, 3, 4, 5]
var numbers = [4, 2, 5, 1, 3];
numbers.sort(function(a, b) {
  return a - b;
});
console.log(numbers); // [1, 2, 3, 4, 5]

也可以写成:

js
var numbers = [4, 2, 5, 1, 3];
numbers.sort((a, b) => a - b);
console.log(numbers); // [1, 2, 3, 4, 5]
var numbers = [4, 2, 5, 1, 3];
numbers.sort((a, b) => a - b);
console.log(numbers); // [1, 2, 3, 4, 5]

对象可以按照某个属性排序:

js
var items = [
  { name: 'Edward', value: 21 },
  { name: 'Sharpe', value: 37 },
  { name: 'And', value: 45 },
  { name: 'The', value: -12 },
  { name: 'Magnetic' },
  { name: 'Zeros', value: 37 }
];

// sort by value
items.sort(function (a, b) {
  return (a.value - b.value)
});

console.log(items); 

// sort by name
items.sort(function(a, b) {
  var nameA = a.name.toUpperCase(); // ignore upper and lowercase
  var nameB = b.name.toUpperCase(); // ignore upper and lowercase
  if (nameA < nameB) {
    return -1;
  }
  if (nameA > nameB) {
    return 1;
  }

  // names must be equal
  return 0;
});
var items = [
  { name: 'Edward', value: 21 },
  { name: 'Sharpe', value: 37 },
  { name: 'And', value: 45 },
  { name: 'The', value: -12 },
  { name: 'Magnetic' },
  { name: 'Zeros', value: 37 }
];

// sort by value
items.sort(function (a, b) {
  return (a.value - b.value)
});

console.log(items); 

// sort by name
items.sort(function(a, b) {
  var nameA = a.name.toUpperCase(); // ignore upper and lowercase
  var nameB = b.name.toUpperCase(); // ignore upper and lowercase
  if (nameA < nameB) {
    return -1;
  }
  if (nameA > nameB) {
    return 1;
  }

  // names must be equal
  return 0;
});

示例

创建、显示及排序数组

js
var stringArray = ["Blue", "Humpback", "Beluga"];
var numericStringArray = ["80", "9", "700"];
var numberArray = [40, 1, 5, 200];
var mixedNumericArray = ["80", "9", "700", 40, 1, 5, 200];

function compareNumbers(a, b)
{
  return a - b;
}

console.log('stringArray:' + stringArray.join()); // Blue,Humpback,Beluga
console.log('Sorted:' + stringArray.sort()); // Beluga,Blue,Humpback

console.log('numberArray:' + numberArray.join()); // 40,1,5,200
console.log('Sorted without a compare function:'+ numberArray.sort()); // 1,200,40,5
console.log('Sorted with compareNumbers:'+ numberArray.sort(compareNumbers)); // 1,5,40,200

console.log('numericStringArray:'+ numericStringArray.join()); // 80,9,700
console.log('Sorted without a compare function:'+ numericStringArray.sort()); // 700,80,9
console.log('Sorted with compareNumbers:'+ numericStringArray.sort(compareNumbers)); // 9,80,700

console.log('mixedNumericArray:'+ mixedNumericArray.join()); // 80,9,700,40,1,5,200
console.log('Sorted without a compare function:'+ mixedNumericArray.sort()); // 1,200,40,5,700,80,9
console.log('Sorted with compareNumbers:'+ mixedNumericArray.sort(compareNumbers)); // 1,5,9,40,80,200,700
var stringArray = ["Blue", "Humpback", "Beluga"];
var numericStringArray = ["80", "9", "700"];
var numberArray = [40, 1, 5, 200];
var mixedNumericArray = ["80", "9", "700", 40, 1, 5, 200];

function compareNumbers(a, b)
{
  return a - b;
}

console.log('stringArray:' + stringArray.join()); // Blue,Humpback,Beluga
console.log('Sorted:' + stringArray.sort()); // Beluga,Blue,Humpback

console.log('numberArray:' + numberArray.join()); // 40,1,5,200
console.log('Sorted without a compare function:'+ numberArray.sort()); // 1,200,40,5
console.log('Sorted with compareNumbers:'+ numberArray.sort(compareNumbers)); // 1,5,40,200

console.log('numericStringArray:'+ numericStringArray.join()); // 80,9,700
console.log('Sorted without a compare function:'+ numericStringArray.sort()); // 700,80,9
console.log('Sorted with compareNumbers:'+ numericStringArray.sort(compareNumbers)); // 9,80,700

console.log('mixedNumericArray:'+ mixedNumericArray.join()); // 80,9,700,40,1,5,200
console.log('Sorted without a compare function:'+ mixedNumericArray.sort()); // 1,200,40,5,700,80,9
console.log('Sorted with compareNumbers:'+ mixedNumericArray.sort(compareNumbers)); // 1,5,9,40,80,200,700

对非 ASCII 字符排序

当排序非 ASCII 字符的字符串(如包含类似 e, é, è, a, ä 等字符的字符串)。

一些非英语语言的字符串需要使用 String.localeCompare。这个函数可以将函数排序到正确的顺序。

js
var items = ['réservé', 'premier', 'cliché', 'communiqué', 'café', 'adieu'];

items.sort(function (a, b) {
  return a.localeCompare(b);
});

console.log(items); //  ["adieu", "café", "cliché", "communiqué", "premier", "réservé"]
var items = ['réservé', 'premier', 'cliché', 'communiqué', 'café', 'adieu'];

items.sort(function (a, b) {
  return a.localeCompare(b);
});

console.log(items); //  ["adieu", "café", "cliché", "communiqué", "premier", "réservé"]

使用映射改善排序

compareFunction 可能需要对元素做多次映射以实现排序,尤其当 compareFunction 较为复杂,且元素较多的时候,某些 compareFunction 可能会导致很高的负载。使用 map 辅助排序将会是一个好主意。基本思想是首先将数组中的每个元素比较的实际值取出来,排序后再将数组恢复。

js
// 需要被排序的数组
var list = ['Delta', 'alpha', 'CHARLIE', 'bravo'];

// 对需要排序的数字和位置的临时存储
var mapped = list.map(function(el, i) {
  return { index: i, value: el.toLowerCase() };
})

// 按照多个值排序数组
mapped.sort(function(a, b) {
  return +(a.value > b.value) || +(a.value === b.value) - 1;
});

// 根据索引得到排序的结果
var result = mapped.map(function(el){
  return list[el.index];
});
// 需要被排序的数组
var list = ['Delta', 'alpha', 'CHARLIE', 'bravo'];

// 对需要排序的数字和位置的临时存储
var mapped = list.map(function(el, i) {
  return { index: i, value: el.toLowerCase() };
})

// 按照多个值排序数组
mapped.sort(function(a, b) {
  return +(a.value > b.value) || +(a.value === b.value) - 1;
});

// 根据索引得到排序的结果
var result = mapped.map(function(el){
  return list[el.index];
});

11. toString

toString() 返回一个字符串,表示指定的数组及其元素。

语法

arr.toString()

无参数

返回值

一个表示指定的数组及其元素的字符串。

描述

Array 对象覆盖了ObjecttoString 方法。

对于数组对象,toString 方法连接数组并返回一个字符串,其中包含用逗号分隔的每个数组元素。

当一个数组被作为文本值或者进行字符串连接操作时,将会自动调用其 toString 方法。

无示例

从 JavaScript 1.8.5 (Firefox 4) 开始,和 ECMAScript 第5版语义(semantics)一致,toString() 方法是通用的,可被用于任何对象。

将调用Object.prototype.toString(),并返回结果值。

ES5 方法

forEach

map

every

some

filter

reduce

reduceRight

indexOf

lastIndexOf

ES6 方法

form

of

copyWith

fill

find

findIndex

includes

keys

values

entries

ES7 方法

flat

flatMap