Слияние объектов

Umbrella JS предоставляет легкий и удобный инструмент для работы с DOM и объектами в JavaScript, включая функциональность слияния объектов. Слияние объектов — важная операция при объединении настроек, конфигураций или данных из нескольких источников. В Umbrella JS для этих целей используется метод u.extend().


Основы метода u.extend()

Метод u.extend() позволяет объединять свойства одного или нескольких объектов в целевой объект. Его базовый синтаксис:

u.extend(target, source1, source2, ...);
  • target — объект, в который будут скопированы свойства других объектов.
  • source1, source2 … — объекты, чьи свойства будут добавлены в target.

Если в целевом объекте уже существует свойство с таким же ключом, оно будет перезаписано значением из последующего объекта.

Пример базового слияния:

const obj1 = {a: 1, b: 2};
const obj2 = {b: 3, c: 4};

u.extend(obj1, obj2);

console.log(obj1); // {a: 1, b: 3, c: 4}

Здесь свойство b из obj1 было заменено значением из obj2, а свойство c было добавлено.


Слияние нескольких объектов

u.extend() поддерживает объединение любого количества объектов:

const defaults = {width: 100, height: 100, color: 'red'};
const settings = {height: 200};
const userOptions = {color: 'blue', border: '1px solid black'};

u.extend(defaults, settings, userOptions);

console.log(defaults);
// {width: 100, height: 200, color: 'blue', border: '1px solid black'}
  • Порядок аргументов имеет значение: свойства объектов, переданных позже, перезаписывают предыдущие.
  • Все изменения происходят в целевом объекте (defaults в примере).

Глубокое слияние

По умолчанию u.extend() выполняет поверхностное слияние, то есть вложенные объекты не объединяются, а полностью заменяются.

const obj1 = {a: {x: 1, y: 2}};
const obj2 = {a: {y: 3, z: 4}};

u.extend(obj1, obj2);

console.log(obj1); // {a: {y: 3, z: 4}}

Если требуется глубокое слияние, необходимо использовать рекурсивную функцию, так как встроенного глубокого слияния в Umbrella JS нет:

function deepExtend(target, ...sources) {
  sources.forEach(source => {
    for (let key in source) {
      if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) {
        if (!target[key] || typeof target[key] !== 'object') {
          target[key] = {};
        }
        deepExtend(target[key], source[key]);
      } else {
        target[key] = source[key];
      }
    }
  });
  return target;
}

const obj1 = {a: {x: 1, y: 2}};
const obj2 = {a: {y: 3, z: 4}};

deepExtend(obj1, obj2);

console.log(obj1); // {a: {x: 1, y: 3, z: 4}}

Копирование без изменения исходного объекта

Иногда важно не изменять исходный объект, а создать новый объединенный объект:

const defaults = {a: 1, b: 2};
const options = {b: 3, c: 4};

const merged = u.extend({}, defaults, options);

console.log(merged);  // {a: 1, b: 3, c: 4}
console.log(defaults); // {a: 1, b: 2}

Использование пустого объекта {} в качестве target гарантирует сохранность исходных данных.


Практические применения

  1. Конфигурация плагинов Объединение настроек по умолчанию с пользовательскими параметрами:
const defaultConfig = {autoplay: true, speed: 300};
const userConfig = {speed: 500};

const finalConfig = u.extend({}, defaultConfig, userConfig);
  1. Объединение данных формы Сбор значений нескольких источников:
const personalData = {name: 'Alice', age: 25};
const contactData = {email: 'alice@example.com', phone: '123456789'};

const userData = u.extend({}, personalData, contactData);
  1. Сбор стилей Формирование CSS-свойств для элементов:
const baseStyles = {color: 'black', fontSize: '16px'};
const hoverStyles = {color: 'red'};

const combinedStyles = u.extend({}, baseStyles, hoverStyles);

Особенности и рекомендации

  • u.extend() не копирует функции прототипа объектов, только их собственные свойства.
  • Для массивов используется обычная замена, а не объединение элементов.
  • Порядок аргументов критичен: последние объекты перезаписывают предыдущие свойства.
  • При глубоких вложенных структурах рекомендуется использовать рекурсивные методы, как deepExtend.

С помощью u.extend() в Umbrella JS обеспечивается быстрая и удобная работа с объектами, позволяющая объединять конфигурации, данные и стили без сложных манипуляций с циклом или Object.assign.