2017-08-21 08:50:25 +08:00

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;
}