3

I have the following code that outputs the length of an array, deletes it, and then outputs the new length:

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); // *[]* 

After the deletion, the array is correctly displayed as empty. Its length, however, is still 1.

9
  • Where are these variables declared? Commented Aug 23, 2013 at 6:59
  • 1
    See first answer in stackoverflow.com/questions/500606/… Commented Aug 23, 2013 at 7:00
  • 1
    possible duplicate of Javascript object with array, deleting does it actually remove the item? Commented Aug 23, 2013 at 7:03
  • 1
    delete is a "lower" level operator. It directly works on the object, it doesn't "know" about the array. Using delete simply doesn't trigger the routine to recompute the array length. Commented Aug 23, 2013 at 7:11
  • 1
    "delete won't actually delete the item, but rather set it to undefined" That's incorrect. The property is removed. Try var a = [1]; delete a[0]; console.dir(a); Commented Aug 23, 2013 at 7:12

5 Answers 5

11

delete is a "lower level" operator. It directly works on the object, it doesn't "know" about the array. Using delete simply doesn't trigger the routine to recompute the array length.


Other answers here claim that the value of the property is set to undfined, which is incorrect. A simple test shows that:

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

and compare to what happens if you really set the value to undefined:

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

For a more solid proof, lets have a look at the specification:

When the [[Delete]] internal method of O is called with property name P and the Boolean flag Throw, the following steps are taken:

  1. Let desc be the result of calling the [[GetOwnProperty]] internal method of O with property name P.
  2. If desc is undefined, then return true.
  3. If desc.[[Configurable]] is true, then
       a. Remove the own property with name P from O.
       b. Return true.
  4. Else if Throw, then throw a TypeError exception.
  5. Return false.

Nowhere it is said that the value of the property is set to undefined.


The consoles of different browsers might show different representations of the array. In this particular example, you can argue whether it should be [] or [undefined].

  • [] (Chrome) seems to make sense because the array really doesn't have any elements, there are no properties with numeric names. However, when you access the .length property, you would get a 1, which can be confusing.
    Not too long ago, Chrome used a representation like [undefined x 5] to indicate an array of length 5 but without elements. I think this was actually a good solution.

  • [undefined] (Firefox) makes sense because the array is of length 1 and accessing arr[0] actually returns undefined (but so does arr[10]).However, arr.hasOwnProperty(0) would be false and if an array really contains the value undefined, how can it be distinguished from an empty array of length one solely by this representation (answer: you can't).

The bottom line is: Don't trust console.log too much. Rather use console.dir if you want an exact representation.

Sign up to request clarification or add additional context in comments.

6 Comments

Why do you downvote me when that is what I wrote, the interpretation of the array object after delete is [ undefined ].
@Antti: What makes you think I downvoted you? I didn't. As I already commented, I got confused by your console output ([ undefined ]) and jumped to conclusions without reading your answer thoroughly and that's why I commented. I didn't downvote however.
One thing that makes me even more confused is that MDN says that both undefined AND no property should behave the same way for forEach, but they do not behave even on Firefox
Mine says undefined, Chrome.
@johnny: Accessing a non-existing property will return undefined. That is not the same as setting the property to undefined though (as I demonstrated in the answer).
|
2

It's because delete on array element set it to undefined so the length don't change. Use splice function instead:

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

1 Comment

simple and effective
1

if you want "delete" a item in array,you could

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 

or

 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 

or

 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 

or

 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 

Comments

0

For my part, I redefined the length after delete:

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; 

Comments

0

I created a new array and pushed elements on it to get the right length. For example, I had this for table headers:

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

Not exactly your question, but it could help others.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.