一、引子:

var a = {n:};
a.x = a = {n:};
alert(a.x); // --> undefined

  以上第二句 a.x = a = {n:2} 是一个连续赋值表达式。这个连续赋值表达式在引擎内部究竟发生了什么?是如何解释的?

二、猜想

  猜想1:从左到右赋值,a.x 先赋值为{n:2},但随后 a 赋值为 {n:2},即 a 被重写了,值为 {n:2},新的 a 没有 x属性,因此为undefined。步骤如下
1, a.x = {n:2};
2, a = {n:2};
这种解释得出的结果与实际运行结果一致,貌似是对的。注意猜想1中 a.x 被赋值过。
  猜想2:从右到左赋值,a 先赋值为{n:2},a.x 发现 a 被重写后(之前a是{a:1}),a.x = {n:2} 引擎限制a.x赋值,忽略了。步骤如下:
1, a = {n:2};
2, a.x 未被赋值{n:2}
等价于 a.x = (a = {n:2}),即执行了第一步,这样也能解释a.x为undefined了。注意猜想2中a.x压根没被赋值过。

三、证明

  上面两种猜想相信多数人都有,有人认为是猜想1, 有人认为是猜想2。其实都错了,我忽略了引用的关系。如下,加一个变量b,指向a。

var a = {n:};
var b = a; // 暂存a
a.x = a = {n:};
alert(a.x);// --> undefined
alert(b.x);// --> [object Object]

  发现 a.x 仍然是undefined,神奇的是 b.x 并未被赋值过(比如:b.x={n:2}),却变成了[object Object]。b 是指向 a({n:1})的,只有a.x = {n:2}执行了才说明 b 是有 x 属性的。

  实际执行过程:从右到左,a 先被赋值为{n:2},随后a.x被赋值{n:2}。等价于:a.x = (a = {n:2});  与猜想2的区别在于 a.x 被赋值了,猜想2中并未赋值。

  最重要的区别,第一步 a = {n:2} 的 a 指向的是新的对象{n:2} , 第二步 a.x = {n:2} 中的 a 是 {a:1}

  即在这个连等语句中,a.x 中的a指向的是 {n:1},a 指向的是 {n:2}。如下图:

  

四:解惑

  这篇写完,或许部分人看完还是晕晕的,因为里面的文字描述实在是绕口。最初我在理解这个连等赋值语句时,认为结果为:{n:2},实际却不是这样的。

  a指向的对象已经不同了,引擎也没有限制a.x的重写。

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

  理解:第一个a.x的a就近原则,指向的是第一行声明的a;console.log(a.x)里的a.x相当于a被重新赋值,就近原则,a指向的是{n:2},并没有x属性,故为undefined。

五:结束

  以另一个连续赋值题结束。fun执行后,这里的 变量 b 溢出到fun外成为了全局变量。想到了吗?

  思考:要记住这种连续赋值,后面的变量是一种隐式声明即可。

function fun(){
var a = b = ;
}
fun();
console.log(a); // --> 报错:a is not defined
console.log(b); // --> 5

最新文章

  1. DIV元素水平和垂直居中
  2. Silverlight datagrid 排序 (转)
  3. <我是一只IT小小鸟>读书笔记
  4. java单例模式和双例模式
  5. TCP/IP详解学习笔记(2)-- 数据链路层
  6. 行内onclick使用遇坑--------作用域与传入字符串
  7. JAVA获取随机数
  8. 大龄剩女四大结局:孤寡 后妈 拉拉 出家 宽带山KDS-宽带山社区-第一城市消费门户
  9. Windows Server 2008 R2 搭建FTP服务
  10. C# 语言规范_版本5.0 (第6章 转换)
  11. 初识webpack——webpack四个基础概念
  12. Grunt参考
  13. FFMPEG 实现 YUV,RGB各种图像原始数据之间的转换(swscale)
  14. .Net Core 部署 CentOs7+Nginx
  15. Python Django对接企业微信第三方服务回调验证的一些坑
  16. Vagrant 入门指南
  17. js中substr、substring、slice的区别
  18. python的列表综合list-comprehension示例,及两列表取补集
  19. Android中服务的生命周期与两种方式的区别
  20. 极限编程核心价值:沟通(Communication)

热门文章

  1. Linux 的源码安装工具 CheckInstall
  2. Basic-Paxos协议日志同步应用
  3. js中给easyui的一列添加按钮
  4. Ubuntu 18.04 sublime text 3176 安装、汉化及配置中文输入
  5. 驱动模块和装模块的概念——Junit单元测试案例
  6. 深入理解Java的注解(Annotation):注解处理器(3)
  7. Spring源码 之环境搭建
  8. Python 进阶 之 @property
  9. JAVA的线程学习、并发线程的学习
  10. explain分析SQL语句详解