-
-
Notifications
You must be signed in to change notification settings - Fork 37
Fixed #6 (reuses object in deep assignment) #8
Conversation
@sindresorhus, I draw your attention that "support symbols as targets" check was failed before this change (when I ran tests just after cloning and now on master branch). |
@Kreozot Thank you for your suggestion, but I think it is incompatible with the project description of
That is because |
Sorry, but I don't get it. How do you think deep-assign should behave with internal objects? Because without this PR it acts like simple object-assign. @sindresorhus, what do you say? |
@Kreozot It does not. Think of the following snippet already mentioned in #6: function User(name) {
this.name = name;
}
var target = {
user: new User('Alice')
};
var source = {
user: new User('Bob')
};
// target.user exists, so deep-assign steps into target.user and source.user:
deepAssign(target, source);
//=> target.user.name === source.user.name === 'Bob' This shows that the target object tree is recursively updated with properties of target.user.name = source.user.name;
// but: target.user !== source.user With non-recursive Object.assign(target, source);
//=> target.user === source.user |
Yes. But with this bug it acts exactly like this. When you assign fixture.foo.bar it actually assign only fixture.foo (that's why changing bar affects original object) |
@Kreozot With the last example I just wanted to show that |
That's why I said "...with this bug..." |
@Kreozot I thought my (deleted) example was flawed by itself (the output doesn't match the code and I couldn't have recognized any difference). Took me some time to find some real difference: var alice = {};
Object.defineProperty(alice, 'name', {value: 'Alice'});
var result = deepAssign({}, {user: alice});
//Current => result.user.name === 'Alice'
//PR => result.user.name === undefined Personally I would prefer the current behavior, because it is consistent with non-plain objects: function User() {}
var alice = new User();
Object.defineProperty(alice, 'name', {value: 'Alice'});
var result = deepAssign({}, {user: alice});
//Current => result.user.name === 'Alice'
//PR => result.user.name === 'Alice' In addition, also the ECMAScript® 2015 Language Specification does not distinguish plain and non-plain objects. |
Finally got it. Thanks for the explanation. Will think. |
Sooo... The problem is not in the PR. The problem is in |
@Kreozot exactly, the
How you look at it: Your PR introduces the inconsistenties between plain and non-plain objects I've mentioned. |
But the whole point of object assign is that it clone object instead of copying a pointer. Without the PR this is useless at all. I can't be sure that object, from that I assign, is safe. |
Maybe we should create another issue about this problem (and a test for it of course)? |
I don't think so.
Sometimes it is intended not to clone and share references. |
If we talk about object-assign, I agree. But isn't deep-assign do the same but for all nested properties? |
I support @Kreozot in here. I've installed deep-assign for this very reason to recursively copy an object, but found it not working as expected. I will have to use his fork instead. |
We need to defined what "Recursive Object.assign()" really means here. And I think @Kreozot is more intuitive. |
This module is now deprecated: b332062 |
No description provided.