您的位置:首页 > 其它

由ECMA规范来看连续赋值

2016-01-26 00:53 381 查看
首先我们来看一段代码:

var a = {n: 1};
var b = a;
a.x = a = {n: 2};
console.log(a.x);
console.log(b.x);


这段代码会输出什么呢?

我们首先来看一下对规范对于赋值操作
A=B
的解释,这一操作的背后究竟发生了什么?

总共有4个步骤

1. 计算表达式
A
,得到
A
的地址
refA


2. 计算表达式
B
,得到
B
的值
valueB


3. 将
valueB
赋值给
refA
指向的名称绑定

4. 返回
valueB


以上的4个步骤也就说明了js的表达式是由右至左的(大部分语言都是这样)

用这种方式来看我们的连续赋值:

A = B = C = D
我们可以看成
A = (B = (C = D))


一、进行的是取地址过程:

1. 取出
A
的地址
refA


2. 取出
B
的地址
refB


3. 取出
C
的地址
refC


4. 取出
D
的地址
refD


二、进行的是取值过程:

1. 取出
D
的值
valueD


三、进行赋值过程:

1. 将
valueD
赋值给
refC
指向的变量,返回
valueD


2. 将
valueD
赋值给
refB
指向的变量,返回
valueD


3. 将
valueD
赋值给
refA
指向的变量,返回
valueD


最终
A,B,C
三个变量的值全部变为
D
的值

下面来看我们文章一开始的那段代码:

首先我们将
a.x
a
的地址分别取出来,在这里分别记为
ref1,ref2


然后我们在计算
{n: 2}
,得到一个值
value1
(也就是一个指针),保存着该对象在内存中的地址

而后将
value1
赋值给
ref1
所指向的变量,对应的对象
a
的地址也会被改变,很多人会有疑问说,这是
ref2
的地址会不会变化,显然是不会的,因为
ref2
只是我们的一个指针,它的值指向的是原来对象
a
在内存中对应对象的地址(
a
的指向改变后,
b
仍指向这片地址),下面就是将
value1
赋值给
ref1
,这时
ref1
的指向被改变,指向内存中
{n: 2}
对象对应的地址。

所以文章开始代码的输出为
undefined
{n: 2}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: