var a = {}
var b = {}
try{
a.x.y = b.e = 1 // Uncaught TypeError: Cannot set property 'y' of undefined
} catch(err) {
console.error(err);
}
console.log(b.e) // 1
var a = {}
var b = {}
try {
a.x.y.z = b.e = 1 // Uncaught TypeError: Cannot read property 'y' of undefined
} catch(err) {
console.error(err);
}
console.log(b.e) // undefined
javascript
operators
order-of-execution
Kevin Askin
fuente
fuente
b.z = 1
yb.e = 1
ejecutaría primero (dada la asociatividad derecha activada=
), luegoa.x.y.z = ...
ejecutaría y fallaría; ¿Por qué lab
asignación pasa en un caso pero no en el otro?y
no existe ena.x
; pero eso es cierto en ambos casos. ¿Por qué impide la asignación del lado derecho en el segundo caso pero no en el primero? ¿Qué es diferente en el orden de ejecución? (Mencioné el error de sintaxis porque el tiempo en el error de sintaxis es muy diferente al de un error de tiempo de ejecución).Respuestas:
En realidad, si lee correctamente el mensaje de error, el caso 1 y el caso 2 arrojan errores diferentes.
Caso
a.x.y
:Caso
a.x.y.z
:Supongo que es mejor describirlo paso a paso en un inglés sencillo.
Caso 1
Caso 2
En los comentarios, Solomon Tam encontró esta documentación de ECMA sobre la operación de asignación .
fuente
El orden de las operaciones es más claro cuando explota el operador de coma dentro de la notación de corchetes para ver qué partes se ejecutan cuando:
Mirando la especificación :
PutValue
es lo que arroja elTypeError
:No se puede asignar nada a una propiedad de
undefined
: el[[CanPut]]
método interno deundefined
siempre volveráfalse
.En otras palabras: el intérprete analiza el lado izquierdo, luego analiza el lado derecho, luego arroja un error si no se puede asignar la propiedad del lado izquierdo.
Cuando tu lo hagas
El lado izquierdo se analiza con éxito hasta que
PutValue
se llama; el hecho de que la.x
propiedad se evalúeundefined
no se considera hasta que se analiza el lado derecho. El intérprete lo ve como "Asignar algún valor a la propiedad" y "de indefinido", y asignarlo a una propiedad deundefined
solo arroja dentroPutValue
.A diferencia de:
El intérprete nunca llega al punto en el que intenta asignar a la
z
propiedad, porque primero debe resolvera.x.y
a un valor. Si sea.x.y
resuelve en un valor (incluso aundefined
), estaría bien: se arrojaría un error dentroPutValue
como arriba. Pero accedera.x.y
arroja un error, porquey
no se puede acceder a la propiedad enundefined
.fuente
Considere el siguiente código:
El esquema general de los pasos necesarios para ejecutar el código es el siguiente ref :
a.x.y
devuelve una referencia de referencia que consta de un valor basea.x
(indefinido) y un nombre referenciado (y
).y
de indefinido en el valor. Se supone que esto arroja una referencia de excepción TypeError .fuente