0

I need a clone function for JavaScript literal objects, which doesn't even needs to clone recursively for now. The function needs to be pure JavaScript no libraries could be used. I've done some research and as some of the most simplified answers to this question suggests, all I need in this case is "for in" loop with hasOwnProperty check. The problem is that the supposedly copied object is behaving as if I've copied the references to the original properties in the new object. That is not my goal. The clone function in a way that any change of the source object does not affect the destination object and vice versa. Here is the code:

...
function clone(from,to){
    for (var key in from){
        if(from.hasOwnProperty(key)){
            to[key]=from[key];
        }
    }
    return to;
}
...
var newComponent = clone(component,{});
var defaultComponentDrawParams = clone(component.drawParams,{});
if(params.type==="button"){
    console.info('new  component');
    component.drawParams.subType="chinga chunga";
    console.info(defaultComponentDrawParams.subType);
    console.info(newComponent.drawParams.subType);
}

And the console displays:

new  component
saveFile
chinga chunga

If I've understood correctly both outputs after "new component" should be "undefined" because my goal is when changing component.drawParams to not change newComponent.drawParams. Please tell me what am I missing.

Community
  • 1
  • 1
DNikolov
  • 16
  • 2

1 Answers1

0

My guess is that you've got multiple components one of them being a "saveFile" component. And the problem is that your clone isn't cloning the objects/arrays, it's simply creating references to them. So when you update one component, all components that have a reference to those same objects are also getting updated.

Below is an example of the type of detection you may need to add in. However this may not be an absolutely complete answer that catches all scenarios.

function clone(from,to){
    for (var key in from){
        if(from.hasOwnProperty(key)){
            var val = from[key];

            if(typeof val === 'object') {
                to[key] = clone(from[key], {});
            } else {
                to[key] = from[key];
            }
        }
    }
    return to;
}

I hesitate to suggest this but another option would be to use a javascript library such as Underscore.js: http://underscorejs.org/

It's extremely lightweight (5kb, not nearly as big as jQuery) and has a lot of these types of things figured out for you.

ArrayKnight
  • 6,956
  • 4
  • 17
  • 20
  • I don't want to use external libraries, and as far as the `if(typeof val==='object')` I taught it will simply call the function itself in case one of the object properties is a object itself. In other words I don't see any change to the way the properties are copied, but I will try it. – DNikolov Mar 25 '14 at 17:48