javascript 连等赋值问题(这是从SegmentFault转过来的一个问题)
var a = {n:1};
var b = a; // 持有a,以回查
a.x = a = {n:2};
alert(a.x);// --> undefined
alert(b.x);// --> {n:2}
对于这段代码,大部分人的理解是这样的:========错误的理解=======
对于 a.x = a = {n:2},大部分人的思路应该是:
- 先把
{n:2}赋值给 a - 然后再创建 a.x,将
{n:2}再赋值给 a.x
这样似乎确实说不通 a.x 的值是 undefined,因为 a.x 确实是被赋值了的啊。
可是事实上,a.x 的值却是 undefined。
再来看一下这个: a = a.x = {n:2}的话,按原先的思路应该是:
- 先把
{n:2}赋值给 a.x,那么也就相当于b.x = {n:2}啦 - 再把 a 重新指向
{n:2}。那么这是后 a.x 的值确实是 undefined,a 对象{n:2}中就没有 x 属性嘛。
按这个思路,上述两种方式的结果应该是不同的。但事实却是a = a.x = {n:2}和a.x = a = {n:2}的结果是一致的。所以很明显这个思路不对。
===========================正确的理解是这样的===================
解析器在接受到 a = a.x = {n:2} 这样的语句后,会这样做:
- 找到 a 和 a.x 的指针。如果已有指针,那么不改变它。如果没有指针,即那个变量还没被申明,那么就创建它,指向 null。
a 是有指针的,指向{n:1};a.x 是没有指针的,所以创建它,指向 null。 - 然后把上面找到的指针,都指向最右侧赋的那个值,即
{n:2}。
所以执行以后,就有了如下的变量关系图。大家可以慢慢体会下,想通了就很简单的。

如果大家觉得这种理解比较难,可以先按下面一种方式理解,等理解了再过来看看上面的解释
赋值是从右到左的,但不要被绕晕了, 其实很简单,从运算符优先级来考虑
a.x = a = {n:2};
.运算优先于=赋值运算,因此此处赋值可理解为
- 声明a对象中的x属性,用于赋值,此时b指向a,同时拥有未赋值的x属性
- 对a对象赋值,此时变量名a改变指向到对象{n:2}
- 对步骤1中x属性,也即a原指向对象的x属性,也即b指向对象的x属性赋值
赋值结果:
a => {n: 2}
b => {n: 1, x: {n: 2 } }
javascript 连等赋值问题(这是从SegmentFault转过来的一个问题)的更多相关文章
- ajax实现给JavaScript中全局变量赋值(转)
原文地址:ajax实现给JavaScript中全局变量赋值 问题简化: <script type="text/javascript"> var a=1 ; functi ...
- JavaScript解构赋值
JavaScript解构赋值 JavaScript解构赋值为我们提供了很多方便,但是用法比较多,本文就来梳理一下.总体来说,主要就两种地方使用解构赋值,一种是数组的解构赋值,另一种是对象的解构赋值.以 ...
- javascript对象引用与赋值
avascript对象引用与赋值 <script type="text/javascript"> //例子一: 引用 var myArrayRef = new Arra ...
- JavaScript连等赋值
最近探究js原理的过程中遇到了这个挺有趣的问题. 先贴代码: var a = {n:1} a.x = a = {n:2} alert(a.x) //undefined 在弄懂这个之前,我们先普及一个知 ...
- javascript给输入框赋值的一个误区
一. 错误的示范 如下代码所示,如果需要用javascript获取id为username1, password1的输入框的值,将其写入id为username2, password2的输入框,那么红线区 ...
- JavaScript的算数,赋值,比较和逻辑运算符
类似a=1+1这样的表达式称为运算符,js的运算符分为算数,赋值,比较和逻辑运算符:常见的算数有:+ - * / %(加减乘除,取模),比方说5/4=4*1+1:5%4=1,js算数顺序:从左往右,先 ...
- JavaScript对象属性赋值操作的逻辑
对象进行属性赋值操作时,其执行逻辑如下所示: 1. 当前对象中是否有该属性?有,进行赋值操作:没有,进行下一步判断. 2. 对象的原型链中是否有该属性?没有,在当前对象上创建该属性,并赋值:有,进行下 ...
- javascript 连等赋值问题
var a = {n:1}; var b = a; // 持有a,以回查 a.x = a = {n:2}; alert(a.x);// --> undefined alert(b.x);// - ...
- JavaScript 将多个引用(样式或者脚本)放入一个文件进行引用
1.将样式放入一个文件进行引用 @import url("../media/css/bootstrap.min.css"); @import url("../media/ ...
随机推荐
- Linux小技巧总结
1.fdisk创建磁盘分区不重启系统partprobe 使用fdisk工具只是将分区信息写到磁盘,如果需要mkfs磁盘分区则需要重启系统才能够读取到/dev/sda*,而使用partprobe则可以使 ...
- C++STL - vector
对vector进行一些总结. 一些需要注意的知识点: 1.标准库vector表示对象的集合, 其中所有对象的类型都相同.因为vector中容纳着其他对象,所以也称作容器. 2.C++语言既有类模板(c ...
- 描述Linux shell中单引号,双引号及不加引号的简单区别(计时2分钟)
简要总结: 单引号: 可以说是所见即所得:即将单引号内的内容原样输出,或者描述为单引号里面看到的是什么就会输出什么. 双引号: 把双引号内的内容输出出来:如果内容中有命令.变量等,会先把变量.命令解析 ...
- Linux 下从头再走 GTK+-3.0 (一)
原本由于项目需求在 Linux 下学习过一段时间的 GTK+2.0 图形开发,时隔一段时间,想真正深入学习一下 GTK . 这次直接从头学习 GTK+-3.0 ,并写下博文便于日后查看,也方便新手入门 ...
- 浅谈输入输出”重定向“——基于Linux系统
前言 进程在启动后会自动的打开3个文件:标准输入.标准输出和标准错误输出分别对应文件描述符0.1.2.对于每个进程他们都都维护了一张文件描述符表(file descriptor table),通常fd ...
- Flex 布局教程:语法篇[转]
网页布局(layout)是CSS的一个重点应用. 布局的传统解决方案,基于盒状模型,依赖 display属性 + position属性 + float属性.它对于那些特殊布局非常不方便,比如,垂直居中 ...
- HttpURLConnection用法详解
针对JDK中的URLConnection连接Servlet的问题,网上有虽然有所涉及,但是只是说明了某一个或几个问题,是以FAQ的方式来解决的,而且比较零散,现在对这个类的使用就本人在项目中的使用经验 ...
- POJ3321Apple Tree[树转序列 BIT]
Apple Tree Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 26995 Accepted: 8007 Descr ...
- 通过Hander进行界面刷新
Timer timer; TimerTask task; Handler handler;//先声明这3个变量 //在onCreate方法内 handler = new Handler(){ @Ove ...
- zkw线段树详解
转载自:http://blog.csdn.net/qq_18455665/article/details/50989113 前言 首先说说出处: 清华大学 张昆玮(zkw) - ppt <统计的 ...