w3schools una tipos pasar parametros funciones funcion entre diferencias diferencia desde javascript

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 .

http://www.ecma-international.org/ecma-262/6.0/index.html#sec-assignment-operators-runtime-semantics-evaluation

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:

  1. 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.

  2. 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:

    1. Evaluar foo para determinar dónde asignar.
    2. Evalúe la expresión {n:2} , que crea un objeto, para determinar el valor a asignar.
    3. Asigne {n:2} a foo, y devuelva {n:2} .

  3. Asigne el valor que la expresión en el lado derecho evaluó a ( {n:2} ), a la referencia a la que foo.x resolvió en el paso 1 ( antes de que se asignara un nuevo valor a foo ). Lo que también es lo mismo que bar.x , debido a la bar = foo asignación bar = 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