Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lodash .clone and .cloneDeep behaviors

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' 
like image 554
GG. Avatar asked Feb 18 '14 11:02

GG.


People also ask

What does _ cloneDeep do?

The _. cloneDeep() method is used to create a deep copy of the value i.e. it recursively clones the value.

How do you copy an object in Lodash?

Lodash's clone() function is a powerful utility for shallow cloning generic objects. The Object. assign() function or the spread operator are the canonical methods for shallow copying a POJO.

Is Deep equal Lodash?

The Lodash _. isEqual() Method performs a deep comparison between two values to determine if they are equivalent. This method supports comparing arrays, array buffers, boolean, date objects, maps, numbers, objects, regex, sets, strings, symbols, and typed arrays.


Video Answer


1 Answers

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';
  • with the Normal build: _.isEqual(data, clone) === false
  • with the Underscore build: _.isEqual(data, clone) === true

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).

like image 91
GG. Avatar answered Oct 11 '22 06:10

GG.