122 lines
2.5 KiB
JavaScript
122 lines
2.5 KiB
JavaScript
var typeOf = require('./typeof'),
|
|
slice = Array.prototype.slice;
|
|
|
|
module.exports = {
|
|
clone: deepClone,
|
|
cloneShallow: clone,
|
|
extend: deepExtend,
|
|
extendShallow: extend,
|
|
update: deepUpdate,
|
|
updateShallow: update,
|
|
merge: deepMerge,
|
|
mergeShallow: merge
|
|
};
|
|
|
|
function clone(val) {
|
|
switch(typeOf(val)) {
|
|
case 'object':
|
|
var args = slice.call(arguments);
|
|
args.unshift({});
|
|
return extend.apply(null, args);
|
|
case 'array':
|
|
return [].concat(val);
|
|
case 'date':
|
|
return new Date(val.getTime());
|
|
case 'regexp':
|
|
return new RegExp(val);
|
|
default:
|
|
return val;
|
|
}
|
|
}
|
|
|
|
function deepClone(val) {
|
|
switch(typeOf(val)) {
|
|
case 'object':
|
|
var args = slice.call(arguments);
|
|
args.unshift({});
|
|
return deepExtend.apply(null, args);
|
|
case 'array':
|
|
return val.map(function(v) { return deepClone(v); });
|
|
default:
|
|
return clone(val);
|
|
}
|
|
}
|
|
|
|
function extend(a, b /*, [b2..n] */) {
|
|
slice.call(arguments, 1).forEach(function(b) {
|
|
Object.keys(b).forEach(function(p) {
|
|
a[p] = b[p];
|
|
});
|
|
});
|
|
return a;
|
|
}
|
|
|
|
function deepExtend(a, b /*, [b2..n] */) {
|
|
slice.call(arguments, 1).forEach(function(b) {
|
|
Object.keys(b).forEach(function(p) {
|
|
if(typeOf(b[p]) === 'object' && typeOf(a[p]) === 'object')
|
|
deepExtend(a[p], b[p]);
|
|
else
|
|
a[p] = deepClone(b[p]);
|
|
});
|
|
});
|
|
return a;
|
|
}
|
|
|
|
function update(a, b /*, [b2..n] */) {
|
|
slice.call(arguments, 1).forEach(function(b) {
|
|
Object.keys(b).forEach(function(p) {
|
|
if(a.hasOwnProperty(p)) a[p] = b[p];
|
|
});
|
|
});
|
|
return a;
|
|
}
|
|
|
|
function deepUpdate(a, b /*, [b2..n] */) {
|
|
slice.call(arguments, 1).forEach(function(b) {
|
|
var ap, bp, ta, tb;
|
|
Object.keys(b).forEach(function(p) {
|
|
if(a.hasOwnProperty(p)) {
|
|
ap = a[p];
|
|
bp = b[p];
|
|
ta = typeOf(ap);
|
|
tb = typeOf(bp);
|
|
if(tb === 'object' && ta === 'object')
|
|
deepUpdate(ap, bp);
|
|
else if(tb === 'array' && ta === 'array') {
|
|
ap.length = 0;
|
|
ap.push.apply(ap, bp.map(function(v) { return deepClone(v); }));
|
|
} else
|
|
a[p] = deepClone(bp);
|
|
}
|
|
});
|
|
});
|
|
return a;
|
|
}
|
|
|
|
function merge(a, b /*, [b2..n] */) {
|
|
slice.call(arguments, 1).forEach(function(b) {
|
|
Object.keys(b).forEach(function(p) {
|
|
if(!a.hasOwnProperty(p)) a[p] = b[p];
|
|
});
|
|
});
|
|
return a;
|
|
}
|
|
|
|
function deepMerge(a, b /*, [b2..n] */) {
|
|
slice.call(arguments, 1).forEach(function(b) {
|
|
var ap, bp, ta, tb;
|
|
Object.keys(b).forEach(function(p) {
|
|
ap = a[p];
|
|
bp = b[p];
|
|
ta = typeOf(ap);
|
|
tb = typeOf(bp);
|
|
if(tb === 'object' && ta === 'object')
|
|
deepMerge(ap, bp);
|
|
else if(!a.hasOwnProperty(p))
|
|
a[p] = deepClone(bp);
|
|
});
|
|
});
|
|
return a;
|
|
}
|