Change Object.assign polyfill to NOT walk entire prototype chain and to NOT force ideologies
See original GitHub issueIs this a bug report?
Yes
Have you read the Contributing Guidelines?
Yes
Environment
Environment: OS: Linux 4.10.0-35-generic #39-Ubuntu SMP Wed Sep 13 07:46:59 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux Node: 8.1.3 npm: 5.3.0
Packages: (wanted => installed) react-native: 0.49.3 => 0.49.3 react: 16.0.0-beta.5 => 16.0.0-beta.5
Target Platform: Android (7)
Steps to Reproduce
(Write your steps here:)
- Create an object with keys
var a = { test: 'derp' }
- Create an object with
a
as the prototypevar b = Object.create(a)
- Attempt to assign
b
to a new objectvar c = Object.assign({}, b)
Expected Behavior
react-native shouldn’t slowly walk the entire prototype chain or force ideologies
Actual Behavior
react-native DOES slowly walk the entire prototype chain AND force ideologies
Reproducible Demo
https://github.com/facebook/react-native/blob/master/Libraries/polyfills/Object.es6.js
Your Polyfill for Object.assign (Object.es6.js) is completely backwards, slow, and forcing an ideology. You are DELIBERATELY walking and copying the entire prototype chain, which is slow, and often not desired. The SUPER INSANE part? You are telling me how to live my life, and throwing an exception if there IS an enumerable property in the prototype chain. Forcing people to do things YOUR way is the wrong way. Please update the polyfill to 1) NOT walk the entire chain, 2) NOT tell me how to code.
By the way, I ran into this simply inheriting from EventEmitter, which is SUPER COMMON by the way.
I am upset that Facebook has written controlling polyfills forcing ideologies and telling me how to live my life. Please stay off my lawn, stop telling me how to code, and stop doing things the slow way just to tell other people how to do things
// We don't currently support accessors nor proxies. Therefore this
// copy cannot throw. If we ever supported this then we must handle
// exceptions and side-effects.
// No SANE person would ever copy an object with `key in obj`
// please use `Object.keys(obj)` instead, which is much faster,
// and doesn't involve forced ideologies
for (var key in nextSource) {
if (false) { // <--- Add false here... because you don't need to tell me the proper way to code
var hasOwnProperty = Object.prototype.hasOwnProperty;
if (!hasOwnProperty.call(nextSource, key)) {
throw new TypeError(
'One of the sources for assign has an enumerable key on the ' +
'prototype chain. Are you trying to assign a prototype property? ' +
'We don\'t allow it, as this is an edge case that we do not support. ' +
'This error is a performance optimization and not spec compliant.'
);
}
}
target[key] = nextSource[key];
}
Issue Analytics
- State:
- Created 6 years ago
- Reactions:1
- Comments:10 (4 by maintainers)
@TheSavior “Also, since all of our other polyfills appear to have that check already, it doesn’t seem like those concerns would be unique to this file. For that reason, it seems reasonable to add that separately, earlier.” I agree it certainly makes sense to add that change to the polyfill (
instanceof Function
check), however being as the polyfill is currently not to standard I am concerned with switching between platforms that implement the standard, and platforms where the non-standard polyfill will be used. The deviation of the polyfill will potentially cause the app to crash where the polyfill is used (as it does now).I will write unit tests when I have some free time, which might not be for a few days
Please note that I want to help make this satisfy your concerns.
The PR is quite difficult to review and merge confidently, this is true polyfills in general. The following explains why.
I have no context on the initial intent of this code, but I assume that the people who wrote it were smart engineers with more context on the situations it needs to support than I do currently.
The fact that there is a specific warning about the
hasOwnProperty
checks and that the polyfill is not spec-compliant implies that we started with a spec compliant polyfill and needed to change it to this approach instead. I could also imagine this being an optimization for Prepack, but based on the history of this file not being recent, that likely isn’t the case.It feels like it would be fairly bad form for us to ignore these warnings without better understanding the situations they were meant to solve. Unfortunately, these warnings were not codeified via tests.
Also unfortunately, I couldn’t trace the history of this file back to where it was added or modified to be able to see if the original authors remember anything about the reasons. The only people I could find related to that history were @mjesun and @davidaurelio. Perhaps they have some context.
In the mean time, while we are trying to get more context before figuring out how to move forward with those changes, I’d be happy to accept a PR that just contains the additional existence check that you added.
This check exists on the other polyfills and I can’t imagine why we’d want to override an existing
Object.assign
function.FWIW, I also have a hard time fully understanding the problems you are trying to address. From you initial post it seems like the main complaint you have is:
When trying to deconstruct that complaint and understand the specifics, I can understand the first half being performance related. For “force ideologies”, I’m not exactly sure what you mean by that. Is that specifically about us overriding existing
Object.assign
functions which would be satisfied by the addition of the existence check above? Or are there other “ideologies” the code is forcing? Can you help understand the specifics of this?