Допустим, у меня есть options
переменная, и я хочу установить значение по умолчанию.
Какова польза / недостаток этих двух альтернатив?
Использование объекта распространения
options = {...optionsDefault, ...options};
Или используя Object.assign
options = Object.assign({}, optionsDefault, options);
Это обязательство , что заставило меня задуматься.
javascript
ecmascript-6
Оливье Тассинари
источник
источник
Ответы:
Это не обязательно исчерпывающе.
Синтаксис распространения
Преимущества:
Если вы создаете код для выполнения в средах без встроенной поддержки, вы можете просто скомпилировать этот синтаксис (в отличие от использования полифилла). (С Вавилоном, например.)
Менее многословно.
Недостатки:
Когда этот ответ был изначально написан, это было предложение , не стандартизированное. При использовании предложений учитывайте, что вы будете делать, если вы сейчас пишете код с ним, и он не стандартизируется и не изменяется по мере продвижения к стандартизации. С тех пор это было стандартизировано в ES2018.
Буквально, не динамично.
Object.assign()
Преимущества:
Стандартизован.
Динамический. Пример:
Недостатки:
Это не имеет прямого отношения к тому, что вы спрашиваете. Этот код не использовался
Object.assign()
, он использовал код пользователя (object-assign
), который делает то же самое. Похоже, они компилируют этот код с Babel (и связывают его с Webpack), о чем я говорил: синтаксис, который вы можете просто скомпилировать. По-видимому, они предпочли это включениеobject-assign
в качестве зависимости, которая войдет в их сборку.источник
Object.assign()
. Или вы можете вручную перебирать массив объектов и их собственные реквизиты, вручную назначая их цели иДля эталонного объекта отдых / разворот завершается в ECMAScript 2018 как этап 4. Предложение можно найти здесь .
В большинстве случаев сброс и распространение объектов работают одинаково, ключевое отличие состоит в том, что распространение определяет свойства, а Object.assign () устанавливает их . Это означает, что Object.assign () запускает сеттеры.
Стоит помнить, что, кроме этого, объект rest / spread 1: 1 отображается на Object.assign () и действует иначе, чем массив (повторяемый). Например, при расширении массива распространяются нулевые значения. Однако, используя нулевые значения, распространяемые по объектам, они просто ничего не значат.
Пример массива (Iterable) Spread
Пример распространения объекта
Это согласуется с тем, как будет работать Object.assign (), и оба молча исключают нулевое значение без ошибок.
источник
Object.assign
использовании сеттеров.Object.assign({set a(v){this.b=v}, b:2}, {a:4}); // {b: 4}
против{...{set a(v){this.b=v}, b:2}, ...{a:4}}; // {a: 4, b: 2}
const x = {c: null};
. В этом случае, AFAIK, мы хотели бы видеть поведение так же , как массив://{a: 1, b: 2, c: null}
.Я думаю, что одно большое различие между оператором распространения и тем,
Object.assign
что, кажется, не упоминается в текущих ответах, заключается в том, что оператор распространения не будет копировать прототип исходного объекта в целевой объект. Если вы хотите добавить свойства к объекту и не хотите изменять его экземпляр, вам придется использовать егоObject.assign
. Пример ниже должен продемонстрировать это:источник
errorExtendedUsingAssign === error
ноerrorExtendedUsingSpread
это новый объект (и прототип не был скопирован).let target = Object.create(source); Object.assign(target, source);
Как уже упоминали другие, в этот момент написания
Object.assign()
требуется полифилл, а распространение объекта...
требует некоторой транспиляции (и, возможно, также полифилла) для работы.Рассмотрим этот код:
Оба они дают одинаковый результат.
Вот вывод из Бабеля в ES5:
Это мое понимание до сих пор.
Object.assign()
на самом деле стандартизирован, где, поскольку распространение объекта...
еще не. Единственная проблема - поддержка браузера для первого и в будущем, второго тоже.Играть с кодом здесь
Надеюсь это поможет.
источник
{}
должно исправить несоответствие.Оператор распространения объекта (...) не работает в браузерах, потому что он пока не является частью какой-либо спецификации ES, а является лишь предложением. Единственный вариант - это скомпилировать его с помощью Babel (или чего-то подобного).
Как видите, это просто синтаксический сахар над Object.assign ({}).
Насколько я вижу, это важные различия.
...
для объектов не нормируется...
защищает вас от случайного изменения объекта...
будет заполнять Object.assign в браузерах без него...
нужно меньше кода, чтобы выразить ту же идеюисточник
Object.assign
, так как оператор распространения всегда даст вам новый объект.Я хотел бы обобщить состояние функции ES "слияние распространенных объектов" в браузерах и в экосистеме с помощью инструментов.
спекуляция
Браузеры: в Chrome, в SF, Firefox скоро (версия 60, IIUC)
Инструменты: Узел 8.7, TS 2.1
связи
Пример кода (удваивается как тест на совместимость)
Опять же: на момент написания этого примера этот пример работал без перехода в Chrome (60+), Firefox Developer Edition (предварительный просмотр Firefox 60) и Node (8.7+).
Зачем отвечать?
Я пишу это через 2,5 года после первоначального вопроса. Но у меня был тот же самый вопрос, и это то, куда Google послал меня. Я раб миссии SO по улучшению длинного хвоста.
Поскольку это расширение синтаксиса «разброса по массивам», мне было очень трудно его найти в Google, и его трудно найти в таблицах совместимости. Самое близкое, что я могу найти - это Kangax «свойство-разброс» , но в этом тесте нет двух спредов в одном выражении (не слияние). Кроме того, имя на страницах с предложениями / чертежами / статусом браузера использует "распространение свойства", но мне кажется, что это был "первый принцип", к которому пришло сообщество после предложений использовать синтаксис распространения для "слияния объектов". (Это может объяснить, почему Google так сложно.) Так что я документирую свои находки здесь, чтобы другие могли просматривать, обновлять и компилировать ссылки об этой конкретной функции. Я надеюсь, что это завоевывает популярность. Пожалуйста, помогите распространять новости о его посадке в спецификации и в браузерах.
Наконец, я бы добавил эту информацию в качестве комментария, но я не мог редактировать их, не нарушив первоначальные намерения авторов. В частности, я не могу редактировать комментарий @ ChillyPenguin без потери намерения исправить @RichardSchulte. Но спустя годы Ричард оказался прав (на мой взгляд). Поэтому я пишу этот ответ вместо этого, надеясь, что в конечном итоге он получит поддержку старых ответов (это может занять годы, но в конце концов это и есть эффект длинного хвоста ).
источник
ПРИМЕЧАНИЕ: распространение не просто синтаксический сахар вокруг Object.assign. Они работают совсем по-другому за кулисами.
Object.assign применяет сеттеры к новому объекту, а Spread - нет. Кроме того, объект должен быть итеративным.
Копировать Используйте это, если вам нужно, чтобы значение объекта было таким, как оно есть в данный момент, и вы не хотите, чтобы это значение отражало какие-либо изменения, сделанные другими владельцами объекта.
Используйте его для создания мелкой копии объекта. Рекомендуется всегда задавать неизменяемые свойства для копирования - поскольку изменяемые версии можно передавать в неизменяемые свойства, функция копирования гарантирует, что вы всегда будете иметь дело с неизменным объектом.
Назначить Назначить несколько противоположно копировать. Assign сгенерирует установщик, который присваивает значение переменной экземпляра напрямую, а не копирует или сохраняет его. При вызове метода получения назначенного свойства он возвращает ссылку на фактические данные.
источник
Другие ответы старые, не может получить хороший ответ.
Ниже приведен пример для литералов объекта, который помогает понять, как они могут дополнять друг друга, и как они не могут дополнять друг друга (следовательно, разница):
Еще несколько небольших примеров, в том числе для массива и объекта:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
источник
Теперь это часть ES6, поэтому оно стандартизировано и задокументировано в MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator
Это очень удобно для использования и имеет большой смысл наряду с деструктуризацией объектов.
Единственным оставшимся преимуществом, перечисленным выше, являются динамические возможности Object.assign (), однако это так же просто, как распространение массива внутри литерального объекта. В скомпилированном выводе babel он использует именно то, что продемонстрировано с Object.assign ()
Таким образом, правильным ответом будет использование разброса объектов, поскольку теперь он стандартизирован, широко используется (см. «Реакция», «Редукс» и т. Д.), Прост в использовании и обладает всеми функциями Object.assign ().
источник
Я хотел бы добавить этот простой пример, когда вам нужно использовать Object.assign.
Это может быть непонятно, когда вы используете JavaScript. Но с TypeScript это проще, если вы хотите создать экземпляр некоторого класса
источник