--- 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")}}
...’)