2012-01-09 9 views
5

El ejemplo básico:La operación de asignación de Javascript es copiar referencias?

var b = 10; 
var c = b; 
b++; 
console.log(b,c); 

>> 11 10 

c parece una copia de b.

Pero en otro caso:

var x = {}; 
var y = x; 
x.abc = 10; 
console.log(x.abc, y.abc); 

>> 10 10 

¿Por qué es el y no una copia de x, sino una referencia que apunta a la misma instancia x puntos a?

Además, supongo que b++ crea otra instancia, por lo que b apunta a la nueva instancia pero c apunta al anterior. Sin embargo ...

var u = 10; 
setTimeout(function() { 
    console.log(u); 
}, 10000) 
u++; 

>> 11 

Si u++ crea una nueva instancia, entonces el u dentro de la función anónima debe apuntar a la edad u, ¿no debería?

Respuesta

9

el c parece una copia de b.

Ambos son referencias del mismo valor inmutable.

Por qué la y no es una copia de x sino una referencia que apunta a la instancia x puntos a?

x fue una referencia a un objeto en primer lugar, por lo y es una copia de la misma (una copia de la referencia, no una copia del objeto).

Si u++ crea una nueva instancia,

No lo hace.

u en la función anónima debe apuntar a la antigua u, ¿no?

u++ asigna una referencia a 11 a u. La función anónima está mirando u y no "el valor de u en el momento en que se creó la función".

+0

tu última frase en realidad resuelve mi confusión. –

+1

@Quentin: por lo que el "objeto" original solo reside en algún lugar dentro del 'objeto de activación' o 'entorno léxico' creado por la implementación js (ES3/5) y nunca puede ser tocado por E CMAscript en sí. – jAndy

+0

"Ambas son referencias del mismo valor inmutable". ¿Eso no contradice la salida observada "11 10"? La salida sugeriría que son referencias a diferentes valores – Neptilo

8

Cuando se asignan primitivas, se les asigna por el valor; los tipos de referencias (como su objeto) se asignan al por referencia (o, como Jon Skeet me corrige, se les asigna una copia de la referencia).

En su segundo ejemplo x e y tanto punto a el mismo objeto en la memoria. Es por eso que la adición de una propiedad abc a uno, también se agrega a la otra

También tendría observa el mismo comportamiento que pasa xoy en una función

function addABC(foo) { 
    foo.abc = 10; 
} 

var x = {}; 
var y = x; 
addABC(x); 
console.log(x.abc, y.abc); 

Ten en cuenta que, a pesar de x e y punto al mismo objeto en la memoria, que son copias separadas de la referencia, por lo que este

var x = { a: 1 }; 
    var y = x; 
    y = {}; 
    alert(x.a); 

y esto

var x = { a: 1 }; 
    var y = x; 
    x = {}; 
    alert(y.a); 

todavía le alertará 1.

+1

No me gusta la terminología de "por referencia" aquí, porque * real "pass-by-reference o copy-by-reference es algo diferente. Por ejemplo, suponga que cambió su método' addABC' a 'foo = "hola" ', eso no cambiaría el valor de' x', ¿verdad? (Es cierto que * supongo * que JavaScript funciona de la misma manera que Java y C# aquí, pero creo que es una suposición razonable.) –

+0

@Jon - tienes razón. Voy a editar –

4

Esta afirmación:

var y = x; 

copia el valor de x como el valor inicial de y. Sin embargo, los valores implicados son referencias a un objeto, no el objeto en sí. Tenga en cuenta que esto es no lo mismo que decir que la asignación copia "una referencia a x" - realmente es el valor de x. Entonces, en particular, si cambia el valor de x para referirse a un objeto diferente, p.

x = "something else"; 

entonces que no va a cambiar el valor de y - su valor seguirá siendo una referencia al objeto original.

+1

Jon Skeet?!?! En la etiqueta de JavaScript?!?! Bienvenido, bien señor! –

+3

@AdamRackis: Él ha sumergido su dedo del pie en este estanque antes. –

Cuestiones relacionadas