@piworks/jquery-extendext v0.1.3
jQuery.extendext
jQuery.extend with configurable behaviour for arrays.
Isn't $.extend good enough ?
Well, it's actually pretty good, and is generally sufficient, but it merges arrays in a strange way depending of what you want. Example:
var DEFAULTS = {
operators: ['AND', 'OR', 'XOR']
};
var config = {
operators: ['OR', 'XOR']
};
config = $.extend(true, {}, DEFAULTS, config);When executing this code, one will expects to get config.operators = ['OR', 'XOR'], but instead you get ['OR', 'XOR', 'XOR], because $.extend merges arrays like objects as per spec.
Other deep merging utilities I found either have the same behaviour or perform both merge and append on array values (nrf110/deepmerge for example).
Usage
jQuery.extendext.js contains a new $.extendext function with the exact same behaviour as $.extend if not additional config is provided.
The difference is that it accepts a optional second string argument to specify how arrays should be merged.
jQuery.extendext([deep ,][arrayMode ,] target, object1 [, objectN ] )- deep boolean — If true, the merge becomes recursive (aka. deep copy).
- arrayMode string — Specify the arrays merge operation, either
replace,concat,extendordefault - target object — The object to extend. It will receive the new properties.
- object1 object — An object containing additional properties to merge in.
- objectN object — Additional objects containing properties to merge in.
"replace" mode
In this mode, every Array values in target is replaced by a copy of the same value found in objectN. The copy is recursive if deep is true.
var DEFAULTS = {
operators: ['AND', 'OR', 'XOR']
};
var config = {
operators: ['OR', 'XOR']
};
config = $.extendext(true, 'replace', {}, DEFAULTS, config);
assert.deepEqual(config, {
operators: ['OR', 'XOR']
}) // true;"concat" mode
In this mode, Arrays found in both target and objectN are always concatenated. If deep is true, a recursive copy of each value if concatenated instead of the value itself.
var DEFAULTS = {
operators: ['AND', 'OR', 'XOR']
};
var config = {
operators: ['OR', 'XOR']
};
config = $.extendext(true, 'concat', {}, DEFAULTS, config);
assert.deepEqual(config, {
operators: ['AND', 'OR', 'XOR', 'OR', 'XOR']
}) // true;"extend" mode
This is how nrf110/deepmerge works. In this mode, Arrays values are treated a bit differently:
- If plain objects are found at the same position in both
targetandobjectNthey are merged recursively or not (depending ondeepoption). - Otherwise, if the value in
objectNis not found intarget, it is pushed at the end of the array.
var DEFAULTS = {
operators: ['AND', 'OR', 'XOR']
};
var config = {
operators: ['XOR', 'NAND']
};
config = $.extendext(true, 'extend', {}, DEFAULTS, config);
assert.deepEqual(config, {
operators: ['AND', 'OR', 'XOR', 'NAND']
}) // true;"default" mode
Same as $.extend.
var DEFAULTS = {
operators: ['AND', 'OR', 'XOR']
};
var config = {
operators: ['OR', 'XOR']
};
config = $.extendext(true, 'default', {}, DEFAULTS, config);
assert.deepEqual(config, {
operators: ['OR', 'XOR', 'XOR']
}) // true;Tests
A QUnit test suite is provided in tests directory.
$.extendext is tested against core jQuery tests for $.extend and nrf110/deepmerge tests (with the difference that extendext, like extend, modifies the first argument where deepmerge does not touch it).
6 years ago