一、引子:

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连续赋值运算的更多相关文章

  1. javascript 连续赋值(连等运算)问题研究

    前几天看到一个javascript 连续赋值的问题,运行了一下,结果出乎意料,发现这里的水真的有点深啊,连续赋值的底层机制,没有一本前端书籍有详细介绍的,自己做实验研究了一下,先来看结果: var a ...

  2. JavaScript 位运算总结&拾遗

    最近补充了一些位运算的知识,深感位运算的博大精深,此文作为这个系列的总结篇,在此回顾下所学的位运算知识和应用,同时也补充下前文中没有提到的一些位运算知识. 把一个数变为大于等于该数的最小的2的幂 一个 ...

  3. javascript位运算

    javascript作为一门高级语言,他尽量让开发人员减少思考底层的硬件工作原理,而将精力集中在逻辑开发的层面.不过,不论这门语言多么高级,我们必须知道数据依然以bits的形式存储,有时候我们会直接与 ...

  4. 一张图彻底搞懂JavaScript的==运算

    一张图彻底搞懂JavaScript的==运算 来源 https://zhuanlan.zhihu.com/p/21650547 PS:最后,把图改了一下,仅供娱乐 : ) 大家知道,==是JavaSc ...

  5. javascript 连续赋值(转载)

    先看一个例子   ● var a = {n:1}; ● var b = a; ● a.x = a = {n:2}; ● console.log("a.x: " + a.x); // ...

  6. 【前端面试】(二)JavaScript加法运算

    视频链接:JavaScript加法运算 - Web前端工程师面试题讲解 数值 + 数值 首先看菜鸟教程有关于数值对象的教程 JavaScript Number 对象 可以知道Infinity , -I ...

  7. (转)深入理解javascript连续赋值表达式

    引入 今天逛园子的时候看到一道javascript面试题,是关于连续赋值的,正好最近读jQuery源码经常看到这种连续赋值的表达式,所以很感兴趣. 废话不多说,来看题: var a = {n: 1} ...

  8. JavaScript 浮点数运算 精度问题

    JavaScript小数在做四则运算时,精度会丢失,这会在项目中引起诸多不便,先请看下面脚本. //加减 <script type="text/javascript" lan ...

  9. JavaScript 中运算优先级问题

    优先级引发的问题 这篇文章对 JavaScript 中的运算符进行小结,很多人对运算符优先级这一知识点都是一带而过.这就导致在写一些比较奇葩的 js 代码,你并不知道它的输出是啥,下面举一个例子,这也 ...

随机推荐

  1. python用户登录,密码错误3次则锁定

    需求: 1.输入用户名密码 2.认证成功后显示欢迎信息 3.输错三次后锁定 实现思路: 1.判断用户是否在黑名单,如果在黑名单提示账号锁定. 2.判断用户是否存在,如果不存在提示账号不存在. 3.判断 ...

  2. kuangbin带你飞 匹配问题 二分匹配 + 二分图多重匹配 + 二分图最大权匹配 + 一般图匹配带花树

    二分匹配:二分图的一些性质 二分图又称作二部图,是图论中的一种特殊模型. 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j ...

  3. 【反演复习计划】【COGS2433】&&【bzoj3930,CQOI2015选数】爱蜜莉雅的冰魔法

    同bzoj3930. (日常盗题图) #include<bits/stdc++.h> #define N 1000010 #define yql 1000000007 #define ll ...

  4. springboot 404返回自定义json(只进入过滤器)

    今天在公司没事干,记一次springboot遇到的一些坑,在百度上也没有搜到类似的问题和答案(或者说 答案不是我想要的) 当我们在SpringBoot遇到了404或者500的错误的时候,你们会怎么办? ...

  5. intValue()的用法

    今天看到了Integer的这个方法,有点疑惑,查了下,做下笔记; 1.intValue()是java.lang.Number类的方法,Number是一个抽象类.Java中所有的数值类都继承它.也就是说 ...

  6. 获取span中的值

    js-code:var baseinfoallfeesum=$("#allFeeSum").html(); $("#baseInfoAllFeeSum").va ...

  7. 2.kafka单节点broker的安装与启动

    下载kafka,http://kafka.apache.org/downloads kafka下面的文件结构如下: 进入bin目录,启动kafka之前要先启动zookeeper ./zookeeper ...

  8. select实现斐波那契和超时机制

    package main import "fmt" func fib(ch chan <-int, quit <- chan bool){ x, y := 1, 1 f ...

  9. python基础复习-1-1文件类型、变量、运算符、表达式

    文件类型: .py python源文件 由python解释器执行 .pyc python源码编译后生成的文件(字节代码) 编译方法: 源码文件中使用py_compile模块 import py_com ...

  10. css深入理解之border

    1.  border-width border-width不支持百分比,类似的还有outline,box-shadow,text-shadow等 border-width支持关键字:thin(1px, ...