题 如何将某些内容附加到数组中?


如何在JavaScript中将对象(如字符串或数字)附加到数组中?


2880


起源




答案:


使用 push() 函数附加到数组:

// initialize array
var arr = [
    "Hi",
    "Hello",
    "Bonjour"
];

// append new value to the array
arr.push("Hola");

console.log(arr);

会打印

["Hi", "Hello", "Bonjour", "Hola"]

你可以使用 push() 函数在单个调用中向一个数组附加多个值:

// initialize array
var arr = [ "Hi", "Hello", "Bonjour", "Hola" ];

// append multiple values to the array
arr.push("Salut", "Hey");

// display all values
for (var i = 0; i < arr.length; i++) {
    console.log(arr[i]);
}

会打印

Hi
Hello
Bonjour
Hola 
Salut
Hey

更新

如果要将一个数组的项添加到另一个数组,则可以使用 firstArray.concat(secondArray)

var arr = [
    "apple",
    "banana",
    "cherry"
];

arr = arr.concat([
    "dragonfruit",
    "elderberry",
    "fig"
]);

console.log(arr);

会打印

["apple", "banana", "cherry", "dragonfruit", "elderberry", "fig"]

3386



注意.push的返回值不是数组(或者是新的,如.concat),而是表示数组新长度的整数。 - Jay
@RST:不要用 for 完全(使用 .forEach)。 - Robert Siemer
我会说原始代码很好。无需任何优化访问权限 length 属性。口译员在这方面做得非常出色,无论你是否优化它,它都不会对真实世界产生任何影响。如果您的阵列变得如此巨大以至于优化 .length 实际上会有所帮助,很可能数组不再是正确的数据结构。运用 forEach 有它的优点,但是高度怀疑增加的性能将是其中之一,因为每次迭代的函数调用会产生成本而不会节省任何成本。 - Stijn de Witt
@RobertSiemer length 每次调用它时都不会计算数组的属性,它是存储在数组中的变量 array 对象,仅在更改阵列时更新。因此,实际上没有包括的性能成本 arr.length 在里面 for 条件。 - mikeyq6
@Mojimi作为初学者,请忽略任何关于边缘情况下的性能问题的建议。使用更具表现力的语法。随着时间的推移,Javascript运行时添加了越来越多的优化 - 它们将内联 forEach 回调函数(其中一些可能已经这样做了)并且生成的机器代码没有区别,如果函数被调用的频率足以被编译而不是由运行时解释。实际上,对于任何非汇编语言都是一样的建议。 - Mörre


如果你只是附加一个变量,那么 push() 工作得很好。如果需要追加另一个数组,请使用 concat()

var ar1 = [1, 2, 3];
var ar2 = [4, 5, 6];

var ar3 = ar1.concat(ar2);

alert(ar1);
alert(ar2);
alert(ar3);

吐出来的:

"1,2,3"
"4,5,6"
"1,2,3,4,5,6"

concat不影响 ar1 和 ar2 除非重新分配,例如:

ar1 = ar1.concat(ar2);
alert(ar1);

将显示:

"1,2,3,4,5,6"

很多很棒的信息 这里


954



只是确保人们捕获var ar3 = ar1.concat(ar2);部分。 ar1.concat(ar2)不会将值保存到ar1中。您必须通过将其分配给ar3或返回到ar1来捕获它,例如:ar1 = ar1.concat(ar2); - vbullinger
我实际上说这是错误的答案。问题是 How do I append to an array in JavaScript?但是 concat 其实 创建 一个 新 阵列。这是一个重要的区别!相反,我会说Omnimike下面的答案实际上是最好的答案:使用 Push.apply 将整个数组推送到现有数组而不创建新数组。 - Stijn de Witt
@StijndeWitt你仍然可以在不创建新数组的情况下追加,如上一条评论中所述 ar1 = ar1.concat(ar2); 将附加 ar1 - cameronjonesweb
@cameronjonesweb实际上,它所做的是创建一个内容与之相同的新数组 ar1,追加 ar2 然后返回新数组。只需省略作业部分(ar1 = ...)从那行代码,你会看到 原版的  ar1 事实上并没有改变。如果你想避免复制,你需要 push。相信,别相信我 文档:“concat()方法返回一个新数组”文档中的第一句话 concat。 - Stijn de Witt
@StijndeWitt你是对的。但是,看一下它的另一种方式,.push只能在添加单个变量/对象时运行良好,但是在添加数组时会遇到麻烦, ar2 以上是反正的。的结果 .push 在场景中将是 = [ar1, [ar2]]。 .concat解决了这个问题,但牺牲了速度并创建了一个新阵列。使用 .push 正确地在数组中追加,首先循环包含的元素并推送每个元素。 ar2.forEach(each => { ar1.push(each); }); - Ade


一些快速基准测试(每个测试= 500k附加元素,结果是多次运行的平均值)显示如下:

Firefox 3.6(Mac):

  • 小阵列: arr[arr.length] = b 是比较快的 (300ms vs. 800ms)
  • 大型阵列: arr.push(b) 是比较快的 (500ms vs. 900ms)

Safari 5.0(Mac):

  • 小阵列: arr[arr.length] = b 是比较快的 (90ms对115ms)
  • 大型阵列: arr[arr.length] = b 是比较快的 (160毫秒对185毫秒)

谷歌Chrome 6.0(Mac):

  • 小阵列: 没有显着差异 (Chrome很快!只有~38ms !!)
  • 大型阵列: 没有显着差异 (160毫秒)

我喜欢 arr.push() 语法更好,但我想我会更好 arr[arr.length] 版本,至少以原始速度。我很乐意看到IE运行的结果。


