原文链接:https://www.cnblogs.com/joesbell/p/6229423.html

<script>
var a = {n:1};
var b = a;
a.x = a = {n:2};
console.log(a.x);// --> undefined
console.log(b.x);// --> [object Object]
</script>

上面的例子看似简单,但结果并不好了解,很容易把人们给想绕了——“a.x不是指向对象a了么?为啥log(a.x)是undefined?”、“b.x不是应该跟a.x是一样的么?为啥log出来居然有2个对象”

当然各位可以先自行理解一下,若能看出其中的原因和工作机理自然就无须继续往下看啦。

下面来分析下这段简单代码的工作步骤,从而进一步理解js引用类型“赋值”的工作方式。

首先是

var a = {n:1};  
var b = a;

在这里a指向了一个对象{n:1}(我们姑且称它为对象A),b指向了a所指向的对象,也就是说,在这时候a和b都是指向对象A的:

这一步很好理解,接着继续看下一行非常重要的代码:

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

我们知道js的赋值运算顺序永远都是从右往左的,不过由于“.”是优先级最高的运算符,所以这行代码先“计算”了a.x。

这时候发生了这个事情——a指向的对象{n:1}新增了属性x(虽然这个x是undefined的):

从图上可以看到,由于b跟a一样是指向对象A的,要表示A的x属性除了用a.x,自然也可以使用b.x来表示了。

接着,依循“从右往左”的赋值运算顺序先执行 a={n:2} ,这时候,a指向的对象发生了改变,变成了新对象{n:2}(我们称为对象B):

接着继续执行 a.x=a,很多人会认为这里是“对象B也新增了一个属性x,并指向对象B自己”

但实际上并非如此,由于( .  运算符最先计算)一开始js已经先计算了a.x,便已经解析了这个a.x是对象A的x,所以在同一条公式的情况下再回来给a.x赋值,也不会说重新解析这个a.x为对象B的x。

所以 a.x=a 应理解为对象A的属性x指向了对象B:

那么这时候结果就显而易见了。当console.log(a.x)的时候,a是指向对象B的,但对象B没有属性x。没关系,当查找一个对象的属性时,JavaScript 会向上遍历原型链,直到找到给定名称的属性为止。但当查找到达原型链的顶部 - 也就是 Object.prototype - 仍然没有找到指定的属性B.prototype.x,自然也就输出undefined;

而在console.log(b.x)的时候,由于b.x表示对象A的x属性,该属性是指向对象B,自然也输出了[object Object]了,注意这里的[object Object]可不是2个对象的意思,对象的字符串形式,是隐式调用了Object对象的toString()方法,形式是:"[object Object]"。所以[object Object]表示的就只是一个对象罢了:)

一道JS 连续赋值运算的问题的更多相关文章

  1. js连续赋值,你理解了吗

    看一道有意思的题,也许你会自信满满地写下答案,会是正确的吗? }; var b = a; a.x = a = {n: }; console.log('a',a); console.log('b',b) ...

  2. new与属性访问的顺序,从一道JS面试题说起

    这段时间一直在研究设计模式,在看工厂模式的时候,看到一段代码 VehicleFactory.prototype.createVehicle = function ( options ) { if( o ...

  3. js赋值运算的理解

    简介 js引擎由于为了效率,很多时候的非直接量赋值都不是copy一份在赋值给新的变量,而是一个引用 ps:直接量:直接值数字字符串等 为什么使用len = doms.length; 里的len效率要比 ...

  4. 那晚征服的一道js经典的面试题

    今天朋友共享了一道js中经典的面试题,需求是这样的 给定你任意一个字符串,让你写出一个算法,求算出该字符串中出现次数最多的一个字符,并将其结果输出 刚拿到这道题的第一感觉便是定义一个count计时器, ...

  5. JS浮点数运算Bug

    JS浮点数运算Bug的解决办法(转) 37.5*5.5=206.08 (JS算出来是这样的一个结果,我四舍五入取两位小数) 我先怀疑是四舍五入的问题,就直接用JS算了一个结果为:206.0849999 ...

  6. 一道js题

    <script> var a = 5; function test(){ this.a = 10; a = 15 this.func = function(){ var a = 20 ; ...

  7. 写了12年JS也未必全了解的连续赋值运算

    引子 var a = {n:1}; var b = a; // 持有a,以回查 a.x = a = {n:2}; alert(a.x);// --> undefined alert(b.x);/ ...

  8. 一道JS面试题引发的血案

    刚入职新公司,属于公司萌新一枚,一天下午对着屏幕看代码架构时. BI项目组长给我看了一道面试别人的JS面试题. 虽然答对了,但把理由说错了,照样不及格. 话不多说,直接上题: var a = 1; s ...

  9. 一道js面试题看变量的作用域

    [问题]分别求下面程序的输出结果: 1. <script type="text/javascript"> var a = 10; sayHi(); function s ...

随机推荐

  1. GTK主题黑边问题

    Linux就是这样,上游一出点什么奇怪的变动,下游程序就要受影响..最近滚了一下后,不知道mesa还是xf86-intel-video哪个玩了什么新花样,所有gtk应用[主要是gnome组件]全部自带 ...

  2. 用source语句引用mysql文件的细节注意

    今天在使用 mysql数据库的时候,创建 数据表的时候出现了很多的小问题,今天一天花费了大量的时间去解决这些问题.首先就是一些小的细节,在文本编辑器上编辑好了SQL语句,然后转移到mysql的命令行中 ...

  3. 为什么C++没有对应realloc的new操作符呢?

    http://blog.csdn.net/rabbit729/article/details/3400260 这个用memcpy明显是有问题的.如果类有资源分配的话,直接memcpy不能复制资源,会导 ...

  4. jquery的遍历选择器-随机整理下

    我从w3c上截了一张图,如图所示: 下面我们来详细说一说.这些选择器. 1.add() 方法将元素添加到匹配元素的集合中.例子: .add(selector) $("div").a ...

  5. java语言编写杨辉三角

    package com.llh.demo; /** * 杨辉三角 * * @author llh * */ public class Test { /* * 杨辉三角 */ public static ...

  6. Coursera上视频无法播放将怎么解决?

    相信很多朋友在播放Coursera中的视频都会遇到一个问题,视频全黑,点击播放,进度条转了一圈又消失不见. 这时候我们该找找是什么问题啦? 解决方法一: 如果你是FQ看的网课视频,那么你把VPN从au ...

  7. C++11 static_assert

    C++11 static_assert C++0x中引入了static_assert这个关键字,用来做编译期间的断言,因此叫做静态断言. 其语法:static_assert(常量表达式,提示字符串). ...

  8. Codeforces 378B. Parade

    B. Parade time limit per test 1 second memory limit per test 256 megabytes input standard input outp ...

  9. struts2框架的登录制作

    首先:我们要建一个web项目 接着: 我们先来导入struts的xml文件 第一步:右击你的项目名,鼠标到MyEclipse会看到一个add struts开头的文件,点开以后看到: 这里我们选择str ...

  10. 玩转 HTML5 下 WebGL 的 3D 模型交并补

    建设性的立体几何具有许多实际用途,它用于需要简单几何对象的情况下,或者数学精度很重要的地方,几乎所有的工程 CAD 软件包都使用 CSG(可以用于表示刀具切削,以及零件必须配合在一起的特征).CSG ...