将多个元素推入数组

496

我想将多个元素作为一个数组推送,但是出现了错误:

> a = []
[]
> a.push.apply(null, [1,2])
TypeError: Array.prototype.push called on null or undefined

我希望做类似于在 Ruby 中所做的事情,我认为 apply 就像是 *

>> a = []
=> []
>> a.push(*[1,2])
=> [1, 2]

你的例子几乎是正确的,只需要将null替换为a,像这样:a.push.apply(a, [1,2]) - undefined
10个回答

858

您可以通过以下方式将多个元素推入数组中

var a = [];
    
a.push(1, 2, 3);

console.log(a);


1
这个答案和被选中的答案产生了不同的,也许是意料之外的结果。a.push(1)与a.push([1])。 - oevna
3
为什么这篇回答的票数比被采纳的答案还多,能有人解释一下吗?它可能更简单,但不够灵活。如果你想合并两个数组,这个方法行不通。 - Tigerware
3
如果你想合并两个数组,只需使用 array.concat()。 - Florent Arlandis
2
@FlorentArlandis array.concat无法将第二个数组添加到第一个数组中。它会创建一个新的数组。我知道这很相似。展开运算符才是我要找的。只需查看其他答案和评论以获取详细信息即可。 - Tigerware
10
ES6现在允许您执行类似于array1.push(...array2)的操作,这与array1.push(array2[0], array2[1], array2[2])完全相同,除了数组array2中元素数量的限制(约为100,000)。 - vantrung -cuncon

690

现在在ECMAScript2015(也称为ES6)中,您可以使用展开运算符一次性添加多个项目:

var arr = [1];
var newItems = [2, 3];
arr.push(...newItems);
console.log(arr);

参阅Kangax的ES6兼容性表格以查看浏览器的兼容情况。


54
这真是太棒了!而且,如果你使用 TypeScript 编写它,它将编译为 "push.apply",这样就可以向后兼容了。 - Chris
2
这个有数组大小限制。尝试使用大数组。你会得到异常。 - SalientBrain
我想了解一下关于大小限制的更多信息,所以我试了一下。a = []; b = []; for (let i = 0; i < 1000000; i++) { b.push(i); } a.push(...(b.slice(0, 130000))); 这确实给我造成了一个错误。"Uncaught RangeError: Maximum call stack size exceeded" 这个限制可能取决于数组中元素的大小,而不仅仅是元素的数量。这只是一个猜测。它可能取决于环境。也只是一个猜测。我还没有尝试查找文档。 - undefined
这个操作与分别使用每个元素相比,性能如何? - undefined

316
使用 applycall 函数调用对象的大多数函数时,context 参数必须是您正在处理的对象。
在这种情况下,您需要使用 a.push.apply(a, [1,2])(或更正确地说是 Array.prototype.push.apply(a, [1,2]))。

1
这种方法可以推送多少个元素?我知道JavaScript有参数限制,使用“apply”函数时是否也是如此? - David Callanan
1
我相信在旧版浏览器中是65,535,在现代浏览器中几乎没有限制(4B)。 - Niet the Dark Absol
在节点(v20.4.0)的默认设置中,限制相当低。我没有找到确切的值,但大约在1<<16和1<<17之间。 - John Williams

95

作为其中一种替代方案,你可以使用Array.concat

var result = a.concat(b);

这会创建并返回一个新数组,而不是将项目推入同一数组。如果您不想修改源数组而是要制作一个浅拷贝副本,则这可能很有用。


31
Array.prototype.concat 返回一个新数组。 - suricactus
12
他想要将元素添加到已有的数组中,因此使用 Array.prototype.push.apply(arr1, arr2) 是正确的答案,因为使用 arr1.concat(arr2) 会创建一个新数组。 - suricactus
4
"@suricactus arr1 = arr1.concat(arr2) 这并不是什么大不了的事情,看起来更加简洁。将新元素添加到旧数组中或者用新数组替换旧数组取决于你的需求。如果你处理的是超过1000万个元素的大数据,将新元素添加到旧数组中会更快一些;如果你处理的是比较小的数据块,速度上几乎没有区别。两种选择都是完全合法的。" - VisioN
5
prototype.push.apply 只调用一次 push 方法。上面的区别不是关于速度,而是关于就地修改和创建新数组的区别。如果我有一个方法,它需要就地修改一个数组,那该怎么办呢?即使使用 VisionN 的代码,concat 方法也不可能起作用,因为它不会修改函数调用者的变量。 - coderforlife
1
a = a.concat(b) is still a shorter syntax than Array.prototype.push.apply(arr1, arr2) - Aizzat Suhardi
显示剩余5条评论

73
如果你想添加多个项目,可以使用 Array.push() 与扩展运算符一起:
a = [1,2]
b = [3,4,5,6]
a.push(...b)

结果将是

a === [1,2,3,4,5,6]

这种方法推送元素是否有数量限制? - David Callanan
no @DavidCallanan - Sarthak Gupta
这似乎是canac在2016年早些时候对此问题的回答的重复。https://dev59.com/cWUq5IYBdhLWcg3wKtbs#35167699 - maurice
我在node v16.20.1中进行了测试,尝试一次性推送1<<17个元素会抛出异常。1<<16个元素是可以的。 - John Williams

29
如果你想要在ECMAScript 2015(即ES6, ES2015)中找到一个替代Array.concat方法的话,它和它一样不会修改数组,但会返回新的数组。你可以使用展开运算符来实现: ```javascript [...arr1, ...arr2] ```


```javascript [...arr1, ...arr2] ```
var arr = [1];
var newItems = [2, 3];
var newerItems = [4, 5];
var newArr = [...arr, ...newItems, ...newerItems];
console.log(newArr);

请注意,这与push方法不同,因为push方法会更改数组。

如果您想查看某些ES2015功能在您的浏览器中是否可用,请查看Kangax的兼容性表

如果您不想等待浏览器支持并且想在生产环境中使用ES2015,则可以使用Babel或类似的转换器。


4

我曾有同样的疑问,在我的情况下,一个更简单的解决方案对我起了作用:

let array = []
array.push(1, 2, 4, "string", new Object())
console.log(array)
// logs [ 1, 2, 4, 'string', {} ]

比什么更容易?这是这个10年前的答案中给出的确切方法。 - miken32
复制相同的评论会给你积分吗?我试图做出贡献,其他人... - Jose Velasco

4
更简单的方法是:
a = []
a.push(1,2,3)

另一种方式是

a = [...a, 4,5,6]

如果你想要创建另一个数组

const b = a.concat(7,8,9)

2
比什么更容易?这些方法是在这个10年前的答案这个7年前的答案中给出的确切方法。 - miken32

0
假设你有一个包含前十个数字的数组,但缺少一个数字,比如说6。你可以使用以下代码将其插入到索引5处的数组中。

function insert(array, index, obj) {
  return [...array.slice(0,index), obj, ...array.slice(index)]
}

let arr = [1,2,3,4,5,7,8,9,0]
arr = insert(arr, 5, 6)
console.log(arr)


0

一次性推送多个对象通常取决于您如何声明数组

这是我的做法

//declaration
productList= [] as  any;

现在 push 记录

this.productList.push(obj.lenght, obj2.lenght, items);

2
“类型断言表达式只能在TypeScript文件中使用。”这是VS Code关于关键字any的提示。 - Ramon Dias

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接