Я хотел бы представить довольно простой вариант ES5. Функция получает 2 параметра - target
и source
, которые должны быть типа «объект». Target
будет результирующим объектом. Target
сохраняет все свои исходные свойства, но их значения могут быть изменены.
function deepMerge(target, source) {
if(typeof target !== 'object' || typeof source !== 'object') return false; // target or source or both ain't objects, merging doesn't make sense
for(var prop in source) {
if(!source.hasOwnProperty(prop)) continue; // take into consideration only object's own properties.
if(prop in target) { // handling merging of two properties with equal names
if(typeof target[prop] !== 'object') {
target[prop] = source[prop];
} else {
if(typeof source[prop] !== 'object') {
target[prop] = source[prop];
} else {
if(target[prop].concat && source[prop].concat) { // two arrays get concatenated
target[prop] = target[prop].concat(source[prop]);
} else { // two objects get merged recursively
target[prop] = deepMerge(target[prop], source[prop]);
}
}
}
} else { // new properties get added to target
target[prop] = source[prop];
}
}
return target;
}
случаи:
target
не имеет source
свойство target
получает его; target
имеет свойство source
и target
& amp; source
не являются обеими объектами (3 случая из 4), свойство target
получает overriden; target
имеет свойство source
, и оба они являются объектами / массивами (1 оставшийся случай), тогда рекурсия объединяет два объекта (или объединение двух массивов), также учитывает следующее:
Предсказуемо, поддерживает примитивные типы, а также массивы и объекты. Кроме того, поскольку мы можем объединить 2 объекта, я думаю, что мы можем объединить более двух с помощью функции reduce .
взглянуть на пример (и поиграть с ним, если хотите ):
var a = {
"a_prop": 1,
"arr_prop": [4, 5, 6],
"obj": {
"a_prop": {
"t_prop": 'test'
},
"b_prop": 2
}
};
var b = {
"a_prop": 5,
"arr_prop": [7, 8, 9],
"b_prop": 15,
"obj": {
"a_prop": {
"u_prop": false
},
"b_prop": {
"s_prop": null
}
}
};
function deepMerge(target, source) {
if(typeof target !== 'object' || typeof source !== 'object') return false;
for(var prop in source) {
if(!source.hasOwnProperty(prop)) continue;
if(prop in target) {
if(typeof target[prop] !== 'object') {
target[prop] = source[prop];
} else {
if(typeof source[prop] !== 'object') {
target[prop] = source[prop];
} else {
if(target[prop].concat && source[prop].concat) {
target[prop] = target[prop].concat(source[prop]);
} else {
target[prop] = deepMerge(target[prop], source[prop]);
}
}
}
} else {
target[prop] = source[prop];
}
}
return target;
}
console.log(deepMerge(a, b));
Существует ограничение - длина стека вызовов браузера. Современные браузеры выдадут ошибку на каком-то действительно глубоком уровне рекурсии (подумайте о тысячах вложенных вызовов). Кроме того, вы можете свободно обращаться с ситуациями типа array + object и т. Д., Добавив новые условия и проверки типов.
Параметр retry_interval контролировал случай, когда сообщение не было подтверждено во время нормальной работы, то есть клиент, по-видимому, не отключился, но не отправлял подтверждения.
Повтор доставки сообщения, описанный в спецификации, охватывает случай, когда клиент повторно подключается. Такое поведение присутствует в Mosquitto, поэтому нарушения спецификации нет, и сообщения будут повторены.