ChatGPT解决这个技术问题 Extra ChatGPT

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

G
GG.

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


Did you use underscore and lodash together?
No, Lodash replaces Underscore.