react - spread operator javascript
Diferencia entre el uso de una sintaxis de propagaciĆ³n(...) y push.apply, cuando se trata de matrices (5)
Tengo dos matrices,
const pets = ["dog", "cat", "hamster"]
const wishlist = ["bird", "snake"]
Quiero añadir una wishlist
de wishlist
a las pets
, lo cual se puede hacer usando dos métodos,
Método 1:
pets.push.apply(pets,wishlist)
Lo que resulta en: [ ''dog'', ''cat'', ''hamster'', ''bird'', ''snake'' ]
Método 2:
pets.push(...wishlist)
Lo que también resulta en: [ ''dog'', ''cat'', ''hamster'', ''bird'', ''snake'' ]
¿Hay una diferencia entre estos dos métodos en términos de rendimiento cuando trato con datos más grandes?
Al interpretar la pregunta como la which is more performant in general, using .push() as an example
que parece que se aplica es [solo un poco] más rápido (a excepción de MS Edge, ver más abajo).
Aquí hay una prueba de rendimiento en la sobrecarga de llamar una función dinámicamente para los dos métodos.
function test() { console.log(arguments[arguments.length - 1]); }
var using = (new Array(200)).fill(null).map((e, i) => (i));
test(...using);
test.apply(null, using)
Chrome 71.0.3578.80 (Official Build) (64-bit)
en Chrome 71.0.3578.80 (Official Build) (64-bit)
, FF 63.0.3 (64-bit)
y Edge 42.17134.1.0
, y estos fueron mis resultados después de ejecutarlos algunas veces por su cuenta Los resultados iniciales Siempre fueron sesgados de una manera u otra
Como puede ver, Edge parece tener una mejor implementación para apply
que para ...
(pero no intente comparar los resultados entre los navegadores, no podemos decir si Edge tiene una mejor apply
que los demás, peor ...
, o un poco de ambos a partir de estos datos).
Teniendo en cuenta esto, a menos que esté apuntando específicamente a Edge, diría que vaya con ...
tal como se lee más limpio, especialmente si necesita volver a pasar un objeto para apply
this
.
Es posible que también dependa del tamaño de la matriz, por lo que, como dijo @Jaromanda X
, haga sus propias pruebas y cambie 200
si realmente necesita estar seguro.
Las otras respuestas interpretaron la pregunta como la which would be better for .push() specifically
, y quedar atrapados en el "problema" que se está resolviendo, simplemente recomendando just use .concat()
, que es básicamente la norma, why are you doing it that way?
lo que puede irritar a algunas personas que vienen de google y no están buscando soluciones para hacer con .push()
(por ejemplo, Math.max
, o su propia función personalizada).
Aparte de lo que señaló ftor , Array.prototype.concat
es, en promedio, al menos 1.4 veces más rápido que el operador de dispersión de matriz.
Vea los resultados aquí: https://jsperf.com/es6-add-element-to-create-new-array-concat-vs-spread-op
Puede ejecutar la prueba en su propio navegador y máquina aquí: https://www.measurethat.net/Benchmarks/Show/579/1/arrayprototypeconcat-vs-spread-operator
Para agregar a una gran variedad, el operador de propagación es mucho más rápido . No sé cómo @ftor
/ @Liau Jian Jie
sacó sus conclusiones, posiblemente malas pruebas.
Chrome 71.0.3578.80 (Official Build) (64-bit)
, FF 63.0.3 (64-bit)
y Edge 42.17134.1.0
Tiene sentido ya que concat()
hace una copia de la matriz y ni siquiera intenta usar la misma memoria.
La cosa sobre las "mutaciones" no parece estar basada en nada; Si está sobrescribiendo su antigua matriz, concat()
no tiene beneficios.
La única razón para no usar ...
sería el desbordamiento de pila, estoy de acuerdo con las otras respuestas que no puede usar ...
o apply
.
Pero incluso entonces el uso de for {push()}
es más o menos el doble de rápido que concat()
en todos los navegadores y no se desborda .
No hay razón para usar concat()
menos que necesite mantener la matriz antigua.
Si está utilizando ES2015, el operador de propagación es el camino a seguir. Al usar el operador de propagación, su código se ve menos detallado y mucho más limpio en comparación con otro enfoque. Cuando se trata de velocidad, creo que habrá poco para elegir entre los dos enfoques.
Tanto Function.prototype.apply
como la sintaxis de propagación pueden causar un desbordamiento de pila cuando se aplican a matrices grandes:
let xs = new Array(500000),
ys = [], zs;
xs.fill("foo");
try {
ys.push.apply(ys, xs);
} catch (e) {
console.log("apply:", e.message)
}
try {
ys.push(...xs);
} catch (e) {
console.log("spread:", e.message)
}
zs = ys.concat(xs);
console.log("concat:", zs.length)
Utilice Array.prototype.concat
lugar. Además de evitar desbordamientos de pila, concat
tiene la ventaja de que también evita mutaciones. Las mutaciones se consideran dañinas porque pueden provocar efectos secundarios sutiles.
Pero eso no es un dogma. Si tiene un ámbito de función y realiza mutaciones para mejorar el rendimiento y aliviar la recolección de basura, puede realizar mutaciones, siempre que no estén visibles en el ámbito principal.