2013-08-23 24 views
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.

+0

這些變量在哪裏聲明? –

+1

請參閱http://stackoverflow.com/questions/500606/javascript-array-delete-elements中的第一個答案 – tsiki

+1

可能的重複[Javascript對象與數組,刪除它實際上是否刪除該項目?](http:// stackoverflow。 com/questions/495764/javascript-object-with-array-deleting-do-it-actually-remove-the-item) – tsiki

回答

11

delete是 「下位」 操作。它直接在對象上工作,它不會「知道」數組。使用delete根本不會觸發例程重新計算數組長度。


其他答案在這裏聲稱該屬性的值設置爲undfined,這是不正確的。一個簡單的測試表明:

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

,並比較,如果你真的將值設置爲undefined會發生什麼:

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

對於一個更堅實的證據,讓我們來看看specification

當[[Delete]]內部方法O被稱爲屬性名稱P和Boolea n標誌,採取以下步驟:

  1. 遞減是主叫的ö的[[GetOwnProperty]]內部方法與屬性名P的結果。
  2. 如果desc未定義,則返回true
  3. 如果降序 [[配置]]是,然後
       一個。使用名稱PO刪除自己的財產。
        b。返回true
  4. 否則如果拋出,則拋出TypeError異常。
  5. 返回false

無處據說屬性的值設置爲undefined


不同瀏覽器的控制檯可能會顯示陣列的不同表示形式。在這個特定的例子中,你可以爭論它應該是[]還是[undefined]

  • []器(Chrome)似乎是有道理的,因爲數組確實沒有任何元素,有與數字名稱沒有屬性。但是,當您訪問.length資產時,您會收到1,這可能會造成混淆。
    不久之前,Chrome使用a representation like [undefined x 5]來指示長度爲5但沒有元素的數組。我認爲這實際上是一個很好的解決方案。

  • [undefined](火狐)是有道理的,因爲數組的長度爲1和訪問arr[0]實際上返回undefined(但這樣做arr[10])。然而,arr.hasOwnProperty(0)false如果數組真的包含值undefined,怎麼了區別於一個單獨由這種表示形式的空單元(答案:你不能)。

底線是:不要相信console.log太多。如果您想要確切的表示,請使用console.dir

+1

非常令人印象深刻和清晰的答案,非常感謝 – Sprottenwels

+0

爲什麼當我寫這個時候,我爲什麼要低估了我,'delete'是'[undefined]'之後的數組對象的解釋。 –

+0

@Antti:是什麼讓你覺得我低估了你?我沒有。正如我已經評論過的,我對你的控制檯輸出('[undefined]')感到困惑,並且沒有徹底地讀出你的答案而跳到了結論,這就是我評論的原因。然而,我並沒有冷靜下來。 –

2

這是因爲數組元素的刪除將它設置爲undefined,所以長度不會改變。使用splice函數:

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

簡單而有效 –

+0

確保您不介意數組移位。 – johnny

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 
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; 
0

我創建了一個新的陣列並在其上push編輯元素,以獲得正確的長度。例如,我有這個表頭:

var finalTableHeaderArray = []; 

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

不完全是你的問題,但它可以幫助別人。

相關問題