La modificación de una copia de un objeto de JavaScript hace que el objeto original cambie

6 minutos de lectura

La modificacion de una copia de un objeto de JavaScript
Vallabha

estoy copiando objA para objB

const objA = { prop: 1 }, 
const objB = objA; 
objB.prop = 2;
console.log(objA.prop); // logs 2 instead of 1

mismo problema para Arrays

const arrA = [1, 2, 3], 
const arrB = arrA; 
arrB.push(4); 
console.log(arrA.length); // `arrA` has 4 elements instead of 3.

  • Esto podría ayudar si no estás usando jQuery: stackoverflow.com/questions/728360/…

    – tomek550

    14/03/2015 a las 14:35

La modificacion de una copia de un objeto de JavaScript
Robbmj

Está claro que tiene algunos conceptos erróneos de lo que la declaración var tempMyObj = myObj; lo hace.

En JavaScript, los objetos se pasan y asignan por referencia (más precisamente, el valor de una referencia), por lo que tempMyObj y myObj son ambas referencias al mismo objeto.

Aquí hay una ilustración simplificada que puede ayudarlo a visualizar lo que está sucediendo.

// [Object1]<--------- myObj

var tempMyObj = myObj;

// [Object1]<--------- myObj
//         ^ 
//         |
//         ----------- tempMyObj

Como puede ver después de la asignación, ambas referencias apuntan al mismo objeto.

Necesitas crear una copia si necesita modificar uno y no el otro.

// [Object1]<--------- myObj

const tempMyObj = Object.assign({}, myObj);

// [Object1]<--------- myObj
// [Object2]<--------- tempMyObj

Respuesta antigua:

Aquí hay un par de otras formas de crear una copia de un objeto.

Como ya estás usando jQuery:

var newObject = jQuery.extend(true, {}, myObj);

Con vainilla JavaScript

function clone(obj) {
    if (null == obj || "object" != typeof obj) return obj;
    var copy = obj.constructor();
    for (var attr in obj) {
        if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr];
    }
    return copy;
}

var newObject = clone(myObj);

Ver aquí y aquí

  • @JAAulde, gracias por actualizar las respuestas, publique su actualización de la pregunta. No estoy seguro de haberlo captado.

    – Robbmj

    14/03/2015 a las 15:13

  • ¡No hay problema! Cuando hago una edición tan extensa de una pregunta que ha sido respondida, trato de hacer un seguimiento. 🙂

    – JA Aulde

    14/03/2015 a las 15:13

  • Puede valer la pena señalar que esto parece comenzar a asomar la cabeza cuando crea sus propios objetos (por ejemplo, let a={}; let b=a; b.blah=1;console.log(a) ). Supongo que muchos novatos (como yo) no notarán esto porque muchos comandos generan un nuevo objeto para nosotros (por ejemplo, mapa/filtro/etc). Me cuesta entender por qué alguien querría sensatamente el comportamiento actual…

    – Granjero de papas

    13 de noviembre de 2019 a las 2:51


  • Object.assign({}, myObj); no creó una copia para mí. En lugar de var tempMyObj = Object.create(myObj); trabajó.

    – Víctor Cui

    15 de marzo de 2021 a las 22:13

  • Esta respuesta también debe incluir cómo hacer esto con matrices: const arrB = arrA.slice();, const arrB = Array.from(arrA);o const arrB = [ ...arrA ];.

    – Sebastián Simón

    24 de julio de 2021 a las 15:24

1646974148 8 La modificacion de una copia de un objeto de JavaScript
Ahmed El Damasy

objeto de clonación profunda con JSON.parse() y JSON.stringify

// Deep Clone
obj = { a: 0 , b: { c: 0}};
let deepClone = JSON.parse(JSON.stringify(obj));

referencia: Este artículo

Mejor referencia: Este artículo

  • este es genial pero no clona funciones dentro del objeto

    -Mina Ragaie

    28 de febrero a las 22:37

  • clonar un objeto que incluye varios niveles o incluye funciones es un proceso complicado, debe usar lodash (lodash.com) para ayudarte en este proceso o crea tu propio algoritmo.

    – Ahmed El Damasy

    2 de marzo a las 12:07

1646974148 872 La modificacion de una copia de un objeto de JavaScript
JKL

Para resumir todo, y como aclaración, hay tres formas de copiar un objeto JS.

  1. A copia normal. Cuando cambia las propiedades del objeto original, las propiedades del objeto copiado también cambiarán (y viceversa).
