I'm using jQuery extend
in a plugin to overwrite the default parameters. However, I have a problem.
Here's my default settings array:
slider.settings = {
background: {
animation : {
direction : 'horizontal',
increment : 15 //can be any number
}
}
}
Now, I want to overwrite the direction
parameter. Here's the array that I will merge with using extend
:
settingsToOverwrite = {
background:{
animation:{
direction:'vertical'
}
}
}
Now, I merge the two:
slider.settings = $.extend(slider.settings, options)
I can see that the direction value has been updated. However, increment is no longer there. I know that to avoid this problem I could only set parameters at the first level but I see more code clarity in doing my way. Is there a way to do so ? If not, I will change everything to be only one level deep.
By default, jQuery.extend()
only compares the immediate properties, performing a "shallow merge." Since both objects have background
, it simply takes the entire background
from the 2nd object.
But, pass a true
as the 1st argument, and jQuery.extend()
will perform a "deep merge."
slider.settings = $.extend(true, slider.settings, options);
Also, since the 1st Object
is the target
and will be both modified and return
'd, you can update slider.settings
with just:
$.extend(true, slider.settings, options);
And, if you'd rather have a new Object
from the merge, you'll have to create it yourself:
slider.settings = $.extend(true, {}, slider.settings, options);
You are right, this is obviously happening because jQuery's extend is "shallow extending" the object.. thus replacing the entire "animation" property.
To fix this, use your brandy dandy deepExtend:
Object.deepExtend = function(destination, source) {
for (var property in source) { // loop through the objects properties
if (typeof source[property] === "object") { // if this is an object
destination[property] = destination[property] || {};
Object.deepExtend(destination[property], source[property]); // recursively deep extend
} else {
destination[property] = source[property]; // otherwise just copy
}
}
return destination;
};
You can use it as follows:
slider.settings = Object.deepExtend(slider.settings, options);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With