Pregunta JavaScript: ¿Cómo pasar objeto por valor?


  • Al pasar objetos como parámetros, JavaScript los pasa por referencia y hace que sea difícil crear copias locales de los objetos.

    var o = {};
    (function(x){
        var obj = x;
        obj.foo = 'foo';
        obj.bar = 'bar';
    })(o)
    

    o tendrá .foo y .bar.


73
2017-09-27 18:37


origen


Respuestas:


Realmente no.

Dependiendo de lo que realmente necesita, uno posibilidad puede ser para establecer o como el prototipo de un nuevo objeto.

var o = {};
(function(x){
    var obj = Object.create( x );
    obj.foo = 'foo';
    obj.bar = 'bar';
})(o);

alert( o.foo ); // undefined

Así que cualquier propiedad que agregue a obj no será agregado a o. Cualquier propiedad agregada a obj con el mismo nombre de propiedad que una propiedad en o sombreará el o propiedad.

Por supuesto, cualquier propiedad agregada a o estará disponible desde obj si no están sombreados, y todos los objetos que tienen o en la cadena de prototipos verá las mismas actualizaciones para o.

También si obj tiene una propiedad que hace referencia a otro objeto, como una matriz, deberá asegurarse de sombrear ese objeto antes de agregar miembros al objeto, de lo contrario, esos miembros se agregarán a obj, y será compartido entre todos los objetos que tienen obj en la cadena de prototipos.

var o = {
    baz: []
};
(function(x){
    var obj = Object.create( x );

    obj.baz.push( 'new value' );

})(o);

alert( o.baz[0] );  // 'new_value'

Aquí puede ver eso porque no sombreó la matriz en baz en o con un baz propiedad en obj, el o.baz Array se modifica.

Entonces, en lugar de eso, necesitarías sombrearlo primero:

var o = {
    baz: []
};
(function(x){
    var obj = Object.create( x );

    obj.baz = [];
    obj.baz.push( 'new value' );

})(o);

alert( o.baz[0] );  // undefined

50
2017-09-27 18:48



Aquí hay una función de clonación que realizará una copia en profundidad del objeto:

function clone(obj){
    if(obj == null || typeof(obj) != 'object')
        return obj;

    var temp = new obj.constructor(); 
    for(var key in obj)
        temp[key] = clone(obj[key]);

    return temp;
}

Ahora puedes usarlo así:

(function(x){
    var obj = clone(x);
    obj.foo = 'foo';
    obj.bar = 'bar';
})(o)

33
2017-09-27 18:55



Mira esta respuesta https://stackoverflow.com/a/5344074/746491 .

En breve, JSON.parse(JSON.stringify(obj)) es una manera rápida de copiar sus objetos, si sus objetos pueden ser serializados a json.


28
2018-06-17 20:50



Estás un poco confundido acerca de cómo funcionan los objetos en JavaScript. La referencia del objeto es el valor de la variable. No hay un valor no serializado. 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á pidiendo fue proporcionado en algún tipo de construcción fácil, en lenguaje nativo, técnicamente sería clonar.

JavaScript realmente es solo pasar por valor ... es solo que el valor pasado podría ser una referencia a algo.


13
2017-09-27 18:46



Utilizar Object.assign()

Ejemplo:

var a = {some: object};
var b = new Object;
Object.assign(b, a);
// b now equals a, but not by association.

Un ejemplo más limpio que hace lo mismo:

var a = {some: object};
var b = Object.assign({}, a);
// Once again, b now equals a.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign


10
2018-03-02 23:59



Utilizar esta

x = Object.create(x1);

x y x1 habrá dos objetos diferentes, cambio en x no cambiará x1


8
2017-08-19 08:49



Javascript siempre pasa por valor. En este caso, está pasando una copia de la referencia o en la función anónima. El código está usando una copia de la referencia pero está mutando el único objeto. No hay forma de que javascript pase por otro valor que no sea el valor.

En este caso, lo que desea es pasar una copia del objeto subyacente. Clonar el objeto es el único recurso. Su método de clonación necesita un poco de una actualización, aunque

function ShallowCopy(o) {
  var copy = Object.create(o);
  for (prop in o) {
    if (o.hasOwnProperty(prop)) {
      copy[prop] = o[prop];
    }
  }
  return copy;
}

7
2017-09-27 18:48



Como una consideración para los usuarios de jQuery, también hay una manera de hacerlo de una manera simple usando el marco. Solo otra forma en que jQuery nos hace la vida un poco más fácil.

var oShallowCopy = jQuery.extend({}, o);
var oDeepCopy    = jQuery.extend(true, {}, o); 

referencias:


6
2018-04-09 17:09



En realidad, Javascript es siempre pasar por valor. Pero debido a que las referencias de objeto son valores, los objetos se comportarán como si fueran pasado por referencia.

Entonces para caminar alrededor de esto, stringify el objeto y analizar gramaticalmente de vuelta, ambos usando JSON. Ver ejemplo de código a continuación:

var person = { Name: 'John', Age: '21', Gender: 'Male' };

var holder = JSON.stringify(person);
// value of holder is "{"Name":"John","Age":"21","Gender":"Male"}"
// note that holder is a new string object

var person_copy = JSON.parse(holder);
// value of person_copy is { Name: 'John', Age: '21', Gender: 'Male' };
// person and person_copy now have the same properties and data
// but are referencing two different objects

5
2018-03-03 12:53



Necesitaba copiar un objeto por valor (no referencia) y encontré útil esta página:

¿Cuál es la forma más eficiente de clonar un objeto en JavaScript?. En particular, clonando un objeto con el siguiente código por John Resig:

//Shallow copy
var newObject = jQuery.extend({}, oldObject);
// Deep copy
var newObject = jQuery.extend(true, {}, oldObject);

2
2017-08-12 13:25