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/ ...
随机推荐
- QT5.5.0版本添加icon图标步骤
1.制作icon图标文件 可以进入这个网站在线制作:http://www.ico.la/ 2.创建资源文件:qrc文件 接着 添加2两项,先点击prefix,然后添加文件--->图标路径 3.可 ...
- proteus 运行出错,用户名不可使用中文!
仿真的时候提示如图提示 cannot open ’c\user\小名\AppData\local\temp\LISA0089.sdf’ 系统用户名不能是中文! 解决办法:重新建立个账户,记得用英文命名 ...
- Fitbit Flex 智能手环佩戴心得 主要说说过敏
参杂一篇杂文. 也是因为体重飙升,所以去年下半年的时候入手了一个Fitbit flex. 当时相比Jawbone up,nfc和ble的特性,以及防水性还是更吸引我一点.所以就入手了. 佩带了如此长的 ...
- checkbox勾选判断
var xieYi=document.getElementById("xieYi"); if(!xieYi.checked){ alert("请先阅读并勾选购买协议!&q ...
- c++实现矩阵类矩阵行列式,伴随矩阵,逆矩阵
//Matrix ver1.0 //只支持矩阵内部(方阵)的运算 #include<iostream> #include<math.h> using namespace std ...
- Codeforces 549C. The Game Of Parity[博弈论]
C. The Game Of Parity time limit per test 1 second memory limit per test 256 megabytes input standar ...
- POJ3211 Washing Clothes[DP 分解 01背包可行性]
Washing Clothes Time Limit: 1000MS Memory Limit: 131072K Total Submissions: 9707 Accepted: 3114 ...
- [No00003F]richtextbox实现拖放
namespace WindowsFormsApplication1 { public partial class Form1 : Form { public Form1() { Initialize ...
- android 下载文件
import com.example.android.R; import android.app.Activity;import android.os.Bundle;import android.os ...
- Xcode 编译的哪些错误
1.error: macro names must be identifiers YourProject_prefix.pch 原因: 因为你弄脏了预处理器宏,在它处于<Multiple Val ...