奇特的JavaScript连续赋值运算
一、引子:
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
奇特的JavaScript连续赋值运算的更多相关文章
- javascript 连续赋值(连等运算)问题研究
前几天看到一个javascript 连续赋值的问题,运行了一下,结果出乎意料,发现这里的水真的有点深啊,连续赋值的底层机制,没有一本前端书籍有详细介绍的,自己做实验研究了一下,先来看结果: var a ...
- JavaScript 位运算总结&拾遗
最近补充了一些位运算的知识,深感位运算的博大精深,此文作为这个系列的总结篇,在此回顾下所学的位运算知识和应用,同时也补充下前文中没有提到的一些位运算知识. 把一个数变为大于等于该数的最小的2的幂 一个 ...
- javascript位运算
javascript作为一门高级语言,他尽量让开发人员减少思考底层的硬件工作原理,而将精力集中在逻辑开发的层面.不过,不论这门语言多么高级,我们必须知道数据依然以bits的形式存储,有时候我们会直接与 ...
- 一张图彻底搞懂JavaScript的==运算
一张图彻底搞懂JavaScript的==运算 来源 https://zhuanlan.zhihu.com/p/21650547 PS:最后,把图改了一下,仅供娱乐 : ) 大家知道,==是JavaSc ...
- javascript 连续赋值(转载)
先看一个例子 ● var a = {n:1}; ● var b = a; ● a.x = a = {n:2}; ● console.log("a.x: " + a.x); // ...
- 【前端面试】(二)JavaScript加法运算
视频链接:JavaScript加法运算 - Web前端工程师面试题讲解 数值 + 数值 首先看菜鸟教程有关于数值对象的教程 JavaScript Number 对象 可以知道Infinity , -I ...
- (转)深入理解javascript连续赋值表达式
引入 今天逛园子的时候看到一道javascript面试题,是关于连续赋值的,正好最近读jQuery源码经常看到这种连续赋值的表达式,所以很感兴趣. 废话不多说,来看题: var a = {n: 1} ...
- JavaScript 浮点数运算 精度问题
JavaScript小数在做四则运算时,精度会丢失,这会在项目中引起诸多不便,先请看下面脚本. //加减 <script type="text/javascript" lan ...
- JavaScript 中运算优先级问题
优先级引发的问题 这篇文章对 JavaScript 中的运算符进行小结,很多人对运算符优先级这一知识点都是一带而过.这就导致在写一些比较奇葩的 js 代码,你并不知道它的输出是啥,下面举一个例子,这也 ...
随机推荐
- HDU2819(二分图匹配,记录过程)
Swap Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- ubuntu下wireshark+scapy+tcpreply
安装wireshark命令: sudo apt-get install wireshark 运行打开wireshark命令: sudo wireshark(一定要以超级权限打开) 正确打开的窗口应该默 ...
- 第三方库SDWebImage的原理
关于SDWebImage,其实是不用懂原理的,只是有一些面试官会问,分享给正在找工作的朋友们: 不多说直接上图: 另外..... 我的愿望是....... 世界和平.........
- lucene 排序
(1)排序对一个文档里什么域都没存储,使用字符串排序会排在首位 (2)排序对一个文档里什么域都没存储,使用数字类型排序会默认给其赋值为0进行排序 (3)我们可以对数字类型的null值的文档进行代码控制 ...
- k8s的chart学习(下)
1.开发自己的chart Kubernetes 给我们提供了大量官方 chart,不过要部署微服务应用,还是需要开发自己的 chart,下面就来实践这个主题. 1.1创建 chart 执行 helm ...
- Go简单的Goroutine示例
最简单的,接下来,会是竞争,加锁... package main import ( "fmt" "runtime" "sync" ) var ...
- [libgdx游戏开发教程]使用Libgdx进行游戏开发(3)-给游戏添加一些控制功能
每个游戏中都有一些只有程序员自己才知道的控制功能,比如增加金钱,满血复活,无视防御,不死等等. 都是为了方便自己调试而在测试阶段使用的功能. 正如上一章提到的:我们也需要加些只有程序员才知道的控制功能 ...
- Linux下Tomcat安装配置
买了台阿里云服务器,因为配置比较低,所以用Linux系统,这里记录一下我在Linux系统中Tomcat的安装配置. 前提JDK已经安装好. 安装 首先在/usr/local/下建立一个tomcat的文 ...
- Vue 不使用Vuex的情况下进行状态管理
在封装自己的Vue ui库的时候,往往要封装一些比较复杂的组件,比如说table,form之类.这些组件由于功能繁杂,还涉及到子组件嵌套及通信,如果没有一套状态管理方案的话很容易导致代码难以阅读.难以 ...
- Jquery EasyUI选项卡-Tabs的使用方法
以下是easyUI的tabs的简单实用介绍. var e =$('#main').tabs('exists','accordion'); if(e==true){ $('#main').tabs(' ...