ECMA 262 5.1 says the following of Array.prototype.push
:
15.4.4.7
Array.prototype.push ( [ item1 [ , item2 [ , … ] ] ] )
....
- Let
O
be the result of callingToObject
passing the this value as the argument.- Let
lenVal
be the result of calling the[[Get]]
internal method ofO
with argument "length
".- Let
n
beToUint32(lenVal)
.- Let
items
be an internal List whose elements are, in left to right order, the arguments that were passed to this function invocation.- Repeat, while items is not empty
- Remove the first element from items and let
E
be the value of the element.- Call the
[[Put]]
internal method ofO
with argumentsToString(n)
,E
, andtrue
.- Increase
n
by 1.- Call the
[[Put]]
internal method of O with arguments "length", n, and true.- Return n.
Notice how the argument 3 to [[Put]]
is true
. Now, [[Put]]
is defined as
8.12.5
[[Put]] ( P, V, Throw )
When the
[[Put]]
internal method ofO
is called with propertyP
, valueV
, and Boolean flagThrow
, the following steps are taken:
- If the result of calling the
[[CanPut]]
internal method ofO
with argumentP
isfalse
, then
- If
Throw
istrue
, then throw aTypeError
exception.- Else return.
...
[[CanPut]]
then returns false
among others, in the case of array if [[Extensible]]
on O
is false
.
Thus, your Chrome is in violation of the ECMA 262 5.1 specification.
Update:
Chrome developers are talking about making the push
, pop
run under strict mode; however the difference is not just "strict" vs "non-strict" as the behaviour of push
and pop
is specified very specifically in the ECMA 262 5.1 specification.