之前在扒源码时经常看到类似的连续赋值操作:

 var a = b = 1; 

在某度搜了众多前辈的博客,总算对这骚操作有点眉目。

Case analysis

首先,javascript中连续赋值最典型案例是:

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

Analysis in short

var a = {n: 1}; //创建对象{n: 1},a指向对象{n: 1}
var b = a; //将 a中的地址传给b,即 b也指向对象{n: 1}
a.x = a = {n: 2};
/*
1)创建对象{n: 1}中的"x"属性
2)将a指向新对象{n: 2}
3) 将对象{n: 1}中的"x"指向新对象{n: 2}
*/
console.log(a.x); //undefined
console.log(b.x); //{n: 2}

如果看懂了,下面可以直接忽略2333

Analysis in long

我归纳了一下,要看懂这个问题要理解三个点:

  • 此处的a,b是引用类型

  • 在javascript中字段访问操作符"."的优先级高于赋值操作符"="

  • 出现多个赋值操作符"="时,运算顺序为从右向左

1. 此处的a,b是引用类型

引用类型是区别于基本类型的。javasript中的基本类型总共有5种,Undefined、Null、String、Number、Boolean。引用类型有Object,Array,Function,,,blabla~,简单说就是除了5种基本类型,可以说其它都为引用类型。

案例中的{n: 1}和{n: 2}都为Object类,即为引用类型。在javascript中当复制保存某个对象时,操作的是对象的引用,但在为对象添加属性时,操作的是实际的对象。即在第一行和第二行命令中a,b其实存储的是对象{n: 1}的引用(地址)。

这有点像C中的指针。如下图,案例第一行命令可以解析为,在堆(heap)中创建了一个对象{n: 1},另外在栈(stack)中创建了变量a,变量a的值为对象{n: 1}的地址,即图中的h[0]。第二行命令意思是再在栈中创建另一个变量b,变量b的值与变量a的值相等,即为对象{n: 1}的地址。

打个比方,你有一张去餐馆的地图,你把地图复制一份给你的基友,地图是多了一张,但餐馆的实际位置是没有改变的。

2. 运算顺序问题

这一节对应的是第二和第三个点。根据javascript中的运算符优先级 Operator precedence,可知:

  • 在javascript中字段访问操作符"."的优先级高于赋值操作符"="
  • 出现多个赋值操作符"="时,运算顺序为从右向左

因此在运行第三行命令时,分3步执行:

(1)先执行"a.x",此时a储存的仍然是h[0]地址,即指向对象{n: 1}。"a.x"相当于"h[0].x",即在对象{n: 1}中添加了属性"x",变为{n: 1; x: undefined},但是"x"还没赋值;注意,此时对象{n: 1; x: undefined}中的"x"属性是等待赋值的,操作挂起。

(2)再执行"a = {n: 2}",由于{n: 2}是个新对象,则程序在堆中再创建一个对象{n: 2},并且将变量a指向该对象,如图,此时a储存的即为h[1]的地址

(3)最后一步"a.x = a",(1)中被挂起的操作继续执行,对象{n: 1; x: undefined}中的"x"指向对象{n: 2}。运算完成。

3. 结果解释

在运行完上述命令后,变量a指向了新对象{n : 2};变量b 的地址没有发生改变,因而仍指向修改后的对象{n: 1;x: {n : 2}}。

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

