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

Библиотека Cash предоставляет удобный и компактный API для работы с DOM, однако одной из её менее известных возможностей является работа с объектами и их слиянием. Слияние объектов позволяет объединять свойства нескольких объектов в один, сохраняя при этом оригинальные значения, если они не переопределяются.

В Cash слияние объектов осуществляется с помощью метода $.extend(). Этот метод позаимствован из jQuery и обладает схожей функциональностью, но в Cash реализован максимально оптимизировано для современного JavaScript.


Синтаксис метода $.extend

$.extend(target, ...sources)
  • target — объект, в который будут скопированы свойства.
  • sources — один или несколько объектов, свойства которых нужно добавить или обновить в target.

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


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

const defaults = { color: 'blue', size: 'medium' };
const options = { size: 'large', weight: 'bold' };

const settings = $.extend({}, defaults, options);
console.log(settings); // { color: 'blue', size: 'large', weight: 'bold' }

В этом примере создаётся новый объект, объединяющий значения defaults и options. Поскольку size присутствует в обоих объектах, сохраняется значение из options.


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

По умолчанию $.extend() выполняет поверхностное копирование свойств. Для вложенных объектов потребуется глубокое слияние, которое позволяет рекурсивно объединять свойства на всех уровнях вложенности. В Cash это делается с использованием первого аргумента true:

const obj1 = { user: { name: 'Alice', age: 25 } };
const obj2 = { user: { age: 30, city: 'Paris' } };

const merged = $.extend(true, {}, obj1, obj2);
console.log(merged); // { user: { name: 'Alice', age: 30, city: 'Paris' } }
  • Первый аргумент true активирует глубокое слияние.
  • Все вложенные свойства объектов объединяются рекурсивно.
  • Значения из объектов-источников заменяют значения целевого объекта только при совпадении ключей.

Слияние массивов и особенностей копирования

При слиянии массивов метод $.extend() не объединяет элементы массива поэлементно. Вложенные массивы копируются как объекты, и целиком заменяются последующими объектами-источниками:

const a = { list: [1, 2] };
const b = { list: [3, 4] };

const result = $.extend(true, {}, a, b);
console.log(result); // { list: [3, 4] }

Если требуется объединение массивов, нужно использовать отдельную логику, например:

const mergedArrays = {
  list: [...a.list, ...b.list]
};

Использование $.extend для конфигурации плагинов

Частая задача в разработке с Cash — создание настраиваемых плагинов. Для этого удобно использовать $.extend для объединения стандартных настроек и пользовательских опций:

const defaultOptions = {
  animation: true,
  duration: 300,
  easing: 'linear'
};

function createPlugin(userOptions) {
  const options = $.extend({}, defaultOptions, userOptions);
  console.log(options);
}

createPlugin({ duration: 500, easing: 'ease-in-out' });
// { animation: true, duration: 500, easing: 'ease-in-out' }

Такая практика обеспечивает гибкость: дефолтные значения остаются, а пользовательские параметры корректно переопределяют их.


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

Важно помнить, что $.extend напрямую изменяет целевой объект. Чтобы не изменять исходные данные, рекомендуется создавать пустой объект как первый аргумент:

const original = { x: 1, y: 2 };
const additional = { y: 3, z: 4 };

const combined = $.extend({}, original, additional);
console.log(original); // { x: 1, y: 2 } — без изменений
console.log(combined); // { x: 1, y: 3, z: 4 }

Особенности и советы по использованию

  1. Поверхностное vs глубокое слияние

    • Поверхностное ($.extend(target, source)) подходит для плоских объектов.
    • Глубокое ($.extend(true, target, source)) — для вложенных структур.
  2. Объединение массивов требует дополнительной логики, так как массивы не сливаются поэлементно.

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

  4. Приоритет значений определяется порядком объектов в аргументах: последний источник имеет наибольший приоритет.

  5. Слияние функций и нестандартных объектов копирует ссылки, а не значения, поэтому для функций или сложных классов может потребоваться дополнительная обработка.


Примеры с реальными DOM-настройками

const defaultStyles = {
  color: 'black',
  fontSize: '14px',
  padding: '5px'
};

const userStyles = {
  fontSize: '16px',
  margin: '10px'
};

const finalStyles = $.extend({}, defaultStyles, userStyles);
console.log(finalStyles);
// { color: 'black', fontSize: '16px', padding: '5px', margin: '10px' }

Метод позволяет легко собирать CSS-настройки, опции виджетов или конфигурации анимации, объединяя базовые значения с индивидуальными.


Метод $.extend является мощным инструментом Cash для работы с объектами, обеспечивая компактное и удобное слияние как плоских, так и вложенных структур, с сохранением приоритета пользовательских данных и возможности создавать полностью новые объекты без изменения исходных.