Comme @Bergi dit, concat
et les marges sont très différentes si l'argument n'est pas un tableau.
Si l'argument n'est pas un tableau, concat
ajoute comme un tout, ...
tente de le parcourir et échoue si elle ne peut pas. Considérer:
a = [1, 2, 3]
x = 'hello';
console.log(a.concat(x)); // [ 1, 2, 3, 'hello' ]
console.log([...a, ...x]); // [ 1, 2, 3, 'h', 'e', 'l', 'l', 'o' ]
Ici, concat
traite la chaîne de façon atomique, alors que ...
utilise sa valeur par défaut itérateur, char par char.
Un autre exemple:
x = 99;
console.log(a.concat(x)); // [1, 2, 3, 99]
console.log([...a, ...x]); // TypeError: x is not iterable
Encore une fois, pour concat
le nombre est un atome, ...
tente de le parcourir et d'échec.
Enfin:
function* gen() { yield *'abc' }
console.log(a.concat(gen())); // [ 1, 2, 3, Object [Generator] {} ]
console.log([...a, ...gen()]); // [ 1, 2, 3, 'a', 'b', 'c' ]
concat
ne fait aucune tentative pour itérer le générateur et l'ajoute comme un tout, ...
bien récupère toutes les valeurs.
Pour résumer, lorsque vos arguments sont peut-être non-ensembles, le choix entre concat
et ...
dépend si vous voulez être répétées.
Le ci-dessus décrit le comportement par défaut de concat
, cependant, ES6 fournit un moyen de le remplacer avec de l' Symbol.isConcatSpreadable
. Par défaut, ce symbole est - true
pour les tableaux, et false
pour tout le reste. Le paramètre true
dit concat
pour itérer l'argument, tout comme ...
n'est:
str = 'hello'
console.log([1,2,3].concat(str)) // [1,2,3, 'hello']
str = new String('hello');
str[Symbol.isConcatSpreadable] = true;
console.log([1,2,3].concat(str)) // [ 1, 2, 3, 'h', 'e', 'l', 'l', 'o' ]
Performance sage- concat
est plus rapide, probablement parce qu'il peut bénéficier de la matrice optimisations spécifiques, tandis que d' ...
doit être conforme à la commune itération protocole. Horaires:
let big = (new Array(1e5)).fill(99);
let i, x;
console.time('concat-big');
for(i = 0; i < 1e2; i++) x = [].concat(big)
console.timeEnd('concat-big');
console.time('spread-big');
for(i = 0; i < 1e2; i++) x = [...big]
console.timeEnd('spread-big');
let a = (new Array(1e3)).fill(99);
let b = (new Array(1e3)).fill(99);
let c = (new Array(1e3)).fill(99);
let d = (new Array(1e3)).fill(99);
console.time('concat-many');
for(i = 0; i < 1e2; i++) x = [1,2,3].concat(a, b, c, d)
console.timeEnd('concat-many');
console.time('spread-many');
for(i = 0; i < 1e2; i++) x = [1,2,3, ...a, ...b, ...c, ...d]
console.timeEnd('spread-many');