理解javascript中的连续赋值的更多相关文章

  1. 理解JavaScript中的原型继承(2)

    两年前在我学习JavaScript的时候我就写过两篇关于原型继承的博客: 理解JavaScript中原型继承 JavaScript中的原型继承 这两篇博客讲的都是原型的使用,其中一篇还有我学习时的错误 ...

  2. 深入理解JavaScript中创建对象模式的演变(原型)

    深入理解JavaScript中创建对象模式的演变(原型) 创建对象的模式多种多样,但是各种模式又有怎样的利弊呢?有没有一种最为完美的模式呢?下面我将就以下几个方面来分析创建对象的几种模式: Objec ...

  3. 深入理解JavaScript中的属性和特性

    深入理解JavaScript中的属性和特性 JavaScript中属性和特性是完全不同的两个概念,这里我将根据自己所学,来深入理解JavaScript中的属性和特性. 主要内容如下: 理解JavaSc ...

  4. 深入理解javascript中执行环境(作用域)与作用域链

    深入理解javascript中执行环境(作用域)与作用域链 相信很多初学者对与javascript中的执行环境与作用域链不能很好的理解,这里,我会按照自己的理解同大家一起分享. 一般情况下,我们把执行 ...

  5. 【干货理解】理解javascript中实现MVC的原理

    理解javascript中的MVC MVC模式是软件工程中一种软件架构模式,一般把软件模式分为三部分,模型(Model)+视图(View)+控制器(Controller); 模型:模型用于封装与应用程 ...

  6. 理解javascript中的策略模式

    理解javascript中的策略模式 策略模式的定义是:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换. 使用策略模式的优点如下: 优点:1. 策略模式利用组合,委托等技术和思想,有效 ...

  7. 深入理解javascript中的立即执行函数(function(){…})()

    投稿:junjie 字体:[增加 减小] 类型:转载 时间:2014-06-12 我要评论 这篇文章主要介绍了深入理解javascript中的立即执行函数,立即执行函数也叫立即调用函数,通常它的写法是 ...

  8. 转载 深入理解JavaScript中的this关键字

    转载原地址: http://www.cnblogs.com/rainman/archive/2009/05/03/1448392.html 深入理解JavaScript中的this关键字   1. 一 ...

  9. js架构设计模式——理解javascript中的MVVM开发模式

    理解javascript中的MVVM开发模式 http://blog.csdn.net/slalx/article/details/7856769 MVVM的全称是Model View ViewMod ...

随机推荐

  1. Echarts设置点击事件

    简单明了. echarts初始化完成之后,给实例对象通过on绑定事件. 这里的事件包括: 'click','dblclick','mousedown','mouseup','mouseover','m ...

  2. RF(ride 工具使用)

    1.新建项目 project,工程 suite,用例 testcase 新建 project:file -> new project,输入工程名,Type 选择 directory,选择工程存放 ...

  3. http抓包—Content-Type讲解

    1.Content-Type的定义 Content-Type(MediaType),即是Internet Media Type,互联网媒体类型,也叫做MIME类型.在互联网中有成百上千中不同的数据类型 ...

  4. celery的定时任务

    定时任务 Celery 中启动定时任务有两种方式,(1)在配置文件中指定:(2)在程序中指定. # cele.py import celery app = celery.Celery('cele', ...

  5. 【BIM】BIMFACE中创建雾化效果

    背景 在BIM运维场景初始化的时候,一般都是首先将整个运维对象呈现在用户面前,例如一座大厦.一座桥梁.一个园区等等,以便于用户进行总览,总体把握运维对象,如果这个宏大的场景边界过于清晰,与背景融合也不 ...

  6. MAC使用Scrapy遇到的坑

    MAC版本:EI Captain Python版本: 2.7.10 MAC默认没有安装pip,所以首先 sudo easy_install pip 然后安装Scrapy: sudo pip insta ...

  7. vue将后台的值赋给前台

    后台传List到前台: 赋值给table 赋值给form(只能一个个的赋值,对应prop属性) 后台传map到前台:(不需要使用下标取值)

  8. css实现文字相对于图片垂直居中

    一 要实现的样式,文字在图片的垂直居中位置 二 实现的代码: <style> .flag{ position: absolute; bottom: 0; width: 23rem; hei ...

  9. 03_CSS入门和高级技巧(1)

    上节课知识的复习 插入图片,页面中能够插入的图片类型:jpg.jpeg.bmp.png.gif:不能的psd.fw. 语法: <img src="路径" alt=" ...

  10. numpy数组的分割与合并

    合并 np.newaxis import numpy as np a=np.array([1,2,3])[:,np.newaxis]#变成列向量 b=np.array([4,5,6])[:,np.ne ...