如何在JavaScript中清空数组?
有没有办法来清空数组,如果可能的话.remove()
?
例如,
A = [1,2,3,4];
我怎样才能清空它?
清除现有arrays的方法A
:
方法1
(这是我对这个问题的原始答案)
A = [];
这段代码将variablesA
设置为一个新的空数组。 如果在其他地方没有引用原始数组A
这是完美的,因为这实际上创build了一个全新的(空)数组。 你应该小心这个方法,因为如果你从另一个variables或属性引用这个数组,原来的数组将保持不变。 只有当你只用原始variablesA
引用数组时才使用它。
这也是最快的解决scheme。
此代码示例显示使用此方法时可能遇到的问题:
var arr1 = ['a','b','c','d','e','f']; var arr2 = arr1; // Reference arr1 by another variable arr1 = []; console.log(arr2); // Output ['a','b','c','d','e','f']
方法2 (如Matthew Crumley所build议的)
A.length = 0
这将通过将其长度设置为0来清除现有的数组。有些人认为,这可能不适用于JavaScript的所有实现,但事实certificate情况并非如此。 在ECMAScript 5中使用“strict mode”时,它也可以工作,因为数组的length属性是读/写属性。
方法3 (由Anthony 提出 )
A.splice(0,A.length)
使用.splice()
将完美工作,但由于.splice()
函数将返回一个包含所有已删除项目的数组,它实际上将返回原始数组的副本。 基准testing表明,这对性能没有任何影响。
方法4 (如tanguy_k所build议的)
while(A.length > 0) { A.pop(); }
这个解决scheme不是很简洁,也是最慢的解决scheme,与原来的答案中引用的早期基准相反。
性能
在清除现有数组的所有方法中,方法2和3的性能非常相似,比方法4快很多。请参阅此基准 。
Diadistis在下面的回答中指出,用于确定上述四种方法的性能的最初的基准是有缺陷的。 原来的基准重新使用清零的数组,所以第二次迭代清除了一个已经为空的数组。
以下基准修复了这个缺陷: http : //jsben.ch/#/hyj65 。 它清楚地显示方法#2(长度属性)和#3(拼接)是最快的(不包括不改变原始数组的方法#1)。
这一直是一个热门话题,引起了很多争议。 实际上有很多正确的答案,因为这个答案已经被标记为很长一段时间的接受答案,所以我将在这里包括所有的方法。 如果您对这个答案投票,请提出其他答案,我也参考。
如果您需要保留原始数组,因为您有其他引用,应该更新它,您可以通过将其长度设置为零来清除它,而无需创build新数组:
A.length = 0;
这里最快的工作实现,同时保持相同的数组 :
Array.prototype.clear = function() { while (this.length) { this.pop(); } };
FYI Map定义了clear()
所以对于Array也有clear()
逻辑。
或者作为Underscore.js混搭 :
_.mixin({ clearArray: function(array) { while (array.length) { array.pop(); } } });
还是一个简单的function:
function clearArray(array) { while (array.length) { array.pop(); } }
FYI不能简化为while (array.pop())
:testing将失败。
和它一起的testing:
describe('Array', function() { it('should clear the array', function() { var array = [1, 2, 3, 4, 5]; array.clear(); expect(array.length).toEqual(0); expect(array[0]).toEqual(undefined); expect(array[4]).toEqual(undefined); // Even with undefined or null inside array = [1, undefined, 3, null, 5]; array.clear(); expect(array.length).toEqual(0); expect(array[0]).toEqual(undefined); expect(array[4]).toEqual(undefined); }); });
这里更新的jsPerf: http : //jsperf.com/array-destroy/32 http://jsperf.com/array-destroy/152
更多的跨浏览器友好和更优化的解决scheme将是使用splice
方法清空数组A的内容,如下所示:
A.splice(0, A.length);
性能testing:
http://jsperf.com/array-clear-methods/3
a = []; // 37% slower a.length = 0; // 89% slower a.splice(0, a.length) // 97% slower while (a.length > 0) { a.pop(); } // Fastest
现在不less于2739个答案的答案是误导和不正确的。
问题是:“你如何清空你现有的arrays? 例如对于A = [1,2,3,4]
。
-
说“
A = []
是答案”是无知的,绝对不正确。[] == []
是错误的 。这是因为这两个arrays是两个独立的个体对象,拥有自己的两个身份,在数字世界占据着自己的空间,每个对象都有自己的空间。
假设你的母亲要你清空垃圾桶。
- 如果你已经完成了你所要求的,你就不会带来新的。
- 相反,你清空垃圾桶。
- 你不用一个新的空jarreplace填满的jar子,而且你不把填充的jar子上的标签“A”粘到新的jar子上,如
A = [1,2,3,4]; A = [];
A = [1,2,3,4]; A = [];
清空数组对象是有史以来最简单的事情:
A.length = 0;
这样,“A”下的jar头不仅是空的,而且还像新的一样干净!
-
此外,你不需要手动清除垃圾,直到jar子是空的! 你被要求在一个回合中完全清空现有的垃圾箱,而不是拾起垃圾直到垃圾箱变空,如下:
while(A.length > 0) { A.pop(); }
-
也不要把你的左手放在垃圾桶的底部,把它放在右边,以便能够把它的内容拉出来,如下所示:
A.splice(0, A.length);
不,你被要求清空它:
A.length = 0;
这是正确清空给定JavaScript数组内容的唯一代码。
您可以将其添加到您的JavaScript文件,以允许您的数组“清除”:
Array.prototype.clear = function() { this.splice(0, this.length); };
那么你可以像这样使用它:
var list = [1, 2, 3]; list.clear();
或者如果你想确保你不摧毁一些东西:
if (!Array.prototype.clear) { Array.prototype.clear = function() { this.splice(0, this.length); }; }
很多人认为你不应该修改本地对象(比如Array),我倾向于同意。 请谨慎决定如何处理这个问题。
Array.prototype.clear = function() { this.length = 0; };
并调用它: array.clear();
=)
如果你对内存分配感兴趣,你可以使用像jsfiddle这样的方法来将每种方法与chrome dev工具的时间表选项卡结合起来。 您需要使用底部的垃圾箱图标来清除arrays后强制进行垃圾回收。 这应该给你一个更确定的答案为您select的浏览器。 这里有很多答案是老的,我不会依赖他们,而是在@ tanguy_k的回答中进行testing。
(对于上述标签的介绍,你可以在这里查看 )
Stackoverflow迫使我复制jsfiddle所以这里是:
<html> <script> var size = 1000*100 window.onload = function() { document.getElementById("quantifier").value = size } function scaffold() { console.log("processing Scaffold..."); a = new Array } function start() { size = document.getElementById("quantifier").value console.log("Starting... quantifier is " + size); console.log("starting test") for (i=0; i<size; i++){ a[i]="something" } console.log("done...") } function tearDown() { console.log("processing teardown"); a.length=0 } </script> <body> <span style="color:green;">Quantifier:</span> <input id="quantifier" style="color:green;" type="text"></input> <button onclick="scaffold()">Scaffold</button> <button onclick="start()">Start</button> <button onclick="tearDown()">Clean</button> <br/> </body> </html>
你应该注意到,它可能取决于数组元素的types,因为JavaScriptpipe理string的方式与其他基本types不同,更不用说数组对象了。 该types可能会影响发生的事情。
关于这个问题,有很多困惑和错误的信息,包括回答和评论中的stream行/转换performance。 while / pop解决scheme具有(如预期的) 最差的性能 。 实际发生的情况是,对于在循环中运行代码段的每个样本,设置只运行一次。 例如:
var arr = []; for (var i = 0; i < 100; i++) { arr.push(Math.random()); } for (var j = 0; j < 1000; j++) { while (arr.length > 0) { arr.pop(); // this executes 100 times, not 100000 } }
我创build了一个可以正常工作的新testing:
http://jsperf.com/empty-javascript-array-redux
警告:即使在这个版本的testing中,也不能真正看到真正的差异,因为克隆数组占用了大部分testing时间。 它仍然表明, splice
是清除数组最快的方式(不考虑[]
因为虽然它是最快的,它实际上并没有清除现有的数组)。
A.splice(0);
我只是对我正在编写的一些代码做了这个。 它清除了数组。
使用Jan最初build议的修改版本:
var originalLength = A.length; for (var i = originalLength; i > 0; i--) { A.pop(); }
如果你正在使用
a = [];
要么
a.length = 0;
那么你只是创build新的数组,指向特定的内存位置。 这意味着前面的数组将保留在内存中,直到垃圾收集。 所以它不是更好的使用方法。 而不是这两个解决scheme更好。
a.splice(0,a.length)
和
while(a.length > 0) { a.pop(); }
根据kenshou.html的回答,第二种方法更快。
如果你使用常量,那么你别无select:
const numbers = [1, 2, 3]
您不能重新分配:
numbers = []
你只能截断:
numbers.length = 0
你可以很容易地创build一个函数来为你做这件事,改变它的长度,甚至把它作为remove()函数添加到本地数组以便重用。
想象一下你有这个数组:
var arr = [1, 2, 3, 4, 5]; //the array
好的,只需简单地运行这个:
arr.length = 0; //change the length
结果是:
[] //result
简单的方法来清空数组…
也使用循环这不是必要的,但只是另一种方式来做到这一点:
/* could be arr.pop() or arr.splice(0) don't need to return as main array get changed */ function emptyArr(arr) { while(arr.length) { arr.shift(); } }
你也可以考虑一些棘手的方法,例如:
arr.splice(0, arr.length); //[]
所以如果arr有5个项目,它将从0接合5个项目,这意味着数组中没有任何东西。
还有其他一些方法,例如简单地重新分配数组:
arr = []; //[]
如果你看看数组的function,还有很多其他的方法来做到这一点,但最推荐的方法可能是改变长度。
正如我刚才所说,你也可以将原型remove()作为你的问题的答案。 您可以简单地select上述方法之一,并将其原型化为JavaScript中的Array对象,如下所示:
Array.prototype.remove = Array.prototype.remove || function() { this.splice(0, this.length); };
你可以简单地调用它来清空你的javascript应用程序中的任何数组:
arr.remove(); //[]
若要清空数组的当前内存位置,请使用: 'myArray.length = 0'
或'myArray.pop() UN-till its length is 0'
-
length
:popup数组的长度为指定大小。 -
pop()
:pop方法从数组的当前内存地址中删除最后一个元素。
例:
var mainArr = new Array(); mainArr = ['1', '2', '3', '4']; var refArr = mainArr; console.log('Current', mainArr, 'Refered', refArr); refArr.length = 3; console.log('Length: ~ Current', mainArr, 'Refered', refArr); mainArr.push('0'); console.log('Push to the End of Current Array Memory Location \n~ Current', mainArr, 'Refered', refArr); mainArr.poptill_length(0); console.log('Empty Array \n~ Current', mainArr, 'Refered', refArr); Array.prototype.poptill_length = function (e) { while (this.length) { if( this.length == e ) break; console.log('removed last element:', this.pop()); } };
使用slice()
:当你想克隆一个新的内存地址给定数组的数组,所以cloneArr的任何修改都不会影响实际的数组。
空arrays与新的内存地址使用:slice(0,0)
var cloneArr = mainArr.slice(0, 3); console.log('Main', mainArr, '\tCloned', cloneArr); cloneArr.length = 0; // Clears current memory location of an array. console.log('Main', mainArr, '\tCloned', cloneArr);
用新的内存位置分配新的空数组[]
。
mainArr = []; // a new empty array is addressed to mainArr.
我很惊讶没有人提出这个问题呢:
let xs = [1,2,3,4]; for (let i in xs) delete xs[i];
这产生了一个与其他解决scheme完全不同的状态的数组。 从某种意义上说,arrays已经被“清空”了:
xs => Array [ <4 empty slots> ] [...xs] => Array [ undefined, undefined, undefined, undefined ] xs.length => 4 xs[0] => ReferenceError: reference to undefined property xs[0]
你可以用[,,,,]
或Array(4)
生成等价的数组,
如果您需要清空Angular 2+ FormArray,请使用下面的代码。
public emptyFormArray(formArray:FormArray) { for (let i = formArray.controls.length - 1; i >= 0; i--) { formArray.removeAt(i); } }