recursive hash merging in javascript

I needed to recursively merge hashses in javascript to deal with options hashes.

jQuery does it with jQuery.extend() but there’s a caveat.  By default extend doesn’t traverse the hashes recursively.  It’s important to note that jQuery.extend() is most commonly used in plugins to add additional methods and objects to the jQuery object/namespace.

.extend does several things:

  • with one param it merges the hash into the jQuery object
  • with two it treats the first as the target and merges subsequent hashes into it
  • the kicker: if you pass true as the first param .extend() merges recursively

So:

var a = {option1: 'value1', option2: { param1: 'value2', param2: 'value3'} };
var b = {option2: { param2: 'value4' } };
jQuery.extend(a, b);

a.option2 is just {param2: ‘value4′} not {param1: ‘value2′, param2: ‘value4′}

but (after reinitialzing a since extend modifies the target) :

jQuery.extend(true, a, b)

and now a.param2 is {param1: ‘value2′, param2: ‘value4′} as I’d like.

to translate:

jQuery.extend(hash1, hash2) is like php’s array_merge()

jQuery.extend(true, hash1, hash2) is like CakePHP’s Set::merge() (an explanation of Set::merge by Felix Geisendörfer is here)