js 连等赋值 分析
JavaScript权威指南-第6版 4.11 赋值表达式 提到了连等赋值的情况,但是解释的不够详细,所以在此总结下;
首先看书上最重要的一句话:

这句话总结下就是:
A = B ; // 整个表达式返回 B
但是完整意义上是这样的:
计算表达式A,得到一个引用
refA;计算表达式B,得到一个值
valueB;将
valueB赋给refA指向的名称绑定;返回
valueB。
第二句:

这句话总结下就是:
A1 = A2 = A3 = A4 // 等价于A1 = (A2 = (A3 = A4))
又因为前面所说,赋值表达式的值就是右操作数的值,所以
(A3 = A4) // 返回 A4
A1 = (A2 = (A3 = A4))
//等价于
//先 从左至右 计算好 A1,A2,A3 的引用,然后
A3 = A4
A2 = A4
A1 = A4
所以,汇总下:
A1 = A2 = A3 = A4
实际上就等价于:
//先 从左至右 计算好 A1,A2,A3 的引用,然后
A1 = A4;
A2 = A4;
A3 = A4;
好了,前面的看懂了,就来到这道神题,javascript 连等赋值问题:
var a = {n:1};
var b = a;
a.x = a = {n:2};
console.log(a.x);// --> undefined
console.log(b.x);// --> {n:2}
我第一次答的时候也错了,后来理理逻辑才对,下面分析分析,不过分析之前建议大家先看这篇:js 操作对象的引用和操作实际对象的区分
言归正传,上面的代码其实等价于下面这样:
var a = { n: 1 };
var b = a;
//先 从左至右 计算好 a,a.x 的引用,然后
a = { n: 2 };
a.x = { n: 2 };
console.log(a.x); // --> undefined
console.log(b.x); // --> {n:2}
关键是这段代码:
a.x = { n: 2 };
这段代码其实跟 a 并没有什么关系,因为 在为对象添加属性时,操作的是实际的对象。
所以,它仅仅是把对象 { n: 1 } 变成了 { n: 1, x: { n: 2 } },你可能疑问,在这个赋值前,a 的对象不就已经是 { n: 2 }了么?
不不不!看红色字体!!!
var a = { n: 1 };
var b = a;
//a.x = a = { n: 2 }; 先 从左至右 计算好 a,a.x 的引用,然后
a = { n: 2 };
a.x = { n: 2 }; //此时的 a 在赋值前就已经计算好引用了,实际上引用的是 { n:1 } 这个对象
console.log(a.x); // --> undefined
console.log(b.x); // --> {n:2}
这样也反过来证明了前面赋值表达式 A=B 的逻辑;
add another demo
var total=0
async function add(num){
// await only delay the assignment operation
// that's how js works in assignment
total=(console.log('executed sync',total)||total)+await (console.log('await execute after expression before')||num)
console.log('res')
}
add(1)
add(2)
Promise.resolve().then(()=>{
console.log(total)
})
参考资料:
由ES规范学JavaScript(二):深入理解“连等赋值”问题
javascript 连等赋值问题
js 连等赋值 分析的更多相关文章
- JS连等赋值的坑
cnblogs标题: JS连等赋值的坑 关于JS连等赋值有个经典的笔试题: var a = {n: 1}; var b = a; a.x = a = {n: 2}; console.log(a.x); ...
- C#保留2位小数几种场景总结 游标遍历所有数据库循环执行修改数据库的sql命令 原生js轮盘抽奖实例分析(幸运大转盘抽奖) javascript中的typeof和类型判断
C#保留2位小数几种场景总结 场景1: C#保留2位小数,.ToString("f2")确实可以,但是如果这个数字本来就小数点后面三位比如1.253,那么转化之后就会变成1.2 ...
- (网页)Angular.js 中 copy 赋值与 = 赋值 区别
转自st.gg Angular.js 中 copy 赋值与 = 赋值 区别 为什么用 $scope.user = $scope.master; $scope.master 会跟着 $scope.use ...
- Flash和js交互的效率分析
Flash和js交互的效率分析 AS代码: var time:int = getTimer(); for (var i:int = 0; i < 50000; i++) { External ...
- fastclick.js源码解读分析
阅读优秀的js插件和库源码,可以加深我们对web开发的理解和提高js能力,本人能力有限,只能粗略读懂一些小型插件,这里带来对fastclick源码的解读,望各位大神不吝指教~! fastclick诞生 ...
- js对象等号赋值的bug
var a = {n: 1}; var b = a; a.x = a = {n: 2}; console.log(a.x); console.log(b.x); 有道题是这样的,觉得很奇葩,分析一下 ...
- js连等赋值
引用:http://www.iteye.com/topic/785445 https://segmentfault.com/q/1010000002637728 这是一个问题 var a = {n:1 ...
- AS3和js相互通信要点分析
目标:在html页面里可以使用事件来影响到swf文件的内容,swf文件也可以影响html里js代码的内容 一.新建flash文件,用Flash CC试用版新建一个TextArea.fla的源文件,不添 ...
- Js的引用赋值与传值赋值
要说js的赋值方式时首先要说明js的数值类型:基本类型和引用类型. 1.基本类型 基本的数据类型有:undefined,boolean,number,string,null. 基本类型存放在栈区,访问 ...
随机推荐
- mybatis 特殊符号转义和模糊查询和批量插入
1 xml文件特殊符号转义 < < > > <> <> & & ' ...
- mysql多实例安装详解
首先说明一个场景:我的电脑是ubuntu系统,之前apt-get自动安装过mysql.这也是出现错误最多的原因之一. 安装过程,其中充斥着各种错误: 6.mkdir mysql 7.groupadd ...
- Atitit.数据库新特性战略规划 mssql sql server 2008 SQL2012 SQL2014
Atitit.数据库新特性 mssql sql server 2008 SQL2012 SQL2014 1. Sql2012 新特性 1 1.1. 增加了Sequence对象. 1 1.2. 新的分页 ...
- atitit.D&D drag&drop拖拽文件到界面功能 html5 web 跟个java swing c#.net c++ 的总结
atitit.D&D drag&drop拖拽文件到界面功能 html5 web 跟个java swing c#.net c++ 的总结 1. DND的操作流程 1 2. Html5 注 ...
- CCOrbitCamera
Cocos2d-x提供了一中根据球面坐标轨迹旋转的方式CCOrbitCamera CC_DEPRECATED_ATTRIBUTE static CCOrbitCamera* actionWithDur ...
- ENGINE_API CXNoTouch
/************************************************************************/ //屏蔽消息面板 //优先级默认为 TP_BOTT ...
- Makefile 10——打造更专业的编译环境-huge项目
先手工创建几个文件目录: 接下来先创建code/foo/src目录下的Makefile: .PHONY: all clean MKDIR = mkdir RM = rm RMFLAGS = -rf C ...
- php html 转义
html_entity_decode($string);htmlentities($string);htmlspecialchars($string);htmlspecialchars_decode( ...
- 在eclipse上Checkstyle的安装和使用
1. 概述 随着中心的代码规范的建立和实施,项目组对代码规范要求,以及软件工程师们对自身代码的编写规范重要性的认知,“代码规范”已经成为了中心的一个“热词”.然后怎么才能写出有规范的代码,怎么才能养成 ...
- 未能加载文件或程序集“Autofac, Version=3.4.0.0,
遇到这个错误的时候:如下图 未能加载文件或程序集“Autofac, Version=3.4.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da” ...