Imagine que tiene un método, cuyo propósito es modificar una matriz de objetos y devolver la nueva versión del mismo.
const likePosts = (posts) => posts.map((post) => { post.isLiked = true return post; }); const originalPosts = [{ isLiked: false }, { isLiked: false }]; const newLikedPosts = likePosts(originalPosts); console.log(newLikedPosts);Pero, como los valores no primitivos de JS son mutables, si después de ejecutar el código, registramos las publicaciones originales, veremos cómo el campo isLiked no es falso, ¡también se ha modificado a verdadero!
const likePosts = (posts) => posts.map((post) => { post.isLiked = true return post; }); const originalPosts = [{ isLiked: false }, { isLiked: false }]; const newLikedPosts = likePosts(originalPosts); console.log({ newLikedPosts }); console.log({ originalPosts });¿Deberíamos preocuparnos por esto? Es decir, por ejemplo, en este escenario, no importa si se actualiza "originalPosts", ya que son datos inútiles para el código después de ejecutar "likePosts".
Si nos preocupamos por la mutación de datos cuando no es necesaria, podríamos estar haciendo una clonación adicional y, en consecuencia, afectando negativamente el rendimiento, ¿verdad?
En otras palabras, cuando codifica JS, ¿está constantemente clonando datos para evitar mutaciones donde no es realmente necesario?
Sí, es algo que vale la pena pensar y preocuparse. En los scripts, al menos en mi experiencia y por lo que he visto en Stack Overflow, muchos errores son causados por un valor mutable que cambia cuando el guionista no lo esperaba.
Con tu código:
const likePosts = (posts) => posts.map((post) => { Si alguien más que mantiene este script (o usted, unos meses más adelante) ve esta función, sería completamente razonable que asumiera que crea una nueva matriz, en lugar de modificar los objetos en la existente; eso es lo que .map es para, y eso es lo que la mayoría de la gente espera que haga. Sin embargo, si muta el objeto dentro de la devolución de llamada y luego devuelve el objeto original, no tiene mucho sentido usar .map , y aquellos que tienen que mantener el código más tarde podrían ser fácilmente engañados por la intención del código, lo que podría conducir a errores.
Claro, para una función tan pequeña, tal cosa es poco probable, pero para el caso general, las cosas rara vez son tan simples. En mi opinión, devolver nuevos objetos en lugar de mutar los existentes a menudo conduce a un código más limpio y comprensible; hay un gran paradigma de programación basado en eso e ideas similares, pero tiene razón en que:
podríamos estar haciendo una clonación adicional y, en consecuencia, afectando negativamente el rendimiento, ¿verdad?
La creación de objetos completamente nuevos cuando no es necesario podría afectar el rendimiento, especialmente si necesita hacerlo con frecuencia y los objetos que de otro modo tendrían que clonarse son grandes y/o profundos. Pero, las computadoras hoy en día son bastante buenas : es bastante improbable que tal diferencia (mutar frente a crear nuevos objetos) tenga algún efecto perceptible en una sección determinada del código, incluso en una máquina de gama baja. Podría, pero probablemente no lo hará.
Como siempre, si el rendimiento es algo que le preocupa, primero asegúrese de tener un código funcional, claro y mantenible, y luego puede ejecutar pruebas de rendimiento para identificar los cuellos de botella y corregirlos. La optimización prematura lleva tiempo, puede hacer que el código sea más difícil de entender y es posible que no tenga ningún efecto en la aplicación resultante en su conjunto.
En la mayoría de los casos, cuando tiene que elegir entre la mutación y la creación de nuevos objetos, probablemente pueda elegir cualquiera de los dos, y su aplicación será igual de buena, siempre que la intención del código sea clara . Por ejemplo, puede cambiar
const likePosts = (posts) => posts.map((post) => { post.isLiked = true return post; });a
const likePosts = (posts) => { for (const post of posts) { post.isLiked = true; } }; La falta de un valor de retorno y la falta de un .map superfluo hace que la intención sea mucho más clara.