27

Code:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Unusual Array Lengths!</title>

    <script type="text/javascript">
        var arrayList = new Array();
        arrayList = [1, 2, 3, 4, 5, ];
        alert(arrayList.length);
    </script>

</head>
<body>
</body>
</html>

Notice the extra comma in the array declaration. The code above gives different outputs for various browsers:

Safari: 5

Firefox: 5

IE: 6

The extra comma in the array is being ignored by Safari and FF while IE treats it as another object in the array.

On some search, I have found mixed opinions about which answer is correct. Most people say that IE is correct but then Safari is also doing the same thing as Firefox. I haven't tested this on other browsers like Opera but I assume that there are discrepancies.

My questions:

i. Which one of these is correct?

Edit: By general consensus (and ECMAScript guidelines) we assume that IE is again at fault.

ii. Are there any other such Javascript browser quirks that I should be wary of?

Edit: Yes, there are loads of Javascript quirks. www.quirksmode.org is a good resource for the same.

iii. How do I avoid errors such as these?

Edit: Use JSLint to validate your javascript. Or, use some external libraries. Or, sanitize your code.

Thanks to DamienB, JasonBunting, John and Konrad Rudolph for their inputs.

Community
  • 1
  • 1
Adhip Gupta
  • 7,063
  • 7
  • 34
  • 46
  • 2
    Thank you thank you thank you!!! A stupid extra comma was causing IE8 to behave differently to FireFox and it was driving me up the wall trying to figure it out! – Tom Aug 06 '09 at 01:55
  • Thanks for posing this question, helped me solve an issue I was having with IE not handling an array as expected. :) – Nathan Pitman Nov 01 '12 at 11:31
  • 1
    Thanks for this. I was getting an IE8 JavaScript error when I checked the .length of an array element. And the cause was an extra comma in the array declaration. – jamesnotjim Sep 16 '13 at 14:16

7 Answers7

9

It seems to me that the Firefox behavior is correct. What is the value of the 6th value in IE (sorry I don't have it handy to test). Since there is no actual value provided, I imagine it's filling it with something like 'null' which certainly doesn't seem to be what you intended to have happen when you created the array.

At the end of the day though, it doesn't really matter which is "correct" since the reality is that either you are targeting only one browser, in which case you can ignore what the others do, or you are targeting multiple browsers in which case your code needs to work on all of them. In this case the obvious solution is to never include the dangling comma in an array initializer.

If you have problems avoiding it (e.g. for some reason you have developed a (bad, imho) habit of including it) and other problems like this, then something like JSLint might help.

John
  • 14,944
  • 12
  • 57
  • 57
7

I was intrigued so I looked it up in the definition of ECMAScript 262 ed. 3 which is the basis of JavaScript 1.8. The relevant definition is found in section 11.1.4 and unfortunately is not very clear. The section explicitly states that elisions (= omissions) at the beginning or in the middle don't define an element but do contribute to the overall length.

There is no explicit statements about redundant commas at the end of the initializer but by omission I conclude that the above statement implies that they do not contribute to the overall length so I conclude that MSIE is wrong.

The relevant paragraph reads as follows:

Array elements may be elided at the beginning, middle or end of the element list. Whenever a comma in the element list is not preceded by an Assignment Expression (i.e., a comma at the beginning or after another comma), the missing array element contributes to the length of the Array and increases the index of subsequent elements. Elided array elements are not defined.

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
  • Konrad: "The relevant definition is found in section 11.1.4 and unfortunately is not very clear." It seems quite clear to me: "Whenever a comma in the element list is not _preceded_ by an Assignment Expression [...]". Only when an expression preceeding a comma has been omitted, will it count as an element ( [, foo] => 2 elements). There is no mention of missing expression following a comma ( [foo, ] => 1 element). IE is at fault. – Zuu Jan 19 '10 at 19:44
  • I agree that it is NOT clear. From the production definition ArrayLiteral : [ ElementList , Elisionopt ]: ... Let pad be the result of evaluating Elision; if not present, use the numeric value zero. ... Call the [[Put]] internal method of array with arguments "length " , ToUint32(pad+len), and false. ... – Chris Dec 12 '12 at 21:10
  • ... To me, this definition says to set the length to the length of the ellision (pad) plus the length of the preceding element list. If this is not how I am supposed to read it, someone please enlighten me. – Chris Dec 12 '12 at 21:16
3

"3" for those cases, I usually put in my scripts

if(!arrayList[arrayList.length -1]) arrayList.pop();

You could make a utility function out of that.

Damien B
  • 1,992
  • 15
  • 19
2

First off, Konrad is right to quote the spec, as that is what defines the language and answers your first question.

To answer your other questions:

Are there any other such Javascript browser quirks that I should be wary of?

Oh, too many to list here! Try the QuirksMode website for a good place to find nearly everything known.

How do I avoid errors such as these?

The best way is to use a library that abstracts these problems away for you so that you can get down to worrying about the logic of the application. Although a bit esoteric, I prefer and recommend MochiKit.

Community
  • 1
  • 1
Jason Bunting
  • 58,249
  • 14
  • 102
  • 93
1

Which one of these is correct?

Opera also returns 5. That means IE is outnumbered and majority rules as far as what you should expect.

Shadow2531
  • 11,980
  • 5
  • 35
  • 48
1

Ecma 262 edition 5.1 section 11.1.4 array initializer states that a comma at the end if the array does not contribute to the length if the array. "if an element is elided at the end of the array it does not contribute to the length of the array"

That means [ "x", ] is perfectly legal javascript and should return an array of length 1

Austin France
  • 2,381
  • 4
  • 25
  • 37
  • There is no ambiguity about it, it is quite clear in the spec, which explicitly states that 'if an element is elided' [ie omitted] 'at the end of the array it does not contribute to the length of the array' - it could not be any clearer – Austin France Sep 20 '12 at 14:52
0

@John: The value of arrayList[5] comes out to be 'undefined'.

Yes, there should never be a dangling comma in declarations. Actually, I was just going through someone else's long long javascript code which somehow was not working correctly in different browers. Turned out that the dangling comma was the culprit that has accidently been typed in! :)

Community
  • 1
  • 1
Adhip Gupta
  • 7,063
  • 7
  • 34
  • 46