Sintaxe de Espalhamento
Experimente
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 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"}
Espalhamento em arrays literais
Um array literal mais poderoso
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.
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 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 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 |
---|
ECMAScript Language Specification # prod-SpreadElement |
ECMAScript Language Specification # prod-ArgumentList |
ECMAScript Language Specification # prod-PropertyDefinition |
Compatibilidade com navegadores
BCD tables only load in the browser
Veja também
- Parâmetros Rest (also '
...
')