--- title: Sintaxe de Espalhamento slug: Web/JavaScript/Reference/Operators/Spread_syntax tags: - ECMAScript 2015 - Iterator - JavaScript translation_of: Web/JavaScript/Reference/Operators/Spread_syntax ---
O código-fonte para este exemplo interativo está armazenado em um repositorio do GitHub. Se você gostaria de contribuir para os exemplos interativos para este projeto, por favor clone https://github.com/mdn/interactive-examples e nos envie um pull request.
Para chamada de funções:
myFunction(...iterableObj);
Para arrays literais ou strings:
[...iterableObj, '4', 'five', 6];
Para objetos literais (novo em ECMAScript 2018; stage 3 draft):
let objClone = { ...obj };
É comum usar {{jsxref( "Function.prototype.apply")}} em casos onde você quer usar os elementos de um array como argumentos para uma função.
function myFunction(x, y, z) { } var args = [0, 1, 2]; myFunction.apply(null, args);
Com a sintaxe de espalhamento, o código acima pode ser escrito assim:
function myFunction(x, y, z) { } var args = [0, 1, 2]; myFunction(...args);
Qualquer argumento numa lista de argumentos pode usar a sintaxe de espalhamento e pode ser usado mais de uma vez.
function myFunction(v, w, x, y, z) { } var args = [0, 1]; myFunction(-1, ...args, 2, ...[3]);
Quando um construtor é chamado com new
, não é possivel usar diretamente um array e apply
(apply
executa o [[Call]]
e não o [[Construct]]
). No entanto, um array pode facilmente ser usado com new
graças ao operador de espalhamento:
var dateFields = [1970, 0, 1]; // 1 Jan 1970 var d = new Date(...dateFields);
Para usar o new
com array de parâmetros sem a sintaxa de espalhamento, você teria que fazer isso indiretamente por meio da aplicação parcial:
function applyAndNew(constructor, args) { function partial () { return constructor.apply(this, args); }; if (typeof constructor.prototype === "object") { partial.prototype = Object.create(constructor.prototype); } return partial; } function myConstructor () { console.log("arguments.length: " + arguments.length); console.log(arguments); this.prop1="val1"; this.prop2="val2"; }; var myArguments = ["hi", "how", "are", "you", "mr", null]; var myConstructorWithArguments = applyAndNew(myConstructor, myArguments); console.log(new myConstructorWithArguments); // (internal log of myConstructor): arguments.length: 6 // (internal log of myConstructor): ["hi", "how", "are", "you", "mr", null] // (log of "new myConstructorWithArguments"): {prop1: "val1", prop2: "val2"}
Criar um novo array usando um array existente como parte dele, não é possível utilizando apenas a sintaxe de array literal. O código imperativo deve ser usado ao invés da combinação de push
, splice
, concat
, etc. Com a sintaxe de espalhamento isso se torna muito mais sucinto:
var parts = ['shoulders', 'knees']; var lyrics = ['head', ...parts, 'and', 'toes']; // ["head", "shoulders", "knees", "and", "toes"]
Assim como espalhar a lista de argumentos, ...
pode ser usado em qualquer lugar em um array literal e pode ser usado multiplas vezes.
var arr = [1, 2, 3]; var arr2 = [...arr]; // like arr.slice() arr2.push(4); // arr2 becomes [1, 2, 3, 4] // arr remains unaffected
Nota: A sintaxe de espalhamento efetivamente vai um nível mais profundo quando se copia um array. Assim sendo, pode ser inadequado para copiar arrays multidimensionais como o exemplo a seguir mostra (é o mesmo com {{jsxref("Object.assign()")}} e a sintaxe de espalhamento).
var a = [[1], [2], [3]]; var b = [...a]; b.shift().shift(); // 1 // Now array a is affected as well: [[], [2], [3]]
{{jsxref("Array.concat")}} é frequentemente usado para concatenar um array no final de um array existente. Sem a sintaxe de espalhamento é feito assim:
var arr1 = [0, 1, 2]; var arr2 = [3, 4, 5]; // Append all items from arr2 onto arr1 arr1 = arr1.concat(arr2);
Com a sintaxe de espalhamento se torna isso:
var arr1 = [0, 1, 2]; var arr2 = [3, 4, 5]; arr1 = [...arr1, ...arr2];
{{jsxref("Array.unshift")}} é frequentemente usado para inserir um array de valores no inicio de um array existente. Sem a sintaxe de espalhamento é feito assim:
var arr1 = [0, 1, 2]; var arr2 = [3, 4, 5]; // Prepend all items from arr2 onto arr1 Array.prototype.unshift.apply(arr1, arr2) // arr1 is now [3, 4, 5, 0, 1, 2]
Com a sintaxe de espalhamento isso se torna [Note, no entanto, que isso cria um novo arr1
array. Ao contrário de {{jsxref("Array.unshift")}}, isso não modifica o array original arr1
array]:
var arr1 = [0, 1, 2]; var arr2 = [3, 4, 5]; arr1 = [...arr2, ...arr1]; // arr1 is now [3, 4, 5, 0, 1, 2]
A proposta Rest/Spread Properties for ECMAScript (stage 3) adiciona espalhamento de propriedades para objetos literais. Este copia as propriedades enumeráveis de um objeto informado em um novo objeto.
Cópia-rasa (Shallow-cloning) (excluindo o protótipo) ou fusão (merge) de objetos agora é possivel usando uma sintaxe mais curta que {{jsxref("Object.assign()")}}.
var obj1 = { foo: 'bar', x: 42 }; var obj2 = { foo: 'baz', y: 13 }; var clonedObj = { ...obj1 }; // Object { foo: "bar", x: 42 } var mergedObj = { ...obj1, ...obj2 }; // Object { foo: "baz", x: 42, y: 13 }
Note que {{jsxref("Object.assign()")}} chamada os setters e a sintaxe de espalhamento não.
A sintaxe de espalhamento (diferente de propriedades espalhadas) só pode ser utilizada com objetos iteráveis.
var obj = {'key1': 'value1'}; var array = [...obj]; // TypeError: obj is not iterable
Quando usar a sintaxe de espalhamento para chamada de funções, esteja ciente da possibilidade de exceder tamanho máximo de argumentos do motor do Javascript. Veja apply()
para mais detalhes.
A sintaxe rest se parece exatamente como a sintaxe de espalhamento, mas esta é usada para desestruturar arrays e objetos. De certa forma, a sintaxe rest é o oposto da sintaxe de espalhamento: A sintaxe de espalhamento (spread) 'expande' um array em vários elementos, enquanto a sintaxe rest coleta multiplos elementos e 'condensa' eles em um único elemento. Veja parâmetros rest.
Specification | Status | Comment |
---|---|---|
{{SpecName('ES2015', '#sec-array-initializer')}} | {{Spec2('ES2015')}} | Defined in several sections of the specification: Array Initializer, Argument Lists |
{{SpecName('ESDraft', '#sec-array-initializer')}} | {{Spec2('ESDraft')}} | No changes. |
Rest/Spread Properties for ECMAScript | Draft | Stage 3 draft. |
{{Compat("javascript.operators.spread")}}
...
’)