Click and click on a frozen array in Chrome without throwing an exception.

The following code does not seem to work as expected in Chrome, and works differently in Firefox.

(function () { 'use strict'; var arr = Object.freeze([1, 2, 3]); try { arr.push(4); } catch (e) { console.log(e); } try { console.log(arr.pop()); }catch (e) { console.log(e); } console.log(arr); })(); 

I expected the output to be:

 Error : (for `arr.push(4)`) Error : (for `arr.pop()`) [1, 2, 3] 

but when I run this code in Chrome 29.0.1547.49 (Official Build 216092) beta-m, I get the following output:

 3 [1, 2, 3] 

Why is there no exception? I ran this code in Firefox Nightly 26.0a1 (2013-08-12), and the result

 TypeError: arr.push(...) is not extensible TypeError: property arr.pop(...) is non-configurable and can't be deleted [1, 2, 3] 

as i expected.

I thought about why there is a difference between Chrome and Firefox, then I realized that this could be due to the strict fashion of the pop and push methods. To summarize, Firefox (SpiderMonkey) pop and push methods are defined in strict mode, but in Chrome (V8) these methods are not defined in strict mode.

I do not know what the actual specification is. (I read some ECMA-262 5.1th Edition, but I cannot find such a section.)

+4
source share
1 answer

ECMA 262 5.1 reports the following Array.prototype.push :

15.4.4.7 Array.prototype.push ( [ item1 [ , item2 [ , โ€ฆ ] ] ] )

....

  • Let O be the result of calling ToObject passing this value as an argument.
  • Let lenVal be the result of calling the [[Get]] O internal method with argument << 27>.
  • Let n be ToUint32(lenVal) .
  • Let items be an internal list whose elements are in order from left to right, the arguments that were passed to this function call.
  • Repeat while items are not empty
    • Remove the first element from the elements and let E be the value of the element.
    • Call the internal [[Put]] O method with arguments ToString(n) , E and true .
    • Increase n by 1.
  • Call the internal method O [[Put]] with arguments "length", n and true.
  • Returns n.

Notice how argument 3 to [[Put]] is true . Now [[Put]] is defined as

8.12.5 [[Put]] ( P, V, Throw )

When the [[Put]] O internal method is called with the P property, the V value and the Boolean Throw flag, the following steps are performed:

  • If the result of calling the [[CanPut]] O internal method with argument P is false , then
    • If Throw is true , then throw a TypeError exception.
    • Repeated return.

...

[[CanPut]] then returns false among others, in the case of an array, if [[Extensible]] on O is false .

Thus, your Chrome is in violation of the ECMA 262 5.1 specification.

Update:

Chrome developers talk about how to make push , pop work in strict mode; however, the difference is not just โ€œstrictโ€ and โ€œnon-strictโ€, as the behavior of push and pop very precisely specified in the ECMA 262 5.1 specification.

+6
source

Source: https://habr.com/ru/post/1496707/


All Articles