Skip to content

Instantly share code, notes, and snippets.

@Bargamut
Last active March 4, 2019 16:33
Show Gist options
  • Save Bargamut/5cd4a14a11541580433975a7360722f5 to your computer and use it in GitHub Desktop.
Save Bargamut/5cd4a14a11541580433975a7360722f5 to your computer and use it in GitHub Desktop.
/**
* Функция слияния объектов, стыренная у jQuery 3.1.1
* Варианты вызова:
* - Object.extend( target [, object1 ] [, objectN ] )
* - переписывает значенимя объекта
*
* - Object.extend( [deep ], target, object1 [, objectN ] )
* - выполняет слияние и обновление значенй клиента
*
* - Object.extend( [deep ], [overwriteArrays ], target, object1 [, objectN ] )
* - выполняет слияние и обновление значенй клиента, перезаписывая состав массивов
*
* Изменения вливаются от последнего аргумента к первому.
*
* @param deep - [ true | false ] рекурсивно обновляем (true) или перезаписываем (false)
* @param overwriteArrays - [ true | false ] перезаписываем (true) или обновляем (false) состав массива
* Перезаписывает и массивы, переданные как аргументы object1 .. objectN
* @param target - целевой объект, в который вливаются все изменения
* @param object1 .. objectN - группа объектов для слияния
*
* @returns {*|{}} - возвращает итоговый объект операций слияния.
*/
(function(OBJECT) {
var class2type = {},
getProto = Object.getPrototypeOf;
var hasOwn = class2type.hasOwnProperty;
var fnToString = hasOwn.toString;
var ObjectFunctionString = fnToString.call(Object);
function isPlainObject(obj) {
var proto, Ctor;
// Detect obvious negatives
// Use toString instead of jQuery.type to catch host objects
if (!obj || toString.call(obj) !== "[object Object]") return false;
proto = getProto(obj);
// Objects with no prototype (e.g., `Object.create( null )`) are plain
if (!proto) return true;
// Objects with prototype are plain iff they were constructed by a global Object function
Ctor = hasOwn.call(proto, "constructor") && proto.constructor;
return typeof Ctor === "function" && fnToString.call(Ctor) === ObjectFunctionString;
}
function opType(obj) {
if (obj == null) return obj + "";
// Support: Android <=2.3 only (functionish RegExp)
return typeof obj === "object" || typeof obj === "function" ?
class2type[toString.call(obj)] || "object" :
typeof obj;
}
function isFunction(obj) {
return opType(obj) === "function";
}
OBJECT.extend = OBJECT.extend || function() {
var options, name, src, copy, copyIsArray, clone,
target = arguments[0],
i = 1,
length = arguments.length,
deep = false,
overwrite = {
arrays: false
};
// Handle a deep copy situation
if (typeof target === "boolean") {
deep = target;
// Skip the boolean and the target
target = arguments[i];
i++;
}
// Если сказано переписывать массивы
if (typeof target === "boolean") {
overwrite.arrays = target;
// Skip the boolean and the target
target = arguments[i];
i++;
}
target = target || {};
// Handle case when target is a string or something (possible in deep copy)
if (typeof target !== "object" && !isFunction(target))
target = {};
// Extend ACMS itself if only one argument is passed
if (i === length) {
target = this;
i--;
}
for (; i < length; i++) {
// Only deal with non-null/undefined values
if ((options = arguments[i]) != null) {
// Если включена перезапись массивов и
// целевой и опциональный параметры - массивы,
// переписываем целевой массив
if (Array.isArray(target) &&
Array.isArray(options) &&
overwrite.arrays
) {
target = options;
continue;
}
// Extend the base object
for (name in options) {
if (!options.hasOwnProperty(name)) continue;
src = target[name];
copy = options[name];
// Prevent never-ending loop
if (target === copy) continue;
// Recurse if we're merging plain objects or arrays
if (deep &&
copy &&
(
isPlainObject(copy) ||
( copyIsArray = Array.isArray(copy) )
)
) {
if (copyIsArray) {
copyIsArray = false;
clone = src && Array.isArray(src) && !overwrite.arrays ? src : [];
} else
clone = src && isPlainObject(src) ? src : {};
// Never move original objects, clone them
target[name] = Object.extend(deep, overwrite.arrays, clone, copy);
// Don't bring in undefined values
} else if (copy !== undefined)
target[name] = copy;
}
}
}
// Return the modified object
return target;
};
}(Object.prototype));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment