探究JS中的连等赋值问题
一、引子
最近在看别人的博客时无意中看到一个这样的问题
var a = {n: 1};
var b = a;
a.x = a = {n:2};
console.log(a.x); //undefined
console.log(a); // {n: 2}
console.log(b); // {n: 1, x: {n: 2}}
这是一个典型的连等赋值问题,是不是发现打印的结果跟自己预料的不太一样,就算一样你能具体讲出内部的执行机制吗?
二、直观理解
咋一看这个表达式,我会本能地把它拆解为这样
a={n:2};
a.x={n:2};
所以根据这个理解得出的打印结果是
console.log(a.x); //{n: 2}
显然结果是不对的,那问题出在了哪里呢?要想从原理上解释这个问题,还得首先理解以下几个知识点
三、需要理解的知识点
- 内存的的运行机制
- JS引擎的解析过程,从左往右
- 连等赋值的执行方向,从右往左
放在这个例子中对应的理解就是:
- a、b这些变量名存储的只是一串指向具体对象的指针,这些指针占用的空间是非常小的,而{n: 1}这些对象才是实实在在存在内存中的值
- JS引擎在执行到a.x = a = {n:2}这句时,并不是直接的从右往左的执行过程。而是计算机会先从左往右解析各个变量名,转换成变量值(计算机只会记变量值,人的话记变量名)。再从右往左执行赋值。
- 也就是在这个表达式中第一个a和第二个a指向的都是{n: 1};
a.x = a = {n:2}
- 解析完成后,从右往左执行赋值,第二个等号赋值时,a重定向到了{n: 2},第一个等号赋值时,实际上是{n:1}.x={n, 2};
而这个时候指向{a:1, x:{n:2}}这个值的只有b了 - 所以a.x的值就变为了undefined,因为a已经重定向赋值为{n:2}了,而b就指向了复合之后的对象
四、理解中的误区及思考
我最开始查了连等赋值的相关文章时,对于以上这些原理的理解是没什么问题的,关键是在理解最后那个赋值过程时,我有过一种理解
a = {n:2};
a.x={n:2};
// 所以此时a= {n:2, x:{n:2}}
产生这种理解的原因是觉得对a的赋值有个先后顺序,但事实上好像是不存在的。我对上面那种从解析赋值角度去理解的核心就是在连等赋值执行过程中,总共分为两步,一步是变量名解析,一步是赋值,然后根据赋值之后的值去看相应的变量名与变量之间的对应关系。
五、参考文档
探究JS中的连等赋值问题的更多相关文章
- 【转】千万不要在JS中使用连等赋值操作
原文链接 千万不要在JS中使用连等赋值操作 目录 前言 赋值顺序? 连续赋值能拆开写么? 后记 前言 文章标题这句话原本是在国外某JavaScript规范里看到的,当时并没有引起足够的重视,直到最 ...
- 深入探究js中的隐式变量声明
前两天遇到的问题,经过很多网友的深刻讨论,终于有一个相对可以解释的通的逻辑了,然后我仔细研究了一下相关的点,顺带研究了一下js中的隐式变量. 以下文章中提到的隐式变量都是指没有用var,let,con ...
- 千万不要在JS中使用连等赋值操作
前言 文章标题这句话原本是在国外某JavaScript规范里看到的,当时并没有引起足够的重视,直到最近一次出现了bug发现JS里的连等赋值操作的特色(坑). 网上搜索一番发现一个非常好的连等赋值的(来 ...
- 深入探究js中无所不在的this
黄金守则: this对象是在运行时基于函数的执行环境绑定的:在全局函数中,this等于window而当函数被作为某个对象的方法调用时, this等于那个对象. 下面是一些相关实践: --------- ...
- 探究JS中对象的深拷贝和浅拷贝
深拷贝和浅拷贝的区别 在讲深拷贝和浅拷贝的区别之前,回想一下我们平时拷贝一个对象时是怎么操作的?是不是像这样? var testObj1 = {a: 1, b:2}, testObj2=testObj ...
- JS中数组初始化以及赋值
.指定长度,然后初始化 ); ;index < ;index++){ vArray[index] = index; } 2.不指定长度,然后初始化 var vArray = new Array( ...
- js 中的基本类型和引用类型的区别
js中的基本类型赋值之后,只有值相等的时候,二者才会相等,例如 var a='123'; var b=a; console.log(a===b); 返回的是true ,说明他们是相等的, 此时改变a ...
- js中的offsetLeft和style.left
(1)style.left是带单位"px"的,而offsetLeft没有单位,另外,style.left必须是内联样式,或者在JS中通过style.left赋值,否则取得的将为空字 ...
- 二、js中基础知识
该篇文章主要是强化一下自己javaScript的基础,让写代码变得更轻松些.基础好的请忽略. JavaScript一种直译式脚本语言,是一种动态类型.弱类型.基于原型的语言,内置支持类型.它的解 ...
随机推荐
- C#:对含有中文的字符串进行MD5加密
MD5CryptoServiceProvider MD5 = new MD5CryptoServiceProvider(); var Sign = BitConverter.ToString(MD5. ...
- Java开发者必备十大学习网站
作为开发者来说,必备的除了对编码的热情还要有自己的一套技巧,另外不可缺少的就是平时学习的网站.以下本人收集的Java开发者必备的网站,这些网站可以提供信息,以及一些很棒的讲座, 还能解答一般问题.面试 ...
- IDEA创建Spring Boot的项目
IDEA创建SpringBoot的项目非常的方便智能,可以实现零配置,只需要在创建的时候勾选你需要的功能,比如mybatis,mysql等等,它会帮你自动下载导入响应的jar,不用自己再去手动填写. ...
- jQuery判断元素是否显示 是否隐藏
var node=$('#id'); 第一种写法 if(node.is(':hidden')){ //如果node是隐藏的则显示node元素,否则隐藏 node.show(); }else{ node ...
- 20145328 《Java程序设计》第0周学习总结
20145328 <Java程序设计>第0周学习总结 阅读心得 从总体上来说,这几篇文章都是围绕着软件工程专业的一些现象来进行描述的,但深入了解之后就可以发现,无论是软件工程专业还是我们现 ...
- 探讨"点"语法的奥秘
点语法 一直以来,都不理解什么是点语法,都说是相当于链接或是路径.也许我浏览的信息量少吧,看过好几篇有关的博文,没什么记载,本篇只是初步见解分析. 在javascript里,属性和方法都使用“点”语法 ...
- JavaScript的this指针到底指向哪?
编程过程中,着实十分困扰this的指向性,经过查阅一番资料,终于搞清楚了,在这里总结一下,全文分为以下三个部分: 什么是this指针? this指针指向哪里? 何时使用this? 一 什么是this指 ...
- bzoj 1691: [Usaco2007 Dec]挑剔的美食家
Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 621 Solved: 280[Submit][Status][Discuss] Description ...
- 如何调试ubifs文件系统
注意内核版本为4.9 在drivers/mtd/ubi/debug.h中加入DEBUG的定义,如下 #ifndef __UBI_DEBUG_H__#define __UBI_DEBUG_H__#def ...
- linux环境变量 export命令详解
由host $ export DVSDK="${HOME}/ti-dvsdk_dm368-evm_xx_xx_xx_xx"引发的问题 1.${HOME}:首先, HOME 是个变量 ...