JavaScript: The Definitive Guide

I recently ran across some curious JavaScript behaviour. Nothing new there, but I was slightly annoyed to see that my handy reference book hadn't given me any clue about the inconsistent way in which different browsers handle the Array.splice method. O'Reilly's JavaScript: The Definitve Guide (5th edition) is usually pretty good at pointing out any browser compatibility issues.

But after digging some more, I was even more confused to find that the book seemed to be wrong in its description of the method.

Here is the part that seems wrong to me, together with the example given:

Array.splice(start, deleteCount, value, ...)

deleteCount: This argument is optional; if not specified, splice() deletes all elements from start to the end of the array.

Example:

var a=[1,2,3,4,5,6,7,8];
a.splice(4);   // Returns [5,6,7,8]; a is [1,2,3,4]

But, according to the ECMAScript specification v3 the second argument is not optional:

Array.prototype.splice(start, deleteCount, [, item1 [, item2 [, ...]]])

When the splice method is called with two or more arguments start, deleteCount and (optionally) item1, item2, etc., the deleteCount elements of the array starting at array index start are replaced by the arguments item1, item2, etc.

Hmm. So what happens when we actually try the example given in the JavaScript book? Here's my results on several different browsers:

var a=[1,2,3,4,5,6,7,8];
a.splice(4);

// Results on Windows unless otherwise stated
// IE 6 + 7:                  Returns []; a is [1,2,3,4,5,6,7,8]
// Opera 9.27:                Returns []; a is [1,2,3,4,5,6,7,8]
// Opera 9.5:                 Returns []; a is [1,2,3,5,6,7,8]
// Firefox 2 + 3:             Returns [5,6,7,8]; a is [1,2,3,4]
// Safari 3.1.2:              Returns [5,6,7,8]; a is [1,2,3,4]
// Safari 3.0.4 (Mac):        Returns []; a is [1,2,3,4,5,6,7,8]
// Google Chrome 0.2.149.27:  Returns [5,6,7,8]; a is [1,2,3,4]

Some interesting and varied results there. The change in behaviour between Opera 9.27 and Opera 9.5 strikes me as being somewhat odd as I think Opera 9.27 was actually behaving correctly. Based on my brief reading of the ECMAScript spec at the time, I would expect an undefined value for the second argument to be cast to a zero value, therefore the returned array is empty and a is left untouched. At least that's what I thought after a quick glance at the convoluted (but precise!) specification which is now unavailable for me to check as the ECMA site currently appears to be down. Perhaps after all this week's excitement regarding ECMAScript Harmony?

Here's a live test showing what your browser makes of the array.splice() call without a deleteCount argument: