3

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

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。

4

5 回答 5

11

delete是“低级”运算符。它直接作用于对象,它不“知道”数组。使用delete简单不会触发例程重新计算数组长度。


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

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

并比较如果你真的将值设置为会发生什么undefined

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

为了更可靠的证明,让我们看一下规范

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

  1. desc为调用具有属性名称P的O的 [[GetOwnProperty]] 内部方法的结果。
  2. 如果desc未定义,则返回true
  3. 如果desc .[[Configurable]] 为true,则
       a. 从O中删除名称为P的自己的属性。    湾。返回
  4. Else if Throw,则抛出TypeError异常。
  5. 返回

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


不同浏览器的控制台可能会显示不同的数组表示。在这个特定的例子中,你可以争论它是否应该是[][undefined]

  • [](Chrome)似乎是有道理的,因为数组确实没有任何元素,没有带有数字名称的属性。但是,当您访问该.length属性时,您会得到一个1,这可能会令人困惑。
    不久前,Chrome 使用类似[undefined x 5]表示长度为 5 但没有元素的数组的表示。我认为这实际上是一个很好的解决方案。

  • [undefined](Firefox)是有道理的,因为数组的长度为 1 并且访问arr[0]实际上返回undefined(但也是如此arr[10])。但是,arr.hasOwnProperty(0)如果false数组确实包含 value undefined,那么如何仅凭此将它与长度为 one 的空数组区分开来代表(答案:你不能)。

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

于 2013-08-23T07:15:59.803 回答
2

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

a = [1,2,3,4];
a.splice(2,1);
console.log(a.length);
于 2013-08-23T07:01:06.023 回答
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
于 2013-08-23T09:58:17.847 回答
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;
于 2014-01-30T16:29:43.353 回答
0

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

 var finalTableHeaderArray = [];

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

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

于 2017-03-30T18:56:21.987 回答