为什么删除后数组的长度仍为非零?

时间:2013-08-23 06:56:25

标签: javascript arrays

我有以下代码输出数组的长度,删除它,然后输出新的长度:

console.log($scope.adviceList.activeAdvices.length); // *1*
$scope.adviceList.activeAdvices.splice(id,1); // *id is a parameter*
console.log($scope.adviceList.activeAdvices.length); // *0*

console.log($scope.adviceList.activeAdvices.length); // *1*
delete $scope.adviceList.activeAdvices[id];
console.log($scope.adviceList.activeAdvices.length); // *0*
console.log($scope.adviceList.activeAdvices); // *[]*

删除后,数组正确显示为空。然而,它的长度仍然是1。

5 个答案:

答案 0 :(得分:11)

delete是“较低级别”的运营商。它直接作用于对象,它不会“知道”关于数组。使用delete只是不会触发例程重新计算数组长度。


此处的其他答案声称该属性的值设置为undfined,这是不正确的。一个简单的测试表明:

var a = [1]; 
delete a[0]; 
console.dir(a);

并比较如果您确实将值设置为undefined会发生什么:

var a = [1]; 
a[0] = undefined; 
console.dir(a);

为了更加可靠,我们来看看specification

  

当使用属性名称​​ P 和布尔标志 Throw 调用 O 的[[Delete]]内部方法时,执行以下步骤采取:

     
      
  1. desc 成为使用属性名 P 调用 O 的[[GetOwnProperty]]内部方法的结果。
  2.   
  3. 如果 desc 未定义,则返回 true
  4.   
  5. 如果 desc 。[[Configurable]]为 true ,则
      一个。从 O 中删除名为 P 的属性。
      湾返回 true
  6.   
  7. 如果抛出,则抛出 TypeError 异常。
  8.   
  9. 返回 false
  10.   

没有人说该属性的值设置为undefined


不同浏览器的控制台可能会显示不同的数组表示形式。在此特定示例中,您可以争论它应该是[]还是[undefined]

  • [](Chrome)似乎有意义,因为数组实际上没有任何元素,没有带数字名称的属性。但是,当您访问.length属性时,您会收到1,这可能会造成混淆。
    不久前,Chrome使用a representation like [undefined x 5]来表示长度为5但没有元素的数组。我认为这实际上是一个很好的解决方案。

  • [undefined](Firefox)有意义,因为数组长度为1,访问arr[0]实际上返回undefined(但arr[10]也是如此)。但是, arr.hasOwnProperty(0)将为false,如果数组确实包含值undefined,那么如何通过此表示将其与长度为1的空数组区分开来(答案:你不能)

底线是:不要太信任console.log。如果您想要精确表示,请使用console.dir

答案 1 :(得分:2)

这是因为数组元素上的删除将其设置为未定义,因此长度不会改变。请改用splice函数:

a = [1,2,3,4];
a.splice(2,1);
console.log(a.length);

答案 2 :(得分:1)

如果你想“删除”数组中的项目,你可以

var a = ["a","b"];
console.log(a);  //a,b
console.log(a.length);//2
a.length = 1;//"delete" all greater than length 1 of items;
console.log(a);//a
console.log(a.length);//1

 var a = ["a","b"];
    console.log(a);  //a,b
    console.log(a.length);//2
    a.pop();//"delete" the last in array:"b"
    console.log(a);//a
    console.log(a.length);//1

 var a = ["a","b"];
    console.log(a);  //a,b
    console.log(a.length);//2
    a.shift();//"delete" the first in array:"a"
    console.log(a);//b
    console.log(a.length);//1

 var a = ["a","b"];
    console.log(a);  //a,b
    console.log(a.length);//2
    a.splice(1,1);//"delete" from index 1(include,first parameter),delete number is 1(second parameter)
    console.log(a);//a
    console.log(a.length);//1

答案 3 :(得分:0)

就我而言,我在删除后重新定义了长度:

var cars = ["BMW", "Volvo", "Saab", "Ford"];
delete cars[1];

/// 1st option ///
for (var i = 0; i < cars.length; i++){
  if(i in cars)
    document.write(cars[i] + " ");
}
/// return: BMW Saab Ford

/// 2nd option ///
cars.length--;
var realLength = cars.length;

答案 4 :(得分:0)

我在其上创建了一个新数组和push ed元素以获得正确的长度。例如,我有这个用于表头:

 var finalTableHeaderArray = [];

 tableHeaderArray.forEach(function (element, index, array) {
    if (removeDisplayItems.indexOf(index) === -1)
        finalTableHeaderArray.push(element);
 }, self);

不完全是你的问题,但它可以帮助其他人。