Skip to content

Native Array.from is overwritten by $A which is not able to handle all cases used by the native function #338

Open

Description

@maxwangry

In version 1.7.3, the native Array.from is overwritten by $A as below:

function $A(iterable) {
  if (!iterable) return [];
  if ('toArray' in Object(iterable)) return iterable.toArray();
  var length = iterable.length || 0, results = new Array(length);
  while (length--) results[length] = iterable[length];
  return results;
}

Array.from = $A;

From the definition of these two functions:
The Array.from() method creates a new Array instance from an array-like or iterable object.
However, the $A function only accepts an array-like collection (anything with numeric indices).
So $A is not able to handle other iterable objects without numeric indices such as MapIterator.

When $A try to create a new array by reading the iterable.length which does exist in some native iterable objects such as MapIterator, the result will be an array with length 0 returned back.

Hope this will be fixed soon.

Thanks,
Max

Activity

  1. manticorp commented on Apr 8, 2022

    @manticorp

    +1 to this...

  2. ejuanis commented on May 22, 2022

    @ejuanis

    +1 to this. Perhaps make this a conditional polyfill if Array,from is supported natively. Google Maps v3.46 and above failed to load the satellite imagery due to this.

    This site overrides Array.from() with an implementation that doesn't support iterables, which could cause Google Maps JavaScript API v3 to not work correctly.

  3. Lubrum commented on May 25, 2022

    @Lubrum

    +1 to this. Also having issues with Google Maps 3.46 and above (satellite images).

  4. savetheclocktower commented on May 25, 2022

    @savetheclocktower
    Collaborator

    For a number of reasons, I view it as unlikely that there will ever be another release of Prototype, so I'd suggest working around this:

    • Before loading Prototype, capture a reference to the native method (var _originalArrayFrom = Array.from;) in an inline script tag
    • Load Prototype
    • Restore the original reference (Array.from = _originalArrayFrom;) in another inline script tag

    Similar approaches are possible if you bundle your dependencies.

  5. stefanbackor commented on Jul 9, 2024

    @stefanbackor

    Try executing this snippet before any other code to protect native implementation

    const nativeArrayFrom = Array.from
    Object.defineProperty(Array, 'from', {
      get: function () {
        return nativeArrayFrom
      },
      set: function () {
        console.warn('Attempt to overwriting native `Array.from` prevented.')
      },
    })
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions