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

Wot*_*els 3 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); // *[]*
Run Code Online (Sandbox Code Playgroud)

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

Fel*_*ing 11

delete是一个"较低级别"的运营商.它直接作用于对象,它不会"知道"关于数组.使用delete简单地不会触发例程重新计算数组长度.


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

var a = [1]; 
delete a[0]; 
console.dir(a);
Run Code Online (Sandbox Code Playgroud)

并比较如果你真的将值设置为undefined:

var a = [1]; 
a[0] = undefined; 
console.dir(a);
Run Code Online (Sandbox Code Playgroud)

为了更加可靠,我们来看看规范:

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

  1. desc是调用属性名为PO的[[GetOwnProperty]]内部方法的结果.
  2. 如果desc未定义,则返回true.
  3. 如果desc.[[Configurable]]为,那么
       a.从O中删除名为P的属性.    湾 回归真实.
  4. 否则,如果抛出,则抛出TypeError异常.
  5. 返回false.

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


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

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

  • [undefined](火狐)是有道理的,因为数组的长度为1和访问arr[0]实际上返回undefined(但这样做arr[10]).然而,arr.hasOwnProperty(0)将是false如果一个数组真的包含值undefined,怎么能够从这个长度仅一个的空数组区别表示(答案:你不能).

底线是:不要console.log太信任.相反,console.dir如果你想要一个精确的表示.