Al pasar objetos como parámetros, JavaScript los pasa por referencia y dificulta la creación de copias locales de los objetos.
var o = {}; (function(x){ var obj = x; obj.foo = 'foo'; obj.bar = 'bar'; })(o)
o
tendrá.foo
y.bar
.Es posible evitar esto mediante la clonación; ejemplo simple:
var o = {}; function Clone(x) { for(p in x) this[p] = (typeof(x[p]) == 'object')? new Clone(x[p]) : x[p]; } (function(x){ var obj = new Clone(x); obj.foo = 'foo'; obj.bar = 'bar'; })(o)
o
no tendrá.foo
o.bar
.
Pregunta
- ¿Existe una mejor manera de pasar objetos por valor, además de crear una copia / clon local?
javascript
vol7ron
fuente
fuente
Respuestas:
Realmente no.
Dependiendo de lo que realmente necesite, una posibilidad puede ser establecer
o
como prototipo de un nuevo objeto.Entonces, cualquier propiedad que agregue
obj
no se agregaráno
. Cualquier propiedad agregadaobj
con el mismo nombre de propiedad que una propiedad eno
sombreará lao
propiedad.Por supuesto, cualquier propiedad agregada
o
estará disponible enobj
si no está sombreada, y todos los objetos que tengano
en la cadena de prototipos verán las mismas actualizacioneso
.También si
obj
tiene una propiedad que hace referencia a otro objeto, como un Array, deberá asegurarse de sombrear ese objeto antes de agregar miembros al objeto; de lo contrario, esos miembros se agregaránobj
y se compartirán entre todos los objetos que tenerobj
en la cadena de prototipos.Aquí puede ver eso porque no siguió la matriz en
baz
elo
con unabaz
propiedad deobj
lao.baz
matriz es modificado.Entonces, en cambio, necesitarías sombrearlo primero:
fuente
Object.create
en mi respuesta, pero no quería estirarme para explicar la superficialidad de la copia ;-)var obj = new Object(x)
. Para mí, creo quenew Object(x)
funcionaríaObject.create(x)
de forma predeterminada - interesantenew Object(x)
simplemente escupe el mismo objeto (como probablemente hayas notado) . Sería bueno si hubiera una forma nativa de clonar. No estoy seguro de si hay algo en proceso.Consulte esta respuesta https://stackoverflow.com/a/5344074/746491 .
En resumen,
JSON.parse(JSON.stringify(obj))
es una forma rápida de copiar sus objetos, si sus objetos se pueden serializar a json.fuente
JSON
no está incluido y debe definirse; bien podría ser más descriptivo con un nombre comoClone
. Sin embargo, sospecho que mi opinión puede cambiar en el futuro, ya que JSON está más integrado en software no basado en navegador como bases de datos e IDEAquí está la función de clonación que realizará una copia profunda del objeto:
Ahora puedes usarlo así:
fuente
Utilizar
Object.assign()
Ejemplo:
Un ejemplo más limpio que hace lo mismo:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
fuente
var b = Object.assign({}, a);
a
se copiarán como referencia.Está un poco confundido acerca de cómo funcionan los objetos en JavaScript. La referencia del objeto es el valor de la variable. No hay ningún valor sin serializar. Cuando crea un objeto, su estructura se almacena en la memoria y la variable a la que se le asignó contiene una referencia a esa estructura.
Incluso si lo que está preguntando se proporcionara en algún tipo de construcción de lenguaje nativo fácil, técnicamente sería una clonación.
JavaScript es realmente solo pasar por valor ... es solo que el valor transmitido podría ser una referencia a algo.
fuente
Utilizar este
x
yx1
serán dos objetos diferentes, el cambiox
no cambiaráx1
fuente
Javascript siempre pasa por valor. En este caso, pasa una copia de la referencia
o
a la función anónima. El código usa una copia de la referencia pero está mutando el objeto único. No hay forma de hacer que JavaScript pase por nada que no sea el valor.En este caso lo que quieres es pasar una copia del objeto subyacente. La clonación del objeto es el único recurso. Sin embargo, su método de clonación necesita un poco de actualización
fuente
Como consideración para los usuarios de jQuery, también hay una manera de hacer esto de una manera simple usando el marco. Solo otra forma en que jQuery nos hace la vida un poco más fácil.
referencias:
fuente
En realidad, Javascript siempre se pasa por valor . Pero debido a que las referencias a objetos son valores , los objetos se comportarán como si fueran pasados por referencia .
Así pues, para caminar por esta, stringify el objeto y analizar de nuevo, tanto el uso de JSON. Vea un ejemplo de código a continuación:
fuente
use obj2 = {... obj1} Ahora ambos objetos tienen el mismo valor pero una referencia diferente
fuente
let a = {value: "old"}
let b = [...a]
b.value = "new"
, y será a{value: "old"}
, será b{value: "new"}
. Pero no funciona cuándolet a = [{value: "old"}]
let b = [...a]
b[0].value = "new"
, y será a[{value: "new"}]
, b será[{value: "new"}]
.Necesitaba copiar un objeto por valor (no referencia) y encontré útil esta página:
¿Cuál es la forma más eficiente de clonar en profundidad un objeto en JavaScript? . En particular, clonar un objeto con el siguiente código de John Resig:
fuente
Con la sintaxis de ES6:
let obj = Object.assign({}, o);
fuente
Object.assign
es que no realiza una copia profunda.Cuando se reduce a eso, es solo un proxy elegante demasiado complicado, pero ¿tal vez Catch-All Proxies podría hacerlo?
fuente
Si está usando lodash o
npm
, use la función de combinación de lodash para copiar en profundidad todas las propiedades del objeto a un nuevo objeto vacío como este:var objectCopy = lodash.merge({}, originalObject);
https://lodash.com/docs#merge
https://www.npmjs.com/package/lodash.merge
fuente