BSD
У меня есть простой объект, который я бы хотел переопределить с другим, в случае, если некоторые из свойств не существуют в объекте, его следует взять из заданного по умолчанию объекта, может быть глубоко вложенным
Ниже приведен пример объекта настроек по умолчанию
defaults = {
name : 'Joe',
options : {
color : 'green',
dates : {
from : new Date,
to : new Date,
}
}
}
Вот предоставленный объект
settings = {
name : 'David',
options : {
color : 'purple'
}
}
Вот ожидаемый результат, комбинация между двумя...
final = {
name : 'David',
options : {
color : 'purple',
dates : {
from : new Date,
to : new Date,
}
}
}
Есть ли простой способ достичь этого без использования каких-либо внешних библиотек? Я пробовал некоторые подходы (JSON.stringify/parse
/iterating over objects/etc...), но не смог получить чистое решение... надеюсь, что oneliner
Любая помощь приветствуется...
Вот мой вклад.
Следует отметить, что код довольно длинный из-за характера
shallow
иdeep
копирования объекта.
Использование Object.assign(defaults, settings)
объединит ваши объекты, но ваш ключ date
будет удален, так как он выполняет мелкую копию объекта.
Ниже я использовал фрагмент, который я нашел о том, How to deep merge instead of shallow merge?
пользователем с именем jhildenbiddle
который выполняет deep
слияние объекта и является immutable
(не редактирует исходные массивы).
let defaults = {
name: 'Joe',
options: {
color: 'green',
dates: {
from: new Date(),
to: new Date(),
}
}
};
let settings = {
name: 'David',
options: {
color: 'purple'
}
};
function mergeDeep(...objects) {
const isObject = obj => obj && typeof obj === 'object';
return objects.reduce((prev, obj) => {
Object.keys(obj).forEach(key => {
const pVal = prev[key];
const oVal = obj[key];
if (Array.isArray(pVal) && Array.isArray(oVal)) {
prev[key] = pVal.concat(...oVal);
} else if (isObject(pVal) && isObject(oVal)) {
prev[key] = mergeDeep(pVal, oVal);
} else {
prev[key] = oVal;
}
});
return prev;
}, {});
}
let final = mergeDeep(defaults, settings);
console.log(final);
Используйте этот параметр $.extend(true, {}, defaults,settings)
. Обратите внимание на порядок переменной json. В этом случае settings
будут переопределять defaults
если эти две переменные имеют одинаковый атрибут.
Если вы смотрите на чистый ответ JS. Вот код.
function extend(a, b){
for (var key in b) {
if (b.hasOwnProperty(key))
a[key] = b[key];
return a;
}
}
}
console.log(extend(defaults,settings));
jQuery
не был включен в качестве тега, поэтому сообщите в своем посте, что вы используете jQuery
:)
JSON.stringify
.
Это может привести к тому, что вручную будет установлено каждое значение, если изменения по умолчанию изменены.
final = {
name : settings.name ? settings.name : "Joe",
options {
color: settings.color ? settings.color : "green",
dates: {
from : settings.dates.from ? settings.dates.from : new Date,
to: settings.dates.to ? settings.dates.to : new Date
}
}
}
Это, вероятно, будет работать лучше всего:
var final = Object.assign({}, default, settings);
Вы можете взглянуть на Object.assign
final = Object.assign(defaults, settings)