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

 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. Maven Wrapper简介

    文章目录 简介 Maven Wrapper的结构 下载Maven Wrapper 使用 Maven Wrapper简介 简介 开发java项目少不了要用到maven或者gradle,对比gradle而 ...

  2. spark系列-2、Spark 核心数据结构:弹性分布式数据集 RDD

    一.RDD(弹性分布式数据集) RDD 是 Spark 最核心的数据结构,RDD(Resilient Distributed Dataset)全称为弹性分布式数据集,是 Spark 对数据的核心抽象, ...

  3. layui表格参数

    layui表格对数据进行用table样式展现 举个例子: <!doctype html> <html> <head> <meta charset=" ...

  4. 微信Webapp开发的各种变态路由需求及解决办法!

    前言 最近在使用BUI Webapp开发的一个小商城项目在微信上遇到一些坑及变态需求, 层层深入, 整理一下给后来人参考. 一定有你还不知道的! 调试缓存 问题描述: 微信打开的web页面默认是会缓存 ...

  5. LFS资料和SSH远程登录全过程

    LFS 即 Linux From Scratch, From Scratch的意思是"白手起家",即从0开始安装Linux,它的所有软件包都需要从源代码开始编译安装.这是通过实际动 ...

  6. Notations

    下面四种记号是为了建立函数间的相对级别. CLRS上的一张图很直观: 大O记号 定义:如果存在正常数\(c\)和\(n_0\),使得当\(N\ge n_o\)时\(T(N)\le cf(N)\),记\ ...

  7. CodeForces - 1047B Cover Points

    B. Cover Points time limit per test1 second memory limit per test256 megabytes inputstandard input o ...

  8. P1516 青蛙的约会和P2421 [NOI2002]荒岛野人

    洛谷 P1516 青蛙的约会 . 算是手推了一次数论题,以前做的都是看题解,虽然这题很水而且还交了5次才过... 求解方程\(x+am\equiv y+an \pmod l\)中,\(a\)的最小整数 ...

  9. MySQL如何安装-教程

    1.先从官网上下载Mysql压缩包https://dev.mysql.com/downloads/mysql/2.解压出来的mysql压缩包是没有图片中的data文件夹和my.ini 如图所示: 3. ...

  10. Android 讯飞语音听写SDK快速接入(附空指针解决和修改对话框文字方法)

    1.账号准备工作 首先要有一个讯飞的账号啦,为后面申请APPID.APPKey等东西做准备.顺带一提:讯飞对不同认证类型用户开 放的SDK的使用次数是有不同的,详情如下图. 账号申请完成后,需要去你自 ...