如何在JavaScript中清空一个数组?

2193

有没有一种方法可以清空一个数组,如果可以的话可能使用 .remove()

例如,

A = [1,2,3,4];

我该如何清空它?


1
这里有一个带有不同可能性的基准测试:http://jsben.ch/#/7QyI1 - EscapeNetscape
17个回答

19
Array.prototype.clear = function() {
    this.length = 0;
};

并将其命名为:array.clear();


91
请勿鼓励修改原生对象。 - Mulan
22
为什么人们总是有这种倾向将被接受的答案放入原型函数中?你在项目中是否真的这样做了?你是否拥有一个大量包含原型扩展的库并将其包含在每个项目中? - nurettin
4
为什么不直接输入 array.length = 0? - Design by Adrian
14
“请不要鼓励修改原生对象。”——我完全同意这一点,但仅仅重复这句话会显得傲慢。提出这种解决方案的人可能不知道后果,仅仅给他们扔下这句话而不是提供简短的解释或链接,不能传达除“我们这些比你聪明的人告诉你不要这样做,因为我们更懂”之外的任何含义。 - John Weisz
7
作为参考:为什么扩展原生对象是不好的实践? - Emile Bergeron
显示剩余4条评论

16

如果你对内存分配感兴趣,你可以使用类似 这个 jsfiddle 结合 Chrome 开发者工具的时间轴选项卡来比较每种方法。在“清除”数组后,您需要使用底部的垃圾桶图标强制进行垃圾回收。这应该为您选择的浏览器提供了更明确的答案。这里很多答案过时了,我不会依靠它们,而是像 @tanguy_k 上面的回答一样进行测试。

(有关上述选项卡的简介,您可以在这里查看)

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>

请注意,这可能取决于数组元素的类型,因为JavaScript对字符串和其他原始类型以及对象数组的处理方式不同。类型可能会影响发生的情况。


13

使用修改后的版本,基于Jan最初的建议:

var originalLength = A.length;
for (var i = originalLength; i > 0; i--) {
     A.pop();
}

压缩工具 Terser:

for (let i = A.length; i > 0;A.pop(),i--) {}

或者这里有另一种看法:

while(!A[Symbol.iterator]().next().done)A.shift()

14
为什么你想要做这样的事情?为什么添加两个变量和一堆代码来做同样的事情? - klh
pop方法会改变A.length,因此迭代次数将是您想要弹出的项目数量的一半;将其存储在变量中将保留原始长度值; - Ofir G

13

A.splice(0);

我刚刚在我正在处理的代码中使用了这个。它清空了数组。


不,你刚刚用一个新创建的匿名数组容器替换了一个命名数组容器。 var A = [1,2,3,4]; var B; B = A.splice(0); console.log(A); console.log(B); - Bekim Bacaj
@BekimBacaj 不是的,splice 会改变原始数组并_返回_一个新数组。返回的结果被忽略了。答案是正确的(但是多余的,因为这已经在很多年前被建议过了)。 - Sebastian Simon

13
如果您使用常量,那么您就没有选择:
const numbers = [1, 2, 3]

你无法重新分配:

numbers = []

您只能截断:

numbers.length = 0

10

enter image description here

如果要清空数组中的当前内存位置,请使用: 'myArray.length = 0''myArray.pop() 直到其长度为0'

  • length : 您可以设置 length 属性以在任何时候截断数组。当您通过更改其 length 属性扩展数组时,实际元素的数量会增加。
  • pop() : pop() 方法从数组中删除最后一个元素并返回该值。
  • shift() : shift() 方法删除零索引处的元素并将连续索引处的值向下移动,然后返回所删除的值。

示例:

var arr = ['77'];
arr.length = 20;
console.log("Increasing : ", arr); // (20) ["77", empty × 19]
arr.length = 12;
console.log("Truncating : ", arr); // (12) ["77", empty × 11]

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());
  }
};

  • new Array() | [] Create an Array with new memory location by using Array constructor or array literal.

    mainArr = []; // a new empty array is addressed to mainArr.
    
    var arr = new Array('10'); // Array constructor
    arr.unshift('1'); // add to the front
    arr.push('15'); // add to the end
    console.log("After Adding : ", arr); // ["1", "10", "15"]
    
    arr.pop(); // remove from the end
    arr.shift(); // remove from the front
    console.log("After Removing : ", arr); // ["10"]
    
    var arrLit = ['14', '17'];
    console.log("array literal « ", indexedItem( arrLit ) ); // {0,14}{1,17}
    
    function indexedItem( arr ) {
        var indexedStr = "";
        arr.forEach(function(item, index, array) {
            indexedStr += "{"+index+","+item+"}";
            console.log(item, index);
        });
        return indexedStr;
    }
    
  • slice() : By using slice function we get an shallow copy of elements from the original array, with new memory address, So that any modification on cloneArr will not affect to an actual|original array.

    var shallowCopy = mainArr.slice(); // this is how to make a copy
    
    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);
    

长度:弹出直到数组的长度达到指定大小。谁告诉你这个胡说八道的? - Bekim Bacaj
实质上,它具有相同的效果。可能应该写成 length = ? 而不仅仅是 length - Tuupertunut
@BekimBacaj 我已经更新了我的回答,我之前假设 length 剪裁到长度,但现在我已更正,length 只是截断或增加数组的大小。 - Yash

5
我很惊讶还没有人提出这个建议:
let xs = [1,2,3,4];
for (let i in xs)
    delete xs[i];

这将产生一个与其他解决方案完全不同的数组状态。从某种意义上说,该数组已经被“清空”:

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)来生成一个等效的数组


7
这句话的意思是:它可能是对另一个问题的很好回答:“如何将数组中的所有元素转换为未定义元素”。 - Ruben
虽然在内部未定义的元素和空槽(“洞”)之间存在差异 - Cauterite
1
那么这可以缩短为 const originalLength = array.length; array.length = 0; array.length = originalLength; - Sebastian Simon

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