Мне нужно объединить два (очень простых) объекта JavaScript во время выполнения. Например, я хотел бы:
var obj1 = { food: 'pizza', car: 'ford' }
var obj2 = { animal: 'dog' }
obj1.merge(obj2);
//obj1 now has three properties: food, car, and animal
У кого-нибудь есть сценарий для этого или знаете встроенный способ сделать это? Мне не нужна рекурсия, и мне не нужно объединять функции, только методы для плоских объектов.
javascript
javascript-objects
JC Grubbs
источник
источник
var obj2 = { animal: 'dog', food: 'bone' };
, слияние было бы{ food: 'bone', car: 'ford', animal: 'dog' }
. Если вы работаете с «вложенными данными» и хотите «глубокое слияние», ищите ответы, в которых упоминается «глубокое слияние» или «рекурсия». Если у вас есть значения, которые естьarrays
, то используйте опцию «arrayMerge» в github «TehShrike / deepmerge», как упомянуто здесь .Ответы:
ECMAScript 2018 Стандартный метод
Вы бы использовали объект распространения :
merged
теперь союзobj1
иobj2
. Свойства вobj2
перезапишут те вobj1
.Вот также документация MDN для этого синтаксиса. Если вы используете babel, вам понадобится плагин babel-plugin-transform-object-rest-spread, чтобы он работал.
ECMAScript 2015 (ES6) Стандартный метод
(см. MDN JavaScript Reference )
Метод для ES5 и ранее
Обратите внимание , что это будет просто добавить все атрибуты
obj2
дляobj1
которых не может быть то , что вы хотите , если вы все еще хотите использовать неизмененныйobj1
.Если вы используете фреймворк, охватывающий все ваши прототипы, вам придется потрудиться с подобными проверками
hasOwnProperty
, но этот код будет работать в 99% случаев.Пример функции:
источник
var merged = {...obj1, ...obj2}
.{...obj1, ...{animal: 'dog'}}
У jQuery также есть утилита для этого: http://api.jquery.com/jQuery.extend/ .
Взято из документации по jQuery:
Приведенный выше код будет мутировать существующий объект с именем
settings
.Если вы хотите создать новый объект без изменения любого аргумента, используйте это:
источник
jQuery.extend(true,settings,override)
, что важно, если свойство в настройках содержит объект, а переопределение имеет только часть этого объекта. Вместо удаления несогласованных свойств глубокий параметр будет обновляться только там, где он существует. По умолчанию установлено значение false.Harmony ECMAScript 2015 (ES6) указывает ,
Object.assign
который будет делать это.Текущая поддержка браузеров становится лучше , но если вы разрабатываете для браузеров, которые не поддерживают, вы можете использовать полифилл .
источник
Object.assign
имеет довольно приличное освещение: kangax.github.io/compat-table/es6/…Object.assign({}, obj1, obj2)
Я гуглил код для слияния свойств объекта и оказался здесь. Однако, поскольку не было никакого кода для рекурсивного слияния, я написал его сам. (Может быть, JQuery Extench является рекурсивным BTW?) В любом случае, надеюсь, кто-то еще найдет это полезным.
(Сейчас код не использует
Object.prototype
:)Код
Пример
Создает объект o3 like
источник
Обратите внимание , что
underscore.js
«Sextend
-метод делает это в однострочнике:источник
_({}).extend(obj1, obj2);
_.defaults(object, *defaults)
«Заполните нулевые и неопределенные свойства в объекте значениями из объектов по умолчанию и верните объект».var mergedObj = _.extend({}, obj1, obj2)
.Подобно jQuery extend (), у вас есть такая же функция в AngularJS :
источник
Мне нужно объединить объекты сегодня, и этот вопрос (и ответы) мне очень помог. Я попробовал некоторые ответы, но ни один из них не соответствовал моим потребностям, поэтому я соединил некоторые ответы, добавил что-то сам и предложил новую функцию слияния. Вот:
Некоторые примеры использования:
источник
merge({}, t1, { key1: 1 })
?Вы можете использовать свойства распространения объекта - в настоящее время предложение ECMAScript этапа 3.
источник
Данные решения должны быть изменены , чтобы проверить
source.hasOwnProperty(property)
вfor..in
петлях до назначения - в противном случае, вы в конечном итоге копирование свойств всей цепи прототипов, которая редко желаемому ...источник
Объединить свойства N объектов в одну строку кода
Object.assign
Метод является частью 2015 (ES6) стандарта ECMAScript и делает именно то , что вам нужно. (IE
не поддерживается)Читать далее...
Polyfill для поддержки старых браузеров:
источник
Objects.assign
возвращает объединенный объект, чего нет в других ответах. Это более функциональный стиль программирования.Следующие два, вероятно, являются хорошей отправной точкой. У lodash также есть функция настройки для этих особых нужд!
_.extend
( http://underscorejs.org/#extend )_.merge
( https://lodash.com/docs#merge )источник
Кстати, все, что вы делаете, это перезаписывает свойства, а не объединяет ...
Вот как действительно объединилась область объектов JavaScript: только ключи в
to
объекте, которые сами не являются объектами, будут перезаписаныfrom
. Все остальное будет действительно объединено . Конечно, вы можете изменить это поведение, чтобы не перезаписывать все, что существует, например, еслиto[n] is undefined
, и т. Д ...:Применение:
источник
Вот мой удар, который
Короткий :)
Пример:
источник
{}
в качестве первого параметра или сделать так, чтобы функция изменила исходный объект. Поэтому , если вы изменитеdst = {}
кdst = arguments[0]
ней изменится первый объект , который пройдет в объединенном к объектуtoString.call(src) == '[object Object]'
для проверки, есть ли объект или нет.typeof src
намного лучше. Более того, он превращает массивы в объект (по крайней мере, у меня такое поведение на последнем Chrome).Object.assign ()
ECMAScript 2015 (ES6)
Это новая технология, часть стандарта ECMAScript 2015 (ES6). Спецификация этой технологии была доработана, но проверьте таблицу совместимости для использования и состояния реализации в различных браузерах.
Метод Object.assign () используется для копирования значений всех перечисляемых собственных свойств из одного или нескольких исходных объектов в целевой объект. Он вернет целевой объект.
источник
Для не слишком сложных объектов вы можете использовать JSON :
Помните, что в этом примере "} {" не должно встречаться в строке!
источник
var so1 = JSON.stringify(obj1); var so2 = JSON.stringify(obj1); objMerge = so1.substr(0, so1.length-1)+","+so2.substr(1); console.info(objMerge);
function merge(obj1, obj2) { return JSON.parse((JSON.stringify(obj1) + JSON.stringify(obj2)) .replace(/\}\{/g, ',').replace(/,\}/g, '}').replace(/\{,/g, '{')); }
objMerge = JSON.parse((JSON.stringify(obj1) + JSON.stringify(obj2)).replace(/\}\{/, ", "));
Там есть библиотека называется
deepmerge
на GitHub : Это , кажется, получает некоторую тягу. Это автономная версия, доступная через менеджеры пакетов npm и bower.Я был бы склонен использовать или улучшить это вместо того, чтобы копировать код из ответов.
источник
Лучший способ сделать это - добавить правильное свойство, которое нельзя перечислить, используя Object.defineProperty.
Таким образом, вы по-прежнему сможете перебирать свойства ваших объектов, не имея вновь созданного «расширения», которое вы получите, если бы вы создали свойство с помощью Object.prototype.extend.
Надеюсь, это поможет:
Как только у вас это заработает, вы можете сделать:
Я только что написал пост в блоге об этом здесь: http://onemoredigit.com/post/1527191998/extending-objects-in-node-js
источник
Вы можете просто использовать JQuery
extend
Теперь
obj1
содержит все значенияobj1
иobj2
источник
jQuery.extend( target [, object1 ] [, objectN ] )
Прототип имеет это:
obj1.extend(obj2)
будет делать то, что вы хотите.источник
Object.prototype
а неObject
... Хорошая идея или нет, это то, чтоprototype.js
делает фреймворк, и поэтому, если вы используете его или другой фреймворк, который зависит от него,Object.prototype
он уже будет расширенextend
.Object.prototype
?Object.extend
не будет мешать вашим объектам, он просто присоединяет функцию кObject
объекту. Иobj1.extend(obj2)
это не правильный способ срабатывания функции, используйObject.extend(obj1, obj2)
insted** Объединение объектов простое использование
Object.assign
или...
оператор распространения **Объекты объединяются справа налево, это означает, что объекты, которые имеют идентичные свойства с объектами справа, будут переопределены.
В этом примере
obj2.car
переопределяетobj1.car
источник
Просто если кто-то использует библиотеку Google Closure :
Аналогичная вспомогательная функция существует для массива :
источник
Я расширил метод Дэвида Коллие:
Если override имеет значение false, никакое свойство не будет переопределено, но будут добавлены новые свойства.
Использование: obj.merge (сливается ... [, переопределить]);
Вот мой код:
Примеры и тестовые случаи:
Мой метод равно можно найти здесь: Сравнение объектов в JavaScript
источник
В MooTools есть Object.merge () :
источник
В Ext JS 4 это можно сделать следующим образом:
Смотрите слияние (объект): объект .
источник
Ого ... это первый пост StackOverflow, который я видел на нескольких страницах. Извиняюсь за добавление еще одного "ответа"
Этот метод предназначен для ES5 и более ранних версий - есть много других ответов на ES6.
Я не видел никакого "глубокого" слияния объекта с использованием
arguments
свойства. Вот мой ответ - компактный и рекурсивный , позволяющий передавать неограниченные аргументы объекта:Закомментированная часть является необязательной. Она просто пропускает передаваемые аргументы, которые не являются объектами (предотвращая ошибки).
Пример:
источник
Использование jQuery.extend () - Ссылка
Использование _.merge () - Ссылка
Использование _.extend () - Ссылка
Использование Object.assign () ECMAScript 2015 (ES6) - Ссылка
Выход всего
источник
Основываясь на ответах Markus и vsync , это расширенная версия. Функция принимает любое количество аргументов. Он может использоваться для установки свойств на узлах DOM и делает глубокие копии значений. Тем не менее, первый аргумент дается ссылкой.
Чтобы обнаружить узел DOM, используется функция isDOMNode () (см. Вопрос переполнения стека JavaScript isDOM - Как проверить, является ли объект JavaScript объектом DOM? )
Он был протестирован в Opera 11, Firefox 6, Internet Explorer 8 и Google Chrome 16.
Код
Некоторые примеры
Установить innerHTML и стиль элемента HTML
Слияние массивов и объектов. Обратите внимание, что undefined может использоваться для сохранения значений в левом массиве / объекте.
Любой аргумент, не являющийся объектом JavaScript (включая ноль), будет игнорироваться. За исключением первого аргумента, также DOM-узлы отбрасываются. Помните, что строки, созданные как new String (), на самом деле являются объектами.
Если вы хотите объединить два объекта в новый (не затрагивая ни один из двух), укажите {} в качестве первого аргумента
Изменить (от ReaperSoon):
Также объединить массивы
источник
источник
Вы должны использовать lodash по умолчаниюDeep
источник
С Underscore.js , чтобы объединить массив объектов, сделайте:
Это приводит к:
источник