Untitled diff
61 removals
Lines | |
---|---|
Total | 153 |
Removed | -34.6%53 |
Words | |
Total | 538 |
Removed | -11.7%63 |
153 lines
64 additions
Lines | |
---|---|
Total | 155 |
Added | +35.5%55 |
Words | |
Total | 661 |
Added | +28.1%186 |
155 lines
# src
# babel
'use strict';
'use strict';
/*
/*
* OBJECT ASSIGN DEEP
* OBJECT ASSIGN DEEP
* Allows deep cloning of plain objects that contain primitives, nested plain objects, or nested plain arrays.
* Allows deep cloning of plain objects that contain primitives, nested plain objects, or nested plain arrays.
*/
*/
/*
/*
* A unified way of returning a string that describes the type of the given variable.
* A unified way of returning a string that describes the type of the given variable.
*/
*/
function getTypeOf (input) {
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
function getTypeOf(input) {
if (input === null) {
if (input === null) {
return 'null';
return 'null';
}
} else if (typeof input === 'undefined') {
else if (typeof input === 'undefined') {
return 'undefined';
return 'undefined';
}
} else if ((typeof input === 'undefined' ? 'undefined' : _typeof(input)) === 'object') {
return Array.isArray(input) ? 'array' : 'object';
else if (typeof input === 'object') {
return (Array.isArray(input) ? 'array' : 'object');
}
}
return typeof input;
return typeof input === 'undefined' ? 'undefined' : _typeof(input);
}
}
/*
/*
* Branching logic which calls the correct function to clone the given value base on its type.
* Branching logic which calls the correct function to clone the given value base on its type.
*/
*/
function cloneValue (value) {
function cloneValue(value) {
// The value is an object so lets clone it.
// The value is an object so lets clone it.
if (getTypeOf(value) === 'object') {
if (getTypeOf(value) === 'object') {
return quickCloneObject(value);
return quickCloneObject(value);
}
}
// The value is an array so lets clone it.
// The value is an array so lets clone it.
else if (getTypeOf(value) === 'array') {
else if (getTypeOf(value) === 'array') {
return quickCloneArray(value);
return quickCloneArray(value);
}
}
// Any other value can just be copied.
// Any other value can just be copied.
return value;
return value;
}
}
/*
/*
* Enumerates the given array and returns a new array, with each of its values cloned (i.e. references broken).
* Enumerates the given array and returns a new array, with each of its values cloned (i.e. references broken).
*/
*/
function quickCloneArray (input) {
function quickCloneArray(input) {
return input.map(cloneValue);
return input.map(cloneValue);
}
}
/*
/*
* Enumerates the properties of the given object (ignoring the prototype chain) and returns a new object, with each of
* Enumerates the properties of the given object (ignoring the prototype chain) and returns a new object, with each of
* its values cloned (i.e. references broken).
* its values cloned (i.e. references broken).
*/
*/
function quickCloneObject (input) {
function quickCloneObject(input) {
const output = {};
var output = {};
for (const key in input) {
for (var key in input) {
if (!input.hasOwnProperty(key)) { continue; }
if (!input.hasOwnProperty(key)) {
continue;
}
output[key] = cloneValue(input[key]);
output[key] = cloneValue(input[key]);
}
}
return output;
return output;
}
}
/*
/*
* Does the actual deep merging.
* Does the actual deep merging.
*/
*/
function executeDeepMerge (target, _objects = [], _options = {}) {
function executeDeepMerge(target) {
var _objects = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
const options = {
var _options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
arrayBehaviour: _options.arrayBehaviour || 'replace', // Can be "merge" or "replace".
var options = {
arrayBehaviour: _options.arrayBehaviour || 'replace' // Can be "merge" or "replace".
};
};
// Ensure we have actual objects for each.
// Ensure we have actual objects for each.
const objects = _objects.map(object => object || {});
var objects = _objects.map(function (object) {
const output = target || {};
return object || {};
});
var output = target || {};
// Enumerate the objects and their keys.
// Enumerate the objects and their keys.
for (let oindex = 0; oindex < objects.length; oindex++) {
for (var oindex = 0; oindex < objects.length; oindex++) {
const object = objects[oindex];
var object = objects[oindex];
const keys = Object.keys(object);
var keys = Object.keys(object);
for (let kindex = 0; kindex < keys.length; kindex++) {
for (var kindex = 0; kindex < keys.length; kindex++) {
const key = keys[kindex];
var key = keys[kindex];
const value = object[key];
var value = object[key];
const type = getTypeOf(value);
var type = getTypeOf(value);
const existingValueType = getTypeOf(output[key]);
var existingValueType = getTypeOf(output[key]);
if (type === 'object') {
if (type === 'object') {
if (existingValueType !== 'undefined') {
if (existingValueType !== 'undefined') {
const existingValue = (existingValueType === 'object' ? output[key] : {});
var existingValue = existingValueType === 'object' ? output[key] : {};
output[key] = executeDeepMerge({}, [existingValue, quickCloneObject(value)], options);
output[key] = executeDeepMerge({}, [existingValue, quickCloneObject(value)], options);
}
} else {
else {
output[key] = quickCloneObject(value);
output[key] = quickCloneObject(value);
}
}
}
} else if (type === 'array') {
else if (type === 'array') {
if (existingValueType === 'array') {
if (existingValueType === 'array') {
const newValue = quickCloneArray(value);
var newValue = quickCloneArray(value);
output[key] = (options.arrayBehaviour === 'merge' ? output[key].concat(newValue) : newValue);
output[key] = options.arrayBehaviour === 'merge' ? output[key].concat(newValue) : newValue;
}
} else {
else {
output[key] = quickCloneArray(value);
output[key] = quickCloneArray(value);
}
}
}
} else {
else {
output[key] = value;
output[key] = value;
}
}
}
}
}
}
return output;
return output;
}
}
/*
/*
* Merge all the supplied objects into the target object, breaking all references, including those of nested objects
* Merge all the supplied objects into the target object, breaking all references, including those of nested objects
* and arrays, and even objects nested inside arrays. The first parameter is not mutated unlike Object.assign().
* and arrays, and even objects nested inside arrays. The first parameter is not mutated unlike Object.assign().
* Properties in later objects will always overwrite.
* Properties in later objects will always overwrite.
*/
*/
module.exports = function objectAssignDeep (target, ...objects) {
module.exports = function objectAssignDeep(target) {
for (var _len = arguments.length, objects = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
objects[_key - 1] = arguments[_key];
}
return executeDeepMerge(target, objects);
return executeDeepMerge(target, objects);
};
};
/*
/*
* Same as objectAssignDeep() except it doesn't mutate the target object and returns an entirely new object.
* Same as objectAssignDeep() except it doesn't mutate the target object and returns an entirely new object.
*/
*/
module.exports.noMutate = function objectAssignDeepInto (...objects) {
module.exports.noMutate = function objectAssignDeepInto() {
for (var _len2 = arguments.length, objects = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
objects[_key2] = arguments[_key2];
}
return executeDeepMerge({}, objects);
return executeDeepMerge({}, objects);
};
};
/*
/*
* Allows an options object to be passed in to customise the behaviour of the function.
* Allows an options object to be passed in to customise the behaviour of the function.
*/
*/
module.exports.withOptions = function objectAssignDeepInto (target, objects, options) {
module.exports.withOptions = function objectAssignDeepInto(target, objects, options) {
return executeDeepMerge(target, objects, options);
return executeDeepMerge(target, objects, options);
};
};