Digamos que eu tenho um options
variável e quero definir algum valor padrão.
Qual é a vantagem / desvantagem dessas duas alternativas?
Usando propagação de objeto
options = {...optionsDefault, ...options};
Ou usando Object.assign
options = Object.assign({}, optionsDefault, options);
Esse é o commit que me fez pensar.
javascript
ecmascript-6
Olivier Tassinari
fonte
fonte
Respostas:
Isso não é necessariamente exaustivo.
Sintaxe de propagação
Vantagens:
Se estiver criando código para execução em ambientes sem suporte nativo, você poderá compilar essa sintaxe (em vez de usar um polyfill). (Com Babel, por exemplo.)
Menos detalhado.
Desvantagens:
Quando esta resposta foi originalmente escrita, era uma proposta , não padronizada. Ao usar propostas, considere o que você faria se escrever um código com ele agora e ele não for padronizado ou alterado à medida que avança para a padronização. Desde então, isso foi padronizado no ES2018.
Literal, não dinâmico.
Object.assign()
Vantagens:
Padronizado.
Dinâmico. Exemplo:
Desvantagens:
Isso não está diretamente relacionado ao que você está perguntando. Esse código não estava usando
Object.assign()
, estava usando o código do usuário (object-assign
) que faz a mesma coisa. Eles parecem estar compilando esse código com o Babel (e empacotando-o no Webpack), que era o que eu estava falando: a sintaxe que você pode compilar. Aparentemente, eles preferiram ter que incluirobject-assign
como uma dependência que entraria em sua construção.fonte
Object.assign()
. Ou você poderia manualmente iterar sobre uma matriz de objetos e seus próprios adereços atribuindo-los manualmente para um alvo e torná-lo ainda mais detalhado: PPara o objeto de referência, o descanso / propagação é finalizado no ECMAScript 2018 como um estágio 4. A proposta pode ser encontrada aqui .
Na maioria das vezes, a redefinição e a propagação de objetos funcionam da mesma maneira, a principal diferença é que a propagação define propriedades, enquanto Object.assign () as define . Isso significa que Object.assign () aciona setters.
Vale lembrar que, além disso, o objeto rest / spread 1: 1 mapeia para Object.assign () e age de maneira diferente para o spread (iterável) da matriz. Por exemplo, ao espalhar uma matriz, valores nulos são espalhados. No entanto, ao usar objetos espalhados, os valores nulos são silenciosamente espalhados para nada.
Exemplo de propagação de matriz (iterável)
Exemplo de propagação de objeto
Isso é consistente com o funcionamento de Object.assign (), ambos excluem silenciosamente o valor nulo sem erro.
fonte
Object.assign
usar setters.Object.assign({set a(v){this.b=v}, b:2}, {a:4}); // {b: 4}
vs{...{set a(v){this.b=v}, b:2}, ...{a:4}}; // {a: 4, b: 2}
const x = {c: null};
. Nesse caso, AFAIK, veríamos comportamento assim como a matriz://{a: 1, b: 2, c: null}
.Eu acho que uma grande diferença entre o operador de propagação e
Object.assign
isso não parece ser mencionado nas respostas atuais é que o operador de propagação não copiará o protótipo do objeto de origem no objeto de destino. Se você deseja adicionar propriedades a um objeto e não deseja alterar de qual instância ele é, será necessário usá-loObject.assign
. O exemplo abaixo deve demonstrar isso:fonte
errorExtendedUsingAssign === error
maserrorExtendedUsingSpread
é um novo objeto (e o protótipo não foi copiado).let target = Object.create(source); Object.assign(target, source);
Como outros já mencionaram, neste momento da escrita, é
Object.assign()
necessário um polyfill e a propagação do objeto...
exige algumas transpilações (e talvez um polyfill também) para funcionar.Considere este código:
Ambos produzem a mesma saída.
Aqui está a saída de Babel, para ES5:
Este é o meu entendimento até agora.
Object.assign()
é realmente padronizado, onde, como a propagação do objeto...
ainda não é. O único problema é o suporte do navegador para o primeiro e, no futuro, para o último também.Jogue com o código aqui
Espero que isto ajude.
fonte
{}
deve corrigir a inconsistência.O operador de propagação de objetos (...) não funciona nos navegadores, porque ainda não faz parte de nenhuma especificação de ES, apenas uma proposta. A única opção é compilá-lo com Babel (ou algo semelhante).
Como você pode ver, é apenas açúcar sintático sobre Object.assign ({}).
Tanto quanto eu posso ver, essas são as diferenças importantes.
...
para objetos não é padronizado...
protege você de alterar acidentalmente o objeto...
polyfill Object.assign em navegadores sem ele...
precisa de menos código para expressar a mesma ideiafonte
Object.assign
, pois o operador de propagação sempre fornecerá um novo objeto.Eu gostaria de resumir o status do recurso ES de "propagação de mesclagem de objetos", em navegadores e no ecossistema por meio de ferramentas.
Spec
Navegadores: no Chrome, no SF, no Firefox em breve (versão 60, IIUC)
Ferramentas: Nó 8.7, TS 2.1
Ligações
Amostra de código (funciona como teste de compatibilidade)
Novamente: no momento da redação deste exemplo, funciona sem transpilação no Chrome (60+), Firefox Developer Edition (visualização do Firefox 60) e Node (8.7+).
Por que responder?
Estou escrevendo isso 2,5 anos após a pergunta original. Mas eu tinha a mesma pergunta, e foi aqui que o Google me enviou. Sou escravo da missão da SO de melhorar a cauda longa.
Como essa é uma expansão da sintaxe "array spread", achei muito difícil para o google e difícil de encontrar em tabelas de compatibilidade. O mais próximo que eu pude encontrar é Kangax "propriedade espalhada" , mas esse teste não tem dois spreads na mesma expressão (não é uma mesclagem). Além disso, o nome nas páginas de propostas / rascunhos / status do navegador usa "propriedade espalhada", mas me parece que esse foi o "primeiro principal" ao qual a comunidade chegou depois das propostas para usar a sintaxe de propagação para "mesclagem de objetos". (O que pode explicar por que é tão difícil pesquisar no Google.) Portanto, documento minha descoberta aqui para que outras pessoas possam visualizar, atualizar e compilar links sobre esse recurso específico. Espero que capte. Ajude a espalhar as notícias sobre o desembarque nas especificações e nos navegadores.
Por fim, eu adicionaria essas informações como um comentário, mas não poderia editá-las sem quebrar a intenção original dos autores. Especificamente, não posso editar o comentário de @ ChillyPenguin sem que ele perca a intenção de corrigir @RichardSchulte. Mas anos depois, Richard se mostrou certo (na minha opinião). Então, em vez disso, escrevo esta resposta, esperando que, eventualmente, ganhe força nas respostas antigas (pode levar anos, mas afinal é isso o efeito da cauda longa ).
fonte
NOTA: A propagação NÃO é apenas açúcar sintático em torno do Object.assign. Eles operam de maneira muito diferente nos bastidores.
Object.assign aplica setters a um novo objeto, o Spread não. Além disso, o objeto deve ser iterável.
Copiar Use isso se você precisar do valor do objeto como está neste momento e não desejar que esse valor reflita as alterações feitas por outros proprietários do objeto.
Use-o para criar uma cópia superficial das boas práticas do objeto para sempre definir propriedades imutáveis para copiar - como versões mutáveis podem ser passadas para propriedades imutáveis, a cópia garantirá que você sempre lide com um objeto imutável
Atribuir Atribuir é um pouco o oposto de copiar. Atribuir irá gerar um setter que atribui o valor diretamente à variável de instância, em vez de copiá-lo ou retê-lo. Ao chamar o getter de uma propriedade de atribuição, ele retorna uma referência aos dados reais.
fonte
Outras respostas são antigas, não foi possível obter uma boa resposta.
O exemplo abaixo é para literais de objetos, ajuda como ambos podem se complementar e como eles não podem se complementar (portanto, diferença):
Vários outros exemplos pequenos aqui, também para array e objeto:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
fonte
Agora isso faz parte do ES6, portanto é padronizado e também está documentado no MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator
É muito conveniente de usar e faz muito sentido, além da destruição de objetos.
A única vantagem restante listada acima são os recursos dinâmicos de Object.assign (), no entanto, isso é tão fácil quanto espalhar a matriz dentro de um objeto literal. Na saída babel compilada, ele usa exatamente o que é demonstrado com Object.assign ()
Portanto, a resposta correta seria usar a propagação de objetos, uma vez que agora é padronizada, amplamente utilizada (consulte react, redux, etc), é fácil de usar e possui todos os recursos de Object.assign ()
fonte
Eu gostaria de adicionar este exemplo simples quando você precisar usar o Object.assign.
Não pode ficar claro quando você usa JavaScript. Mas com o TypeScript é mais fácil se você deseja criar uma instância de alguma classe
fonte