skip to Main Content

I had thought array.push was a very basic function so I was surprised to see Babel polyfill array.push for Chromium browsers. I checked the MDN document for array.push and saw that it says:

See also

Polyfill of Array.prototype.push in core-js with fixes of this method

I checked core-js document and its implementation but it is unclear how it "fixes" the problem in Chromium browsers.

So what is the problem? And how are Firefox/Safari implementations different from Chromium’s implementation? Checking the following output for reference.

The corejs3 polyfill added the following polyfills:
  es.object.to-string { "ie":"10" }
  es.promise { "ie":"10" }
  web.dom-collections.for-each { "ie":"10" }
  es.array.from { "ie":"10" }
  es.string.iterator { "ie":"10" }
  es.array.push { "chrome":"115", "edge":"110", "ie":"10" } //Only for Chromium, not for FF & Safari
  ...

2

Answers


  1. So what is the problem?

    When browsers allowed making array lengths non-writable as seen here, it affected the Array.push() method since Array.push() adds the specified elements to the end of an array and returns the new length of the array. If the array length is made non-writable, the array will not be able to update it. This causes an error. Unfortunately, with this addition, a bug was discovered. Core-js has added a polyfill which is what you just came across:

    properErrorOnNonWritableLength().

    Login or Signup to reply.
  2. So what is the problem?

    Some engines (in particular V8) are failing the Array/prototype/push
    /set-length-zero-array-length-is-non-writable
    test case
    of the test262 suite. That’s a bug, and core-js provides a workaround.

    Now what does the test check for? A really obscure edge case:

    • if you take an array and make its .length non-writable
    • then proceed to call .push(), which would attempt to write the .length and fail
    • but actually do not pass any arguments, so the .length doesn’t actually change
    • and if you still expect this to throw an exception

    …then V8 lets you down: it doesn’t throw the exception that it should throw but simply returns 0 (the length of the unchanged empty array).

    Also there appears to be a second problem, with really old Firefox versions, from before the feature of non-writable .length properties was introduced (10 years ago!), that it would not throw the expected TypeError but an InternalError.

    It is unclear how it "fixes" the problem in Chromium browsers.

    The polyfill – just like any other polyfill – overwrites Array.prototype.push with a conforming implementation that simply assigns the respective properties on the receiver. This includes the assignment to .length, even with an unchanged value, which will throw as expected. (Well actually it calls an array-set-length.js method to do that, which has to do the writability check explicitly in some engines).

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search