62

I try to clone an array of objects with nested objects.

Something like:

var data = [
    { id: 1, values: { a: 'a', b: 'b' } },
    { id: 2, values: { c: 'c', d: 'd' } }
];

_.Clone

With the _.clone method and the isDeep parameter at true:

var clone = _.clone(data, true);

data[1].values.d = 'x';

console.log( _.isEqual(data, clone) ); // true, clone[1].values.d == 'x'

I expected clone[1].values.d == 'd' :

If isDeep is true nested objects will also be cloned, otherwise they will be assigned by reference.

What is wrong?

_.CloneDeep

In addition, when I try with the _.cloneDeep method, I get an error:

var clone = _.cloneDeep(data);

// Uncaught TypeError: Object function u(n){return n instanceof u?n:new o(n)}
// has no method 'cloneDeep'

Why this error?

$.extend

With $.extend the clone has no reference to the original object as expected:

var clone = $.extend(true, {}, data);

console.log( _.isEqual(data, clone) ); // false, clone[1].values.d == 'd' 
GG.
  • 21,083
  • 14
  • 84
  • 130
  • 8
    Are you sure that you're calling the lodash version of clone and not the underscore version? I get the same behaviour as you describe if i add lodash.js first followed by underscore.js. – Gruff Bunny Feb 18 '14 at 11:50
  • 2
    If I use the code in the question and assign lodash to `_`, I cannot reproduce the problem stated in the question. (That is, `_.clone` with `isDeep` set to `true` works as expected.) Gruff Bunny's hypothesis is a good one. I believe there's also a way to use lodash as an exact drop-in replacement for underscore.js. I'd expect such use of lodash to not perform deep copies since underscore.js does not do it. – Louis Feb 18 '14 at 12:24

1 Answers1

42

Thanks to Gruff Bunny and Louis' comments, I found the source of the issue.

As I use Backbone.js too, I loaded a special build of Lodash compatible with Backbone and Underscore that disables some features. In this example:

var clone = _.clone(data, true);

data[1].values.d = 'x';

I just replaced the Underscore build with the Normal build in my Backbone application and the application is still working. So I can now use the Lodash .clone with the expected behaviour.

Edit 2018: the Underscore build doesn't seem to exist anymore. If you are reading this in 2018, you could be interested by this documentation (Backbone and Lodash).

GG.
  • 21,083
  • 14
  • 84
  • 130