const a = { x: 0}
const b = a;
b.x = 1; // also updates a.x
  1. A copia superficial. Las propiedades de nivel superior serán únicas para el objeto original y el copiado. Sin embargo, las propiedades anidadas se compartirán entre ambos objetos. Usar el operador de propagación ...{} o Object.assign().
const a = { x: 0, y: { z: 0 } };
const b = {...a}; // or const b = Object.assign({}, a);

b.x = 1; // doesn't update a.x
b.y.z = 1; // also updates a.y.z
  1. A copia profunda. Todas las propiedades son únicas para el objeto original y las copias, incluso las propiedades anidadas. Para una copia profunda, serialice el objeto en JSON y vuelva a analizarlo en un objeto JS.
const a = { x: 0, y: { z: 0 } };
const b = JSON.parse(JSON.stringify(a)); 

b.y.z = 1; // doesn't update a.y.z
  1. Utilizando Object.create() crea un nuevo objeto. Las propiedades se comparten entre los objetos (cambiando uno también cambia el otro). La diferencia con una copia normal es que las propiedades se agregan debajo del prototipo del nuevo objeto. __proto__. Cuando usted Nunca cambie el objeto original, esto también podría funcionar como una copia superficial, pero sugeriría usar uno de los métodos anteriores, a menos que necesite específicamente este comportamiento.

  • Tenga en cuenta que usando JSON.stringify hacer una copia profunda de un objeto descartará cualquier valor que no sea válido en JSON (como funciones) y cualquiera que no sea enumerable.

    – Quintín

    25 de enero a las 11:37

Intente usar el método create() como se menciona a continuación.

var tempMyObj = Object.create(myObj);

Esto resolverá el problema.

La modificacion de una copia de un objeto de JavaScript
invitado271314

Intenta usar $.extender():

Sin embargo, si desea conservar los dos objetos originales, puede hacerlo pasando un objeto vacío como destino:

var object = $.extend({}, object1, object2);


var tempMyObj = $.extend({}, myObj);

  • bingo, eso era lo que estaba a punto de escribir .. 🙂

    – Rohit416

    14/03/2015 a las 14:33

  • JavaScript ahora tiene una función similar incorporada, Object.assign(). Ejemplo de uso: Object.assign({}, myObj).

    – Rory O’Kane

    20 de abril de 2017 a las 22:57

  • @RoryO’Kane: esto me dio lo que necesitaba, ¡muchas gracias!

    – JJ Ward

    9 ene a las 18:23

1646974149 427 La modificacion de una copia de un objeto de JavaScript
Yusuf Febrian

usa tres puntos para esparcir el objeto en la nueva variable

const a = {b: 1, c: 0};
let d = {...a};

  • bingo, eso era lo que estaba a punto de escribir .. 🙂

    – Rohit416

    14/03/2015 a las 14:33

  • JavaScript ahora tiene una función similar incorporada, Object.assign(). Ejemplo de uso: Object.assign({}, myObj).

    – Rory O’Kane

    20 de abril de 2017 a las 22:57

  • @RoryO’Kane: esto me dio lo que necesitaba, ¡muchas gracias!

    – JJ Ward

    9 ene a las 18:23

Como no pude encontrar este código en cualquier lugar alrededor de respuestas sugeridas para casos de copia/clonación superficiales, dejaré esto aquí:

// shortcuts
const {
  create,
  getOwnPropertyDescriptors,
  getPrototypeOf
} = Object;

// utility
const shallowClone = source => create(
  getPrototypeOf(source),
  getOwnPropertyDescriptors(source)
);

// ... everyday code ...

const first = {
  _counts: 0,
  get count() {
    return ++this._counts;
  }
};

first.count;  // 1

const second = shallowClone(first);

// all accessors are preserved
second.count; // 2
second.count; // 3
second.count; // 4

// but `first` is still where it was
first.count;  // just 2

La principal diferencia con respecto a Object.assign o {...spread} operaciones, es que esta utilidad conservará todos los accesores, símbolos, etc., en el proceso, incluida la herencia.

Todas las demás soluciones en este espacio parecen pasar por alto el hecho de que la clonación, o incluso la copia, no se trata solo de valores de propiedades como se recuperan una vez, sino que los accesores y la herencia pueden ser más que bienvenidos en los casos diarios.

Para todo lo demás, use nativo structuredClone método o es polirelleno 👋

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad