60 lines
1.7 KiB
JavaScript
60 lines
1.7 KiB
JavaScript
export function cloneShallow(obj) {
|
|
return isPlainObject(obj)
|
|
? Object.assign({}, obj)
|
|
: Object.setPrototypeOf(Object.assign({}, obj), Object.getPrototypeOf(obj));
|
|
}
|
|
function isPlainObject(obj) {
|
|
if (typeof obj !== "object" ||
|
|
obj === null ||
|
|
Object.prototype.toString.call(obj) != "[object Object]") {
|
|
// Not an object
|
|
return false;
|
|
}
|
|
if (Object.getPrototypeOf(obj) === null) {
|
|
return true;
|
|
}
|
|
let proto = obj;
|
|
// Find the prototype
|
|
while (Object.getPrototypeOf(proto) !== null) {
|
|
proto = Object.getPrototypeOf(proto);
|
|
}
|
|
return Object.getPrototypeOf(obj) === proto;
|
|
}
|
|
export function merge(...args) {
|
|
let output = null, items = [...args];
|
|
while (items.length > 0) {
|
|
const nextItem = items.shift();
|
|
if (!output) {
|
|
output = cloneShallow(nextItem);
|
|
}
|
|
else {
|
|
output = mergeObjects(output, nextItem);
|
|
}
|
|
}
|
|
return output;
|
|
}
|
|
function mergeObjects(obj1, obj2) {
|
|
const output = cloneShallow(obj1);
|
|
Object.keys(obj2).forEach(key => {
|
|
if (!output.hasOwnProperty(key)) {
|
|
output[key] = obj2[key];
|
|
return;
|
|
}
|
|
if (Array.isArray(obj2[key])) {
|
|
output[key] = Array.isArray(output[key])
|
|
? [...output[key], ...obj2[key]]
|
|
: [...obj2[key]];
|
|
}
|
|
else if (typeof obj2[key] === "object" && !!obj2[key]) {
|
|
output[key] =
|
|
typeof output[key] === "object" && !!output[key]
|
|
? mergeObjects(output[key], obj2[key])
|
|
: cloneShallow(obj2[key]);
|
|
}
|
|
else {
|
|
output[key] = obj2[key];
|
|
}
|
|
});
|
|
return output;
|
|
}
|