10

Apparently JS implementation in IE9 contains (IMO, critical) bug in handling array literals.

In IE9 in some cases this code:

var a = [1,2,3,4,];

will create array of length 5 with last element equals to undefined.

Here are two versions of my KiTE engine test pages:

The only difference is that first document contains data.contacts property initialized as [1,2,3,4] and second one as [1,2,3,4,].

Internal IE debugger reports that data.contacts array contains 5 elements in second case. Without debugger this code fails at line 98 in kite.js (trying to get property of undefined - fifth element of that data.content array )

Questions:

  1. How and where people usually report bugs in IE?
  2. Have you seen anything similar to this problem? I am looking for simplest case where this problem is reproducible.

Update: here is the test http://jsfiddle.net/hmAms/ where all browsers (IE9 included) agree on the fact that var a = [1,2,3,4,]; is of length 4.

c-smile
  • 26,734
  • 7
  • 59
  • 86
  • 2
    i think it shouldnt be written `[1,2,3,4,]` in the first place – Ibu Jun 01 '11 at 05:24
  • 2
    The last comma indicates that there is another value. In your case its undefined. So where is the bug? Remove the obsolete comma and your problem is gone. – Andreas Jun 01 '11 at 05:26
  • 2
    Trailing comma is supported by many languages and is useful for auto-generated code (note JSON does not support it officially) and makes editing and merging source code easier. – Peter Davis Jun 01 '11 at 05:40
  • @Peter Davis: Very true. As soon as JS uses C notation it should use its basic syntax features. To avoid surprises. But my question is about different thing actually: IE handles trailing commas in array literals differently in different context - that is the problem. – c-smile Jun 01 '11 at 06:00

2 Answers2

10

A single trailing comma in an array literal should be ignored. Two trailing commas is an elision and should add one to the array's length. So:

alert( [1,2,3,4,].length );   // 4

alert( [1,2,3,4,,].length );  // 5

Some versions of IE (< 9?) treat the single trainling comma as an elison and incorrectly add one to length, so the results above are 5 and 6 respsectively. That is inconsistent with ECMA-262 §11.1.3 and therefore is a bug.

The purpose of an elision is to increase array length without creating a extra property or assigning directly to length, so:

var x = [,1,,];

is equivalent to:

var x = new Array(3);
x[1] = 1;

The result in both cases should be an array with length 3 and one property named '1' with value 1. The leading comma and trailing comma pair are elisions, they only affect the length, they do not create properties. IE interprets the leading comma correctly but incorrectly interprets both trailing commas as elisions, incrementing the length by 1 too many.

var x = [,1,,3,,];
var s = 'length: ' + x.length;

for (var p in x) {
  s += '\nindex ' + p + ' has value ' +  x[p]; 
}
alert(s);

The result should be:

length: 5
index 1 has value 1
index 3 has value 3

Incidentally, this bug has probably been around since IE allowed array literals, version 4 at least (1997?).

RobG
  • 142,382
  • 31
  • 172
  • 209
  • http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf "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 AssignmentExpression (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. If an element is elided at the end of an array, that element does not contribute to the length of the Array." – thetoolman Nov 10 '11 at 20:08
  • So the spec clearly states that only the final comma won't contribute to the array length, which is what iE(<9) does wrong. – thetoolman Nov 10 '11 at 20:09
  • @thetoolman - that last sentence was added in ES5. It was not intended to change the behaviour of elisions (otherwise it directly contradicts the first sentence), but to confirm that a single trailing comma does not increase the array length. The statement is unnecessary and confusing - a single comma is only an elision at the start of an array literal, it isn't an elision anywhere else (including at the end). Array member AssignmentExpressions include the following comma (if there is one), so a single trailing comma is part of the preceding AssignmentExpression, and therefore not an elision. – RobG Nov 12 '11 at 03:42
-3

That's not a bug. That's exactly how it should behave. Microsoft did that on purpose. If you want an array with only 4 items, get rid of the last comma. Simple as that.

If the results you're after is to have an extra, undefined value at the end, you're in luck. Even without the comma, it'll be undefined. It, and every single number after 3.

McKayla
  • 6,879
  • 5
  • 36
  • 48
  • 1
    Older versions of IE call it a syntax error, as do most browsers if you trail a comma in an object literal. Best to use ,null] or ,undefined]if you must end an array with a null value. – kennebec Jun 01 '11 at 05:34
  • Really? And what about this: http://jsfiddle.net/hmAms/ then? What array length IE9 reports to you? That is the problem - it is not consistent. – c-smile Jun 01 '11 at 05:34
  • Like I said, `[..., undefined]` is absolutely pointless. It'll be undefined anyway. – McKayla Jun 01 '11 at 05:35
  • @c-smile It's also inconsistent that IE9 isn't absolutely horrible, like it's older siblings. They should fix that then? – McKayla Jun 01 '11 at 05:36
  • @tylermwashburn I didn't get that passage about IE inconsistency. And that question is not clear either, sorry. Who should fix what? – c-smile Jun 01 '11 at 05:53
  • @c-smile I'm just saying that you shouldn't always be consistent. Sometimes being consistent can decrease the overall quality of something. – McKayla Jun 01 '11 at 05:55
  • 2
    @tylermwashburn - -1 because it absolutely **is** a bug. A trailing elision requires 2 commas: `alert([1,2,3,4,,].length);` should be 5, IE<9 shows 6. Elisions are used to make an array longer without defining a value. It's probably there for consistency with Array in other languages. – RobG Jun 01 '11 at 07:11
  • @kennebec - -1 if I could vote down coments. Older versions of IE **do not** call it a syntax error, they incorrectly think it's an elision and add one to the array's length. – RobG Jun 01 '11 at 07:17
  • @RobG Would you stop being such an uptight prick about everything? You're starting to get on my nerves. – McKayla Jun 01 '11 at 23:41
  • @tylermwashburn - how would you go about correcting errors propigated in a number of answers and responses, and where the authors don't correct their answers or delete their erroneous comments? – RobG Jun 02 '11 at 01:43
  • @RobG By suggestions ways to fix the problems, not just calling them out and acting like they're a class lower then me because they made a mistake. **We're humans. We are here to make mistakes, and learn from them.** I haven't fixed anything because you're too busy telling me I suck to actually help me improve. It's people like you that are ruining the sense of community this site used to have. – McKayla Jun 03 '11 at 06:51