40

I have a simple object (or hash) in Javascript:

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

I need a copy of it. Is there a settings.clone() type method that will give me another object with the same attributes? I'm using jQuery, so happy to use a jQuery utility method if one exists.

Charles Merriam
  • 19,908
  • 6
  • 73
  • 83
at.
  • 50,922
  • 104
  • 292
  • 461
  • possible duplicate of [Copying an Object in Javascript](http://stackoverflow.com/questions/728360/copying-an-object-in-javascript) – Bergi Feb 21 '13 at 11:57
  • IMHO this should be renamed 'How to copy/clone a hash/object in **jquery**'. Then it would be different from the above duplicate. – AnnanFay Nov 18 '14 at 22:49

6 Answers6

66

Yes, extend an empty object with the original one; that way, everything will simply be copied:

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

Extending some filled object with another, e.g.:

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

will return:

{a:1, b:2}

With the same logic:

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

will return:

{foo:'bar', test:123}

i.e. effectively a clone.

pimvdb
  • 151,816
  • 78
  • 307
  • 352
  • 4
    incorrect; contained objects are still passed by reference, and not deep-cloned, e.g. a={aa:{aaa:3}}; b=$extend({},a}; a.aa.aaa=4; b.aa.aaa==4 !! – Berry Tsakala Feb 09 '14 at 15:18
  • 3
    @BerryTsakala: Since JQuery 1.1.4 you can use [`extend(true, ...)`](https://api.jquery.com/jQuery.extend/#jQuery-extend-deep-target-object1-objectN) to create deep copies. – Florian Brucker Dec 07 '15 at 12:30
33

In a non jQuery way.

var newObj = {};

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

This copies only the top-level properties. To copy hashes with nested objects as property values, you will need to use a recursive function.

NB: The Object.keys(settings) avoids the need for calling settings.hasOwnProperty(key).

Cheeso
  • 189,189
  • 101
  • 473
  • 713
Pantelis
  • 6,086
  • 1
  • 18
  • 21
4
var clone = $.extend(true, {}, settings);

Set first argument to true.

EDIT: First argument true signifies deep copy. For given example in original question there is no need for deep copy since there are simple immutable key-value pairs. For question in title - as a general case - use deep copy. Otherwise you get half-copy.

Rax
  • 470
  • 5
  • 15
2

My 2 cents:

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

  return object;
}

It may not be the most optimized option but it can be handy for some scenarios.

fguillen
  • 36,125
  • 23
  • 149
  • 210
2

It sounds like you want jQuery extend, which can copy an object for you.

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

aepheus
  • 7,827
  • 7
  • 36
  • 51
1

Underscore.js also has an extend function if you are not using jQuery:

extend _.extend(destination, *sources) Copy all of the properties in the source objects over to the destination object, and return the destination object. It's in-order, so the last source will override properties of the same name in previous arguments.

_.extend({name: 'moe'}, {age: 50});
=> {name: 'moe', age: 50}
Cees Timmerman
  • 17,623
  • 11
  • 91
  • 124
d-coded
  • 413
  • 3
  • 9