JS:连续赋值运算

首先来看一段代码:

1
2
3
var o = {a:1};
o.b = o = {a:2};
alert(o.b); // undefined

以上第二句 o.b = o = {a:2} 是一个连续赋值表达式。那么在这个过程中究竟发生了什么呢?

在ECMAScript(3rd)文档中有关于赋值表达式的解释:

The production AssignmentExpression : LeftHandSideExpression = AssignmentExpression is evaluated as follows:

  1. Evaluate LeftHandSideExpression.
  2. Evaluate AssignmentExpression.
  3. Call GetValue(Result(2)).
  4. Call PutValue(Result(1), Result(3)).
  5. Return Result(3).

左侧得出的是引用,右侧调用GetValue取得的是确定值。

然后我们来分析 o.b = o = {a:2} 这个表达式。假设 {a: 1} 这个对象为 obg1,{a: 2} 这个对象为obg2,全局为global。

上述表达式的解析过程如下:o.b = Expression1,而 Expression1 为另一个赋值表达式 o = {a:2} 。

首先解析 o.b = expression1,步骤如下:

  1. 先取得引用 (obj1, "b") 。
  2. 然后解析 Expression1 。这个解析过程的步骤如下:
    1. 先取得引用 (global, "o") 。
    2. 求赋值表达式的值: obg2 。
    3. 取得步骤 b 中的结果: obg2 。
    4. 将步骤 c 的结果赋值给步骤 a 的结果,即把 obg2 赋值给 (global, "o") 。
    5. 返回步骤 c 的结果,即 obg2 。
  3. 取得步骤 2 中的结果: obg2 。
  4. 将步骤 3 的结果赋值给步骤1的结果,即把 obg2 赋值给 (obj1, "b") 。
  5. 返回步骤 3 的结果,即 obg2 。

结果即为:

obg1: {a: 1, b: obg2}

obg2: {a: 2}

我们常说赋值运算是从右至左,是指右边先结合。如果理解为右边先运算就会有误解了,虽然右边先赋值成功。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值