mixin-deep icon indicating copy to clipboard operation
mixin-deep copied to clipboard

The second object was changed when the first is "{}"

Open cczw2010 opened this issue 2 years ago • 3 comments

The Code:

import mixinDeep from "mixin-deep"
const a = {a:{a:1,b:0}};
const b = {a:{b:2},b:1};
const c = {a:{a:2},c:2};
const d = mixinDeep({},a,b,c);
console.log("a",a)
console.log("b",b)
console.log("c",c)
console.log("d",d)

The console output:

a { a: { a: 2, b: 2 } }
b { a: { b: 2 }, b: 1 }
c { a: { a: 2 }, c: 2 }
d { a: { a: 2, b: 2 }, b: 1, c: 2 }

why "a" is changed,

cczw2010 avatar Mar 23 '22 08:03 cczw2010

Because objects are not cloned, when they are assigned. See the added log at the end:

import mixinDeep from "mixin-deep"
const a = {a:{a:1,b:0}};
const b = {a:{b:2},b:1};
const c = {a:{a:2},c:2};
const d = mixinDeep({},a,b,c);
console.log("a",a)
console.log("b",b)
console.log("c",c)
console.log("d",d)
console.log("d.a === a.a", d.a === a.a)

I suppose to change https://github.com/jonschlinkert/mixin-deep/blob/8f464c8ce9761a8c9c2b3457eaeee9d404fa7af9/index.js#L29 to

target[key] = mixinDeep({}, val);

in case isObject(val).

Note: This does not clone arrays.

maiermic avatar May 29 '22 11:05 maiermic

Thanks for the reply

cczw2010 avatar Jun 08 '22 01:06 cczw2010

I hit this too and thought it was a bug, but this behaviour is actually specified in the tests. I found this unintuitive and unpredictable, so I created PR 15 to make it work the way I expected.

If you need to use my version before Jon merges my pull request, you can install it using the command npm install cloudrac3r/mixin-deep#v3.0.0

cloudrac3r avatar Aug 23 '23 03:08 cloudrac3r