Tradução em progresso.
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.
Sintaxe
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 };
Exemplos
Espalhamento e chamadas de funções
Substituindo apply
É comum usar 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]);
Apply para new
Quando um construtor é chamado com new
, não é possivel usar um array diretamente 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"}
Espalhamento em arrays literais
Um array literal mais poderoso
Sem a sintaxe de espalhamento, criar um novo array usando um array existente como parte dele, a sintaxe de array literal não é mais suficiente e 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.
Copiando um array
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 level 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 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]]
Uma maneira melhor de concatenar arrays
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];
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 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]
Espalhamento em objetos literais
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 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 Object.assign()
chamada os setters e a sintaxe de espalhamento não.
Apenas para iteráveis
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
Espalhamento com muitos valores
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.
Sintaxe Rest (parâmetros)
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.
Especificações
Specification | Status | Comment |
---|---|---|
ECMAScript 2015 (6th Edition, ECMA-262) | Padrão | Defined in several sections of the specification: Array Initializer, Argument Lists |
ECMAScript Latest Draft (ECMA-262) | Rascunho | No changes. |
Rest/Spread Properties for ECMAScript | Draft | Stage 3 draft. |
Compatibilidade com Navegadores
Desktop | Mobile | Server | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Spread in array literals | Chrome Full support 46 | Edge Full support 12 | Firefox Full support 16 | IE No support No | Opera Full support 37 | Safari Full support 8 | WebView Android Full support 46 | Chrome Android Full support 46 | Edge Mobile Full support 12 | Firefox Android Full support 16 | Opera Android Full support 37 | Safari iOS Full support 8 | Samsung Internet Android Full support 5.0 | nodejs
Full support
5.0.0
|
Spread in function calls | Chrome Full support 46 | Edge Full support 12 | Firefox Full support 27 | IE No support No | Opera Full support 37 | Safari Full support 8 | WebView Android Full support 46 | Chrome Android Full support 46 | Edge Mobile Full support 12 | Firefox Android Full support 27 | Opera Android Full support 37 | Safari iOS Full support 8 | Samsung Internet Android Full support 5.0 | nodejs
Full support
5.0.0
|
Spread in destructuring | Chrome Full support 49 | Edge No support No | Firefox Full support 34 | IE No support No | Opera Full support 37 | Safari ? | WebView Android Full support 49 | Chrome Android Full support 49 | Edge Mobile No support No | Firefox Android Full support 34 | Opera Android Full support 37 | Safari iOS ? | Samsung Internet Android Full support 5.0 | nodejs Full support Yes |
Spread in object literals | Chrome Full support 60 | Edge No support No | Firefox Full support 55 | IE No support No | Opera Full support 47 | Safari Full support 11.1 | WebView Android Full support 60 | Chrome Android Full support 60 | Edge Mobile No support No | Firefox Android Full support 55 | Opera Android ? | Safari iOS Full support 11.1 | Samsung Internet Android Full support 8.2 | nodejs
Full support
8.3.0
|
Legend
- Full support
- Full support
- No support
- No support
- Compatibility unknown
- Compatibility unknown
- Experimental. Expect behavior to change in the future.
- Experimental. Expect behavior to change in the future.
- User must explicitly enable this feature.
- User must explicitly enable this feature.
Veja também
- Parâmetros Rest (also ‘
...
’)