在 JavaScript 中复制数组的最快方法 - 切片与“for”循环
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3978492/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Fastest way to duplicate an array in JavaScript - slice vs. 'for' loop
提问by Marco Demaio
In order to duplicate an array in JavaScript: which of the following is faster to use?
为了在 JavaScript 中复制数组:以下哪个使用起来更快?
Slice method
切片法
var dup_array = original_array.slice();
For
loop
For
环形
for(var i = 0, len = original_array.length; i < len; ++i)
dup_array[i] = original_array[i];
I know both ways do only a shallow copy: if original_array contains references to objects, objects won't be cloned, but only the references will be copied, and therefore both arrays will have references to the same objects. But this is not the point of this question.
我知道这两种方法都只做一个浅拷贝:如果 original_array 包含对对象的引用,则不会克隆对象,但只会复制引用,因此两个数组都将引用相同的对象。但这不是这个问题的重点。
I'm asking only about speed.
我只问速度。
回答by Dan
There are at least 5(!) ways to clone an array:
至少有5 种(!) 方法可以克隆数组:
- loop
- slice
- Array.from()
- concat
- spread operator (FASTEST)
- 环形
- 片
- Array.from()
- 连接
- 展开运算符(最快)
There has been a huuuge BENCHMARKS thread, providing following information:
有一个huuuge BENCHMARKS线程,提供以下信息:
for blinkbrowsers
slice()
is the fastest method,concat()
is a bit slower, andwhile loop
is 2.4x slower.for other browsers
while loop
is the fastest method, since those browsers don't have internal optimizations forslice
andconcat
.
对于blink浏览器
slice()
是最快的方法,concat()
速度稍慢,while loop
慢2.4 倍。对于其他浏览器
while loop
是最快的方法,因为这些浏览器没有对slice
和进行内部优化concat
。
This remains true in Jul 2016.
2016 年 7 月仍然如此。
Below are simple scripts that you can copy-paste into your browser's console and run several times to see the picture. They output milliseconds, lower is better.
下面是简单的脚本,您可以将它们复制粘贴到浏览器的控制台中并运行几次以查看图片。他们输出毫秒,越低越好。
while loop
while 循环
n = 1000*1000;
start = + new Date();
a = Array(n);
b = Array(n);
i = a.length;
while(i--) b[i] = a[i];
console.log(new Date() - start);
slice
片
n = 1000*1000;
start = + new Date();
a = Array(n);
b = a.slice();
console.log(new Date() - start);
Please note that these methods will clone the Array object itself, array contents however are copied by reference and are not deep cloned.
请注意,这些方法将克隆 Array 对象本身,但是数组内容是通过引用复制的,而不是深度克隆。
origAr == clonedArr //returns false
origAr[0] == clonedArr[0] //returns true
回答by KingKongFrog
Technically slice
isthe fastest way. However, it is even faster if you add the 0
begin index.
从技术上讲slice
是最快的方法。但是,如果添加0
开始索引,速度会更快。
myArray.slice(0);
is faster than
比
myArray.slice();
回答by Yukulélé
what about es6 way?
es6方式怎么样?
arr2 = [...arr1];
回答by Vladimir Kharlampidi
Easiest way to deep clone Array or Object:
深度克隆数组或对象的最简单方法:
var dup_array = JSON.parse(JSON.stringify(original_array))
回答by Sajjad Shirazy
var cloned_array = [].concat(target_array);
回答by lincolnk
I put together a quick demo: http://jsbin.com/agugo3/edit
我整理了一个快速演示:http: //jsbin.com/agugo3/edit
My results on Internet Explorer 8 are 156, 782, and 750, which would indicate slice
is much faster in this case.
我在 Internet Explorer 8 上的结果是 156、782 和 750,这表明slice
在这种情况下要快得多。
回答by Redu
a.map(e => e)
is another alternative for this job. As of today .map()
is very fast (almost as fast as .slice(0)
) in Firefox, but not in Chrome.
a.map(e => e)
是这项工作的另一种选择。截至今天.map()
,.slice(0)
在 Firefox 中非常快(几乎和 一样快),但在 Chrome 中则不然。
On the other hand, if an array is multi-dimensional, since arrays are objects and objects are reference types, none of the slice or concat methods will be a cure... So one proper way of cloning an array is an invention of Array.prototype.clone()
as follows.
另一方面,如果数组是多维的,因为数组是对象,对象是引用类型,所以 slice 或 concat 方法都不能治愈......所以克隆数组的一种正确方法是Array.prototype.clone()
as的发明如下。
Array.prototype.clone = function(){
return this.map(e => Array.isArray(e) ? e.clone() : e);
};
var arr = [ 1, 2, 3, 4, [ 1, 2, [ 1, 2, 3 ], 4 , 5], 6 ],
brr = arr.clone();
brr[4][2][1] = "two";
console.log(JSON.stringify(arr));
console.log(JSON.stringify(brr));
回答by Lior Elrom
Fastest Way to Clone an Array
克隆阵列的最快方法
I made this very plain utility function to test the time that it takes to clone an array. It is not 100% reliable however it can give you a bulk idea as for how long it takes to clone an existing array:
我制作了这个非常简单的实用函数来测试克隆数组所需的时间。它不是 100% 可靠的,但是它可以让您大致了解克隆现有数组需要多长时间:
function clone(fn) {
const arr = [...Array(1000000)];
console.time('timer');
fn(arr);
console.timeEnd('timer');
}
And tested different approach:
并测试了不同的方法:
1) 5.79ms -> clone(arr => Object.values(arr));
2) 7.23ms -> clone(arr => [].concat(arr));
3) 9.13ms -> clone(arr => arr.slice());
4) 24.04ms -> clone(arr => { const a = []; for (let val of arr) { a.push(val); } return a; });
5) 30.02ms -> clone(arr => [...arr]);
6) 39.72ms -> clone(arr => JSON.parse(JSON.stringify(arr)));
7) 99.80ms -> clone(arr => arr.map(i => i));
8) 259.29ms -> clone(arr => Object.assign([], arr));
9) Maximum call stack size exceeded -> clone(arr => Array.of(...arr));
UPDATE:
Note: out of them all, the only way to deep clone an array is by using JSON.parse(JSON.stringify(arr))
.
That said, do not use the above if your array might include functions as it will return null
.
Thank you @GilEpshtain for this update.
更新:
注意:在所有这些中,深度克隆数组的唯一方法是使用JSON.parse(JSON.stringify(arr))
.
也就是说,如果您的数组可能包含函数,请不要使用上述内容,因为它将返回null
.
感谢 @GilEpshtain 提供此更新。
回答by serv-inc
As @Dan said "This answer becomes outdated fast. Use benchmarksto check the actual situation", there is one specific answer from jsperf that has not had an answer for itself: while:
正如@Dan 所说的“这个答案很快就过时了。使用基准测试来检查实际情况”,jsperf 有一个特定的答案本身没有答案:while:
var i = a.length;
while(i--) { b[i] = a[i]; }
had 960,589 ops/sec with the runnerup a.concat()
at 578,129 ops/sec, which is 60%.
有 960,589 次操作/秒,亚军a.concat()
为 578,129 次操作/秒,占 60%。
This is the lastest Firefox (40) 64 bit.
这是最新的 Firefox (40) 64 位。
@aleclarson created a new, more reliable benchmark.
@aleclarson 创建了一个新的、更可靠的基准。
回答by Margus
Take a look at: link. It's not about speed, but comfort. Besides as you can see you can only use slice(0)on primitive types.
看看:链接。这不是关于速度,而是关于舒适。此外,正如您所看到的,您只能在原始类型上使用slice(0)。
To make an independent copy of an array rather than a copy of the refence to it, you can use the array slice method.
要制作数组的独立副本而不是对它的引用的副本,您可以使用数组切片方法。
Example:
例子:
To make an independent copy of an array rather than a copy of the refence to it, you can use the array slice method.
var oldArray = ["mip", "map", "mop"]; var newArray = oldArray.slice();
To copy or clone an object :
function cloneObject(source) { for (i in source) { if (typeof source[i] == 'source') { this[i] = new cloneObject(source[i]); } else{ this[i] = source[i]; } } } var obj1= {bla:'blabla',foo:'foofoo',etc:'etc'}; var obj2= new cloneObject(obj1);
要制作数组的独立副本而不是对它的引用的副本,您可以使用数组切片方法。
var oldArray = ["mip", "map", "mop"]; var newArray = oldArray.slice();
复制或克隆一个对象:
function cloneObject(source) { for (i in source) { if (typeof source[i] == 'source') { this[i] = new cloneObject(source[i]); } else{ this[i] = source[i]; } } } var obj1= {bla:'blabla',foo:'foofoo',etc:'etc'}; var obj2= new cloneObject(obj1);
Source: link
来源:链接