I am working in jquery with backbone.js and running into the case where i need to duplicate models, but i need to do a deep copy on them so no references exist between the copies. Models can have other models as attributes. Models can have anon functions as attributes.
So i'm working on creating an algorithm that will deep clone most backbone models. I’m expecting that all bindings should be removed (for the new instance) during this copy so I’m not worried about trying to keep them.
Goals:
The simplified version of what I currently have is below:
/** * Performs a deep copy of a backbone.js model * All bindings for the copy are lost * @param orgModel - the original model to copy */ function deepCopyModel(orgModel) { var dupModel = Backbone.Model.extend({}); var orgAttributes= orgModel.toJSON(); var keepAttr=_.keys(orgAttributes); //remove any special cases keepAttr=_.without( keepAttr , 'specialCase1', 'specialCase2' ); //or keepAttr=_.difference(keepAttr, ['specialCase1', 'specialCase2'] ); //remove undefined values keepAttr=_.filter(keepAttr,function(key) { return ( typeof(attributes[key])!="undefined" ); }); //grab the resulting list of attributes after filtering var result=_.pick(attributes,keepAttr); //assign attributes to the copy using set dupModel.set(result); //TODO: Implement deep copy of functions //TODO: Implement deep copy of inner models return dupModel; }
Any help or insight you can give would be greatly appreciated. Thanks!
Model contains dynamic data and its logic. It performs various types of action on the data like validation, conversion, computed properties, access control etc. 1. It extends Backbone.
Spread operation is the easiest way to clone a object in ES6. Data loss happens on this method as well. However, since this is native to ES6 it is more performant than JSON. strigify().
A deep copy is a copy of all elements of the original object. Changes made to the original object will not be reflected in the copy. In this article, you will create deep copies of objects using the Lodash library.
BackboneJS allows developing of applications and the frontend in a much easier way by using JavaScript functions. BackboneJS provides various building blocks such as models, views, events, routers and collections for assembling the client side web applications.
jQuery's extend
method allows you to simply copy object properties from one to another.
Here's a contrived, but illustrative example. It even shows why you would not need to "deep" copy functions!
var someObj = {
a : "a",
b : 12345,
c : {
d : "d",
e : "e"
},
f : function() {
alert(this.a);
}
};
//copy from original to new empty object
var deepCopy = $.extend(true, {}, someObj);
deepCopy.a = "deepCopy.a";
deepCopy.c.d = "deepCopy.c.d";
alert("someObj is not affected when deep copying: " + someObj.c.d);
alert("deepCopy is entirely distinct when deep copying: " + deepCopy.c.d);
deepCopy.f();
someObj.f();
Here's a fiddle for your convenience: http://jsfiddle.net/S6p3F/3/
Running this code you will see that someObj
and deepCopy
are identical in structure but distinct objects.
As you can see, deep copying of functions is not required as the this
reference is bound to whatever object the function is applied to. This is becausein javascript, calling a function as deepCopy.f()
is functionally equivalent to deepCopy.f.call(deepCopy)
. A more illustrative example:
function someFunction() {
alert(this.someProperty);
}
var a = {
someProperty: "a's property"
},
b = {
someProperty: "b's property"
};
someFunction.call(a);
someFunction.call(b);
And a fiddle: http://jsfiddle.net/S6p3F/2/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With