写了10年的Javascript也未必全了解的连续赋值运算


Posted in Javascript onMarch 25, 2011

一、引子

var a = {n:1}; 
a.x = a = {n:2}; 
alert(a.x); // --> undefined

这是蔡蔡在看 jQuery源码 时发现这种写法的。以上第二句 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:1}; 
var b = a; // 暂存a 
a.x = a = {n:2}; 
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}。
1, a = {n:2};
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:2};

a.x 中的a指向的是 {n:1},a 指向的是 {n:2}。如下图

写了10年的Javascript也未必全了解的连续赋值运算
四:解惑

这篇写完,或许部分人看完还是晕晕的。因为里面的文字描述实在是绕口。最初我在理解这个连等赋值语句时

var a = {n:1}; 
a.x = a = {n:2};

认为引擎会限制a.x的重写(a被重写后),实际却不是这样的。指向的对象已经不同了。引擎也没有限制a.x={n:2}的重写。
谢谢所有参与讨论的人:蔡蔡、呆呆、儒儒。这个问题最早是蔡蔡提出的。儒儒在 菜鸟灰呀灰 群里每次的讨论都那么投入,认真,哪怕是别人提出的话题。

五:结束

呵,以另一个连续赋值题结束。fun执行后,这里的 变量 b 溢出到fun外成为了全局变量。想到了吗?

function fun(){ 
var a = b = 5; 
} 
fun(); 
alert(typeof a); // --> undefined 
alert(typeof b); // --> number
Javascript 相关文章推荐
js post方式传递提交的实现代码
May 31 Javascript
同时使用n个window onload加载实例介绍
Apr 25 Javascript
node.js中实现同步操作的3种实现方法
Dec 05 Javascript
JavaScript使用DeviceOne开发实战(四)仿优酷视频应用
Dec 02 Javascript
用JS实现轮播图效果(二)
Jun 26 Javascript
bootstrap Table的一些小操作
Nov 01 Javascript
JS实现图片上传多次上传同一张不生效的处理方法
Aug 06 Javascript
使用Vue CLI创建typescript项目的方法
Aug 09 Javascript
vue实现扫码功能
Jan 17 Javascript
viewer.js一个强大的基于jQuery的图像查看插件(支持旋转、缩放)
Apr 01 jQuery
vue 弹出遮罩层样式实例
Jul 22 Javascript
详解Vue 的异常处理机制
Nov 30 Vue.js
js 实现图片预加载(js操作 Image对象属性complete ,事件onload 异步加载图片)
Mar 25 #Javascript
基于jquery的3d效果实现代码
Mar 23 #Javascript
jquery 操作表格实现代码(多种操作打包)
Mar 20 #Javascript
jQuery实现的Email中的收件人效果(按del键删除)
Mar 20 #Javascript
jquery图片上下tab切换效果
Mar 18 #Javascript
javascript一些实用技巧小结
Mar 18 #Javascript
jquery获取下拉列表的值为null的解决方法
Mar 18 #Javascript
You might like
PHP+jquery+ajax实现即时聊天功能实例
2014/12/23 PHP
PHP观察者模式示例【Laravel框架中有用到】
2018/06/15 PHP
js固定DIV高度,超出部分自动添加滚动条的简单方法
2013/07/10 Javascript
js 窗口抖动示例
2013/09/04 Javascript
jQuery判断元素是否存在的可靠方法
2014/05/06 Javascript
深入理解JavaScript中的对象
2015/06/04 Javascript
Jquery1.9.1源码分析系列(六)延时对象应用之jQuery.ready
2015/11/24 Javascript
详解JavaScript的另类写法
2016/04/11 Javascript
JS中sort函数排序用法实例分析
2016/06/16 Javascript
微信JSAPI支付操作需要注意的细节
2017/01/10 Javascript
JS验证字符串功能
2017/02/22 Javascript
通过实例解析chrome如何在mac环境中安装vue-devtools插件
2020/07/10 Javascript
python实现简单的socket server实例
2015/04/29 Python
python获取程序执行文件路径的方法(推荐)
2018/04/26 Python
解决Python print输出不换行没空格的问题
2018/11/14 Python
基于Python实现用户管理系统
2019/02/26 Python
python内存监控工具memory_profiler和guppy的用法详解
2019/07/29 Python
基于Numba提高python运行效率过程解析
2020/03/02 Python
python 数据分析实现长宽格式的转换
2020/05/18 Python
keras训练曲线,混淆矩阵,CNN层输出可视化实例
2020/06/15 Python
优秀中专生推荐信
2013/11/17 职场文书
兼职学生的自我评价
2013/11/24 职场文书
毕业生的求职信范文分享
2013/12/04 职场文书
运动会广播稿60字
2014/01/15 职场文书
第一批党的群众路线教育实践活动工作总结
2014/03/03 职场文书
汽车促销活动方案
2014/03/31 职场文书
满月酒邀请函
2015/01/30 职场文书
总经理岗位职责范本
2015/04/01 职场文书
幼儿园教研工作总结2015
2015/05/12 职场文书
2015年小学师德师风建设工作总结
2015/10/23 职场文书
《日月潭》教学反思
2016/02/20 职场文书
会计专业2019暑假实习报告
2019/06/21 职场文书
PHP基本语法
2021/03/31 PHP
Vue.js中v-for指令的用法介绍
2022/03/13 Vue.js
详细介绍Java中的CyclicBarrier
2022/04/13 Java/Android
Win11 Beta 22621.601 和 22622.601今日发布 KB5017384修复内容汇总
2022/09/23 数码科技