Skip to content

assignDeep copy plain objects values instead of reference #151

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

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
35 changes: 35 additions & 0 deletions reflections/shape/shape-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -711,6 +711,41 @@ QUnit.test("assignDeepList", function(){
], "assigned right");
});

QUnit.test("assignDeep copy #150", function() {
var obj = {};
var objMap = {prop: { foo: 'bar' }};
getSetReflections.setKeyValue(objMap.prop,canSymbol.for("can.onValue"), function(){});
shapeReflections.assignDeep(obj, objMap);
QUnit.notEqual(obj.prop, objMap.prop, "copy without referencing");
});

QUnit.test("assign-deep with a constructor #150", function() {
var Example = {};
getSetReflections.setKeyValue(Example,canSymbol.for("can.new"), function(){
return this;
});

var objMap = {};

shapeReflections.assignDeep(objMap, {nested: Example});
ok(objMap.nested === Example);
});

QUnit.test("assign-deep with duplicate objects #150", function() {
var me = {
name: "Justin"
};

var references = {
husband: me,
friend: me
};

var ref = {};
shapeReflections.assignDeep(ref, references);
ok(ref.husband === ref.friend, "multiple properties point to the same thing");
});


/*QUnit.test("getAllEnumerableKeys", function(){

Expand Down
19 changes: 15 additions & 4 deletions reflections/shape/shape.js
Original file line number Diff line number Diff line change
Expand Up @@ -813,18 +813,29 @@ shapeReflections = {
return target;
},
assignDeepMap: function(target, source) {

var hasOwnKey = fastHasOwnKey(target);
var getKeyValue = target[getKeyValueSymbol] || shiftedGetKeyValue;
var setKeyValue = target[setKeyValueSymbol] || shiftedSetKeyValue;
var serialized = new Map();
var serializedNewVal;

shapeReflections.eachKey(source, function(newVal, key){
if(!hasOwnKey(key)) {
// set no matter what
getSetReflections.setKeyValue(target, key, newVal);
if (newVal && (typeReflections.isConstructorLike(newVal) || typeReflections.isPrimitive(newVal) || typeReflections.isPlainObject(newVal) === false)) {
// set no matter what
getSetReflections.setKeyValue(target, key, newVal);
} else {
serializedNewVal = serialized.get(newVal);
if (!serializedNewVal) {
serializedNewVal = shapeReflections.serialize(newVal);
serialized.set(newVal, serializedNewVal);
}
setKeyValue.call(target, key, serializedNewVal);
}
} else {
var curVal = getKeyValue.call(target, key);

// if either was primitive, no recursive update possible
if(newVal === curVal) {
// do nothing
Expand Down