-
Notifications
You must be signed in to change notification settings - Fork 217
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
Copy own __proto__ safely #164
Conversation
- When the src object has an own __proto__ property, avoid modifying the result object's prototype
O hai @mnespor! This change takes deepmerge farther down the path that I'm trying to walk it back from in e.g. #152 – I want to make deepmerge more explicitly only concerned with deep merging properties on vanilla objects. deepmerge has historically been unclear on exactly what properties it should recurse down into, but starting with I think the defaulting of the Once #152 is implemented, cloned properties will never even have a prototype with any meaningful properties of its own! |
I'm tempted to go in the direction of "only assign new values if the target doesn't have the property, OR if the target hasOwnProperty and that property is enumerable" and just not copy any values where that isn't the case |
I like that a lot. It moves in the vanilla object direction and it protects from JSON.parse Should a change like that point at the v5 branch? |
- Only assign values if the target doesn't have the property, or if the target has that property as own and enumerable. - See TehShrike#164 (comment) - Reduce the likelihood of surprises when merging non-plain objects
index.js
Outdated
@@ -36,6 +36,11 @@ function getKeys(target) { | |||
return Object.keys(target).concat(getEnumerableOwnPropertySymbols(target)) | |||
} | |||
|
|||
function propertyIsPlain(target, key) { | |||
return target[key] === undefined |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Checking for undefined
isn't technically correct, since it would incorrectly return true in this case:
Object.defineProperty({}, key, {
configurable: true,
enumerable: false,
writable: true,
value: undefined
})
The most correct check I can think of would be !(key in target)
.
No need to point this at the v5 branch, this will be a good feature release. |
:-o can |
I found out it can, specifically on the test case that replaces a plain string with a nested object
… On Oct 4, 2019, at 10:16 AM, Josh Duff ***@***.***> wrote:
:-o can in ever throw?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.
|
Would something like |
Unsure. Depends on what you'd like it to do when |
Now I'm leaning towards renaming (If Downside: this would throw a After thinking about it some more, I'm getting nervous about breaking the case where someone passes in custom Maybe the test function should be changed to It could return I just realized that If we switch to |
Wanna switch the function to |
- see discussion in TehShrike#164 - add test cases for custom string merging and objects with null prototype
Definitely. I noticed that |
I don't think we need to check for That "is unsafe" check would incorrectly return
Oh right... we only need to check for And since Spelling it out for my sanity – a property is unsafe to touch if:
So, unsafe when So I think I've talked myself back to something like what you had before my last comment. A property is also unsafe if the target object is frozen, right? I think I was confusing merging string values with merging string properties. |
For a few minutes tonight, I considered frozen target objects unsafe to merge. However, that caused test case |
Published as 4.2.0 🌿 |
@TehShrike It's exactly why we are using this dependency for in Material-UI. +1 for going down this direction, especially if it can save bytes. |
modifying the result object's prototype