tipos - pasar parametros a una funcion javascript desde html
¿Por qué el valor de foo.x no está definido en foo.x=foo={n: 2}? (4)
Esta pregunta ya tiene una respuesta aquí:
Este codigo
var foo = {n: 1};
var bar = foo;
foo.x = foo = {n: 2};
¿Podría explicar qué se entiende por:
foo.x = foo = {n: 2};
Veo que {n:2}
está asignado a foo
. ¿Por qué se asigna undefined
a foo.x
? foo = {n: 2};
volver undefined
?
Debido a que la propiedad de acceso foo.x
a la izquierda se evalúa antes del lado derecho.
Dejemos que quede más claro lo que realmente hace su código, dando nombres nuevos a las expresiones temporales que se evalúan:
var foo0 = {n: 1};
var foo1 = {n: 2};
foo0.x = foo1;
foo0 = foo1;
console.log(foo0.x);
Por foo0.x
tanto, foo0.x
es foo1.x
undefined
está undefined
.
En su código original, puede ver que bar.x
es {n: 2}
, lo que confirma esta explicación.
Debido a que reasignó foo a un objeto con una sola propiedad, { n: 2 }
.
En JavaScript, las expresiones se evalúan de derecha a izquierda. Entonces, cuando intenta acceder a foo.x
, está tratando de obtener el valor de x
del valor recién asignado de foo, { n: 2 }
, que undefined
está undefined
.
Según la especificación de JavaScript, el lado izquierdo siempre se evalúa primero:
12.14.4 Semántica en tiempo de ejecución: evaluación
AssignmentExpression [In, Yield] : LeftHandSideExpression [? Yield] = AssignmentExpression [? In,? Yield]
Si LeftHandSideExpression no es un ObjectLiteral ni un ArrayLiteral , entonces
1. Sea lref el resultado de evaluar LeftHandSideExpression .
Se puede ver claramente si agrega otra referencia al objeto foo
:
var ref = {n:1};
var foo = ref;
var bar = foo;
foo.x = foo = {n: 2};
ref.x
existe porque foo.x
refiere al valor no modificado de foo
.
De acuerdo con la especificación , el lado izquierdo de una expresión de asignación se evalúa primero, aunque el operador tenga prioridad de derecha a izquierda. Por lo tanto, la expresión foo.x = foo = {n: 2}
que es la misma que foo.x = (foo = {n: 2})
se evalúa de la siguiente manera:
- Evalúe la expresión de la mano izquierda
foo.x
para obtener una referencia, que es donde se asignará el valor de la expresión de la mano derecha. - Evalúe la expresión de la mano derecha para obtener el valor que se asignará. El lado derecho es otra expresión de asignación, por lo que se evalúa de la misma manera:
- Evaluar
foo
para determinar dónde asignar. - Evalúe la expresión
{n:2}
, que crea un objeto, para determinar el valor a asignar. - Asigne
{n:2}
a foo, y devuelva{n:2}
.
- Evaluar
- Asigne el valor que la expresión en el lado derecho evaluó a (
{n:2}
), a la referencia a la quefoo.x
resolvió en el paso 1 ( antes de que se asignara un nuevo valor afoo
). Lo que también es lo mismo quebar.x
, debido a labar = foo
asignaciónbar = foo
en la línea anterior.
Cuando se hace esto, el objeto original, esa bar
sigue siendo una referencia a, tendrá una propiedad x
que hace referencia al segundo objeto creado. foo
también es una referencia a ese segundo objeto, entonces foo === bar.x