我的基准测试循环:

function arrpush_small() {
    var arr1 = [];
    for (a = 0; a < 100; a++)
    {
        arr1 = [];
        for (i = 0; i < 5000; i++)
        {
            arr1.push('elem' + i);
        }
    }
}

function arrlen_small() {
    var arr2 = [];
    for (b = 0; b < 100; b++)
    {
        arr2 = [];
        for (j = 0; j < 5000; j++)
        {
            arr2[arr2.length] = 'elem' + j;
        }
    }
}


function arrpush_large() {
    var arr1 = [];
    for (i = 0; i < 500000; i++)
    {
        arr1.push('elem' + i);
    }
}

function arrlen_large() {
    var arr2 = [];
    for (j = 0; j < 500000; j++)
    {
        arr2[arr2.length] = 'elem' + j;
    }
}

370



问题是.length是一个存储值还是在被访问时计算,因为如果后一个为真,则可能是使用一个简单变量(如j)作为索引值可能更快 - yoel halb
静电+1,你如何制作这些基准? - mko
@yozloy: jsperf.com 是你的朋友 :) - Jens Roland
这种类型的基准测试很有趣,但具有讽刺意味的是,在提高应用程在任何周期中,渲染循环都要昂贵得多。此外,浏览器开发人员不断优化JS语言的这些内部。这就是我的downvote的原因,而不是这个答案的有趣之处。如果你想要更快的应用程序,首先是基准测试并看看要改变什么 - 在100次中有99次不会像这个测试所显示的那样。通常是它可怜的开发人员JS / CSS - 而不是浏览器内部使它变慢。 - LessQuesar
我同意LessQuesar尽可能坚持内置。微观优化本身并不坏,但他认为浏览器总能提高发动机转速是正确的。举个例子:在撰写本文时,对于上面列出的所有技术,每浏览器的性能几乎相同。几年前这么小的收获意味着很多大惊小怪,现在却没有收获。 - Beejor


我认为值得一提的是,可以使用多个参数调用push,这些参数将按顺序附加到数组中。例如:

var arr = ['first'];
arr.push('second', 'third');
console.log(arr); // ['first', 'second', 'third']

因此,您可以使用push.apply将数组附加到另​​一个数组,如下所示:

arr.push.apply(arr, ['forth', 'fifth']);
console.log(arr); // ['first', 'second', 'third', 'forth', 'fifth']

注释ES5 有更多关于究竟是什么的信息  和 应用 做。

2016年更新:用 传播,你不需要那个 apply 更像,像:

arr.push(...['fourth', 'fifth']);
console.log(arr) // ['first', 'second', 'third', 'fourth', 'fifth']

260



在不创建新数组的情况下附加项目数组的最佳答案。 - Gabriel Littman
@GabrielLittman特别是因为附加到数组,恕我直言,应该修改数组,而不是创建一个新数组。 - Juan Mendes
我喜欢push.apply版本,宁愿使用 Array.prototype.push.apply() 虽然。 - Michael
有时保留对数组的引用很重要 - 例如,当一个数组在某个控制器的作用域中并且某些服务需要更新数组中的数据以供显示时,在AngularJs中。这就是为什么我在推动这个解决方案。 - see sharper


您可以使用 push 和 apply 函数附加两个数组。

var array1 = [11, 32, 75];
var array2 = [99, 67, 34];

Array.prototype.push.apply(array1, array2);

它会附加 array2 至 array1。现在 array1 包含 [11, 32, 75, 99, 67, 34]。 这段代码比编写简单得多 for 循环复制数组中的每个项目。


64



这就是我所需要的,保持原始数组引用 - amit bakle


使用 concat

a = [1, 2, 3];
b = [3, 4, 5];
a = a.concat(b);

a 现在包含所有元素, [1, 2, 3, 3, 4, 5]

参考: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/concat


35





如果 arr 是一个数组,和 val 是您要添加的值:

arr.push(val);

例如。

arr = ['a', 'b', 'c'];
arr.push('d');
console.log(arr);

将记录:

['a', 'b', 'c', 'd']

34





随着新的ES6 传播运营商,使用连接两个数组 push 变得更容易:

var arr = [1, 2, 3, 4, 5];
var arr2 = [6, 7, 8, 9, 10];
arr.push(...arr2);
console.log(arr); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

这增加了内容 arr2 到了最后 arr

Babel REPL示例


33





如果你想追加两个数组 -

var a = ['a', 'b'];
var b = ['c', 'd'];

然后你可以使用:

var c = a.concat(b);

如果你想添加记录 g 阵列(var a=[])然后你可以使用:

a.push('g');

27





Javascript用 ECMAScript 5 现在大多数浏览器都支持的标准,你可以使用 apply() 追加 array1 至 array2

var array1 = [3, 4, 5];
var array2 = [1, 2];

Array.prototype.push.apply(array2, array1);

console.log(array2); // [1, 2, 3, 4, 5]

Javascript用 ECMAScript 6 Chrome和FF以及IE Edge支持的标准,你可以使用 spread运营商:

"use strict";
let array1 = [3, 4, 5];
let array2 = [1, 2];

array2.push(...array1);

console.log(array2); // [1, 2, 3, 4, 5]

spread 运营商将取代 array2.push(...array1); 同 array2.push(3, 4, 5); 当浏览器在思考逻辑时。

奖励点

如果你想创造 另一个 变量存储来自两个数组的所有项目,您可以这样做:

ES5  var combinedArray = array1.concat(array2);

ES6  const combinedArray = [...array1, ...array2]

传播运营商(...)是从一个集合中分散所有项目。


24