javascript引用类型指针的工作方式


Posted in Javascript onApril 13, 2015

先看个例子:

<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的:

javascript引用类型指针的工作方式

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

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

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

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

javascript引用类型指针的工作方式

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

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

javascript引用类型指针的工作方式

接着继续执行 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:

javascript引用类型指针的工作方式

那么这时候结果就显而易见了。当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]表示的就只是一个对象罢了

以上所述就是本文的全部内容了,希望大家能够喜欢。

Javascript 相关文章推荐
用apply让javascript函数仅执行一次的代码
Jun 27 Javascript
控制input输入框中提示信息的显示和隐藏的方法
Feb 12 Javascript
《JavaScript DOM 编程艺术》读书笔记之JavaScript 图片库
Jan 09 Javascript
Node.js中的缓冲与流模块详细介绍
Feb 11 Javascript
Jquery实现简单的轮播效果(代码管用)
Mar 14 Javascript
ros::spin() 和 ros::spinOnce()函数的区别及详解
Oct 01 Javascript
JS常用知识点整理
Jan 21 Javascript
详解React中的组件通信问题
Jul 31 Javascript
解决Vue2.0中使用less给元素添加背景图片出现的问题
Sep 03 Javascript
Vue基于vuex、axios拦截器实现loading效果及axios的安装配置
Apr 26 Javascript
vue App.vue中的公共组件改变值触发其他组件或.vue页面监听
May 31 Javascript
JS实现拖拽元素时与另一元素碰撞检测
Aug 27 Javascript
javascript实现图片自动和可控的轮播切换特效
Apr 13 #Javascript
使用jQuery实现更改默认alert框体
Apr 13 #Javascript
javascript异步处理工作机制详解
Apr 13 #Javascript
JavaScript中DOM详解
Apr 13 #Javascript
js 获取元素在页面上的偏移量的方法汇总
Apr 13 #Javascript
javascript中scrollTop详解
Apr 13 #Javascript
jQuery实现的在线答题功能
Apr 12 #Javascript
You might like
php生成图形(Libchart)实例
2013/11/06 PHP
php实现上传图片文件代码
2015/07/19 PHP
PHP fopen函数用法实例讲解
2019/02/15 PHP
php抽象方法和普通方法的区别点总结
2019/10/13 PHP
thinkphp5 + ajax 使用formdata提交数据(包括文件上传) 后台返回json完整实例
2020/03/02 PHP
javascript真的不难-回顾一下基础知识
2013/01/15 Javascript
实现只能输入数字的input不用replace方法
2013/09/12 Javascript
原生javascript实现无间缝滚动示例
2014/01/28 Javascript
javascript实现简单查找与替换的方法
2015/07/22 Javascript
jquery对所有input type=text的控件赋值实现方法
2016/12/02 Javascript
jqGrid翻页时数据选中丢失问题的解决办法
2017/02/13 Javascript
Vue0.1的过滤代码如何添加到Vue2.0直接使用
2017/08/23 Javascript
基于vue配置axios的方法步骤
2017/11/09 Javascript
JS实现将对象转化为数组的方法分析
2019/01/21 Javascript
Vue.js组件实现选项卡以及切换特效
2019/07/24 Javascript
JS实现的碰撞检测与周期移动完整示例
2019/09/02 Javascript
如何利用javascript接收json信息并进行处理
2020/08/06 Javascript
分享给Python新手们的几道简单练习题
2017/09/21 Python
python3设计模式之简单工厂模式
2017/10/17 Python
Python实现图片滑动式验证识别方法
2017/11/09 Python
python使用selenium实现批量文件下载
2019/03/11 Python
Python零基础入门学习之输入与输出
2019/04/03 Python
python os.path.isfile 的使用误区详解
2019/11/29 Python
使用PyTorch实现MNIST手写体识别代码
2020/01/18 Python
HTML5 canvas画矩形时出现边框样式不一致的解决方法
2013/10/14 HTML / CSS
理肤泉美国官网:La Roche-Posay
2018/01/17 全球购物
生产现场工艺工程师岗位职责
2013/11/28 职场文书
后进生转化工作制度
2014/01/17 职场文书
妇联主席先进事迹
2014/05/18 职场文书
廉政承诺书
2015/01/19 职场文书
英雄儿女观后感
2015/06/09 职场文书
技能培训通讯稿
2015/07/18 职场文书
早上好问候语大全
2015/11/10 职场文书
Python利用机器学习算法实现垃圾邮件的识别
2021/06/28 Python
Ajax实现三级联动效果
2021/10/05 Javascript
Python自动化实战之接口请求的实现
2022/05/30 Python