Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
maxwangry opened this issue Feb 14, 2018 · 5 comments

Comments

@maxwangry
Copy link

maxwangry commented Feb 14, 2018

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

@manticorp
Copy link

+1 to this...

@ejuanis
Copy link

ejuanis commented May 22, 2022

+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.

@Lubrum
Copy link

Lubrum commented May 25, 2022

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

@savetheclocktower
Copy link
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.

@stefanbackor
Copy link

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
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants