web-dev-qa-db-fra.com

Comment copier / cloner un hachage / un objet dans JQuery?

J'ai un objet simple (ou hash) en Javascript:

var settings = {
  link: 'http://example.com',
  photo: 'http://photos.com/me.jpg'
};

J'en ai besoin d'une copie. Existe-t-il une méthode de type settings.clone() qui me donnera un autre objet avec les mêmes attributs? J'utilise jQuery, donc heureux d'utiliser une méthode utilitaire jQuery s'il en existe une.

37
at.

Oui, étendre un objet vide avec l'original; de cette façon, tout sera simplement copié:

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

Extension d'un objet rempli avec un autre, par exemple:

$.extend({a:1}, {b:2})

retournera:

{a:1, b:2}

Avec la même logique:

$.extend({}, {foo:'bar', test:123})

retournera:

{foo:'bar', test:123}

c'est-à-dire efficacement un clone.

61
pimvdb

De manière non jQuery.

var newObj = {};

Object.keys(settings).forEach(function(key) {
     newObj[ key ] = settings[ key ];
}); 

Cela copie uniquement les propriétés de niveau supérieur. Pour copier des hachages avec des objets imbriqués en tant que valeurs de propriété, vous devrez utiliser une fonction récursive.

NB: La Object.keys(settings) évite d'avoir à appeler settings.hasOwnProperty(key).

32
Pantelis
var clone = $.extend(true, {}, settings);

Définissez le premier argument sur true.

EDIT: Le premier argument true signifie une copie complète. Pour un exemple donné dans la question d'origine, il n'est pas nécessaire de copier en profondeur car il existe de simples paires clé-valeur immuables. Pour une question dans le titre - comme cas général - utilisez une copie complète. Sinon, vous obtenez une demi-copie.

4
Rax

Il semble que vous souhaitiez étendre jQuery, qui peut copier un objet pour vous.

http://api.jquery.com/jQuery.extend/

2
aepheus

Mes 2 cents:

function clone(hash) {
  var json = JSON.stringify(hash);
  var object = JSON.parse(json);

  return object;
}

Ce n'est peut-être pas l'option la plus optimisée, mais elle peut être pratique pour certains scénarios.

1
fguillen

Underscore.js a également une fonction d'extension si vous n'utilisez pas jQuery:

extend _.extend(destination, *sources) Copiez toutes les propriétés des objets source vers l'objet de destination et renvoyez l'objet de destination. C'est dans l'ordre, donc la dernière source remplacera les propriétés du même nom dans les arguments précédents.

_.extend({name: 'moe'}, {age: 50});
=> {name: 'moe', age: 50}
1
d-coded