J'essaie de cloner un tableau d'objets avec des objets imbriqués.
Quelque chose comme:
var data = [
{ id: 1, values: { a: 'a', b: 'b' } },
{ id: 2, values: { c: 'c', d: 'd' } }
];
Avec le _.clone
méthode et le paramètre isDeep
à true
:
var clone = _.clone(data, true);
data[1].values.d = 'x';
console.log( _.isEqual(data, clone) ); // true, clone[1].values.d == 'x'
J'esperais clone[1].values.d == 'd'
:
Si isDeep est true, les objets imbriqués seront également clonés, sinon ils seront affectés par référence.
Qu'est-ce qui ne va pas?
De plus, quand j'essaie avec le _.cloneDeep
méthode, j'obtiens une erreur:
var clone = _.cloneDeep(data);
// Uncaught TypeError: Object function u(n){return n instanceof u?n:new o(n)}
// has no method 'cloneDeep'
Pourquoi cette erreur?
Avec $.extend
le clone n'a aucune référence à l'objet d'origine comme prévu:
var clone = $.extend(true, {}, data);
console.log( _.isEqual(data, clone) ); // false, clone[1].values.d == 'd'
Grâce aux commentaires de Gruff Bunny et de Louis, j'ai trouvé la source du problème.
Comme j'utilise Backbone.js aussi, j'ai chargé une version spéciale de Lodash compatible avec Backbone et Underscore qui désactive certaines fonctionnalités. Dans cet exemple:
var clone = _.clone(data, true);
data[1].values.d = 'x';
_.isEqual(data, clone) === false
_.isEqual(data, clone) === true
Je viens de remplacer la construction Underscore par la construction Normal dans mon application Backbone et l'application fonctionne toujours. Je peux donc maintenant utiliser le Lodash .clone avec le comportement attendu.
Edit 2018: la construction Underscore ne semble plus exister . Si vous lisez ceci en 2018, vous pourriez être intéressé par cette documentation (Backbone et Lodash).