2012-01-30 6 views
6

Incluso como un desarrollador JS un tanto experimentado, me encuentro constantemente sorprendido por las copias superficiales y profundas de los objetos.¿Existen reglas generales para cuando los valores de JavaScript se copian por referencia y no por valor?

¿Hay alguna regla general para cuando los valores de JavaScript se copian por referencia y no por valor para los tipos de objetos principales? Por ejemplo, sé que los valores de cadena siempre se copian por valor y no por referencia.

+0

Depende de su método de copia. Tienes que ser específico, ¿cómo copias tus valores? –

+0

¿O quisiste decir el caso cuando un valor pasa como argumento en una función? –

+0

En lugar de pasar por argumentos, estoy pensando en un simple 'var x, y; x = {'blah': 'foo'}; y = x; x = {'bar': 'bas'}; console.log (y); 'tipo de situaciones, pero si hay más matices para los tipos de copia que, por favor, hágame saber cómo puedo mejorar la pregunta. – buley

Respuesta

4

En JavaScript, todos los objetos se almacenan y se pasan 'por referencia'.

var a = { v: 'a' }, b = { v: 'b' }; 
a=b; 
b.v='c'; 

a y b hará referencia al mismo objeto; a.v == 'c' y b.v == 'c'.

tipos de datos primitivos (string, number, boolean, null, y undefined) son inmutables; ellos son pasados ​​por valor.

var a = 'a', b = 'b'; 
a=b; 
b='c'; 

Dado que estamos tratando con primitivas, a == 'b' y b == 'c'.


Pedantes le dirá que JavaScript no se pasan por referencia en un sentido clásico, o que es un lenguaje "puro pase por valor", pero creo que eso complica las cosas, a efectos prácticos. No, no puede modificar directamente un argumento pasado a una función como si fuera una variable (lo que sería cierto si el idioma fuera verdadero paso por referencia), pero tampoco recibe una copia de un objeto pasado como argumento (como lo haría si fuera true pass-by-value). Para la mayoría de los propósitos (desde el punto de vista del usuario del idioma, usted), los objetos pasados ​​a una función son referencias, ya que puede modificar ese objeto y afecta el objeto de la persona que llama. Vea también el fantastic answers to this question.

2

bien, permítanme explicar su código:

var x, y; 
x = { 'blah': 'foo' }; 
y = x; 
x = { 'bar': 'bas' }; 

Por lo tanto, se declaran dos variables, y luego se asigna un valor de objeto a la primera variable:

x = { 'blah': 'foo' }; 

Por lo tanto, lo que pasa aquí :

  1. Se evalúa el objeto literal - { ... } - lo que da como resultado la creación e inicialización de un nuevo objeto nativo
  2. A referencia para este objeto se asigna a la variable x.

A continuación, esta línea

y = x; 

simplemente copia la referencia que se almacena en x a la variable y. Ahora ambas variables almacenan la misma referencia al objeto.

Finalmente, esta línea

x = { 'bar': 'bas' }; 

asigna un nuevo valor a la variable x. Se evalúa el objeto literal que da como resultado la creación/inicialización de otro objeto, y una referencia a ese objeto se almacena en x.

La variable y, sin embargo, todavía contiene una referencia al primer objeto.

Cuestiones relacionadas