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

先看个例子:

 <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]表示的就只是一个对象罢了

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

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索javascript
引用类型
指针类型的引用、值类型不需要指针引用、c 指针 指向引用类型、javascript 引用类型、javascript的引用类型,以便于您获取更多的相关知识。

时间: 2024-10-30 05:49:32

javascript引用类型指针的工作方式_javascript技巧的相关文章

实例分析浏览器中“JavaScript解析器”的工作原理_javascript技巧

浏览器在读取HTML文件的时候,只有当遇到<script>标签的时候,才会唤醒所谓的"JavaScript解析器"开始工作. JavaScript解析器工作步骤: 1."找一些东西": var. function. 参数:(也被称之为预解析) 备注:如果遇到重名分为以下两种情况: 遇到变量和函数重名了,只留下函数 遇到函数重名了,根据代码的上下文顺序,留下最后一个 2.逐行解读代码. 备注:表达式可以修改预解析的值 JS解析器在执行第一步预解析的时候,会

谈一谈javascript中继承的多种方式_javascript技巧

JS 是没有继承的,不过可以曲线救国,利用构造函数.原型等方法实现继承的功能. var o=new Object(); 其实用构造函数实例化一个对象,就是继承,这里可以使用Object中的所有属性与方法.那么为什么能访问Object对象的方法,其实访问的是其原型对象的方法,所有的方法都是放在原型中而不是类中. console.log(o.__proto__ === Object.prototype) // true 继承的本质 console.log(o.__proto__ === Object

javascript 框架小结 个人工作经验_javascript技巧

/**************************************************************************************** 作者:萧 枫 QQ:77182997 MSN:xiaofengnet@hotmail.com Email:xiaofengnet@163.com 网址:http://www.d369.net 请保留版权 谢谢合作 版本:V 1.6.1 /*****************************************

JavaScript是如何实现继承的(六种方式)_javascript技巧

前言:大多OO语言都支持两种继承方式: 接口继承和实现继承 ,而ECMAScript中无法实现接口继承,ECMAScript只支持实现继承,而且其实现继承主要是依靠 原型链 来实现. 1.原型链 基本思想:利用原型让一个引用类型继承另外一个引用类型的属性和方法. 构造函数,原型,实例之间的关系:每个构造函数都有一个原型对象,原型对象包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针. 原型链实现继承例子: function SuperType() { this.property

基于JavaScript如何实现私有成员的语法特征及私有成员的实现方式_javascript技巧

前言 在面向对象的编程范式中,封装都是必不可少的一个概念,而在诸如 Java,C++等传统的面向对象的语言中, 私有成员是实现封装的一个重要途径.但在 JavaScript 中,确没有在语法特性上对私有成员提供支持, 这也使得开发人员使出了各种奇技淫巧去实现 JS 中的私有成员,以下将介绍下目前实现 JS 私有成员特性的几个方案以及它们之间的优缺点对比. 现有的一些实现方案 约定命名方案 约定以下划线'_'开头的成员名作为私有成员,仅允许类成员方法访问调用,外部不得访问私有成员.简单的代码如下:

学习javascript面向对象 掌握创建对象的9种方式_javascript技巧

本文为大家分享了javascript创建对象的9种方式,供大家参考,具体内容如下 [1]使用Object构造函数 [缺点]使用同一个接口创建很多对象,会产生大量重复代码 var person = new Object(); person.name = "Nicholas"; person.age = 29; person.job = "Software Engineer"; person.sayName = function(){ alert(this.name);

浅谈JavaScript中的this指针和引用知识_javascript技巧

this是javascript的一个关键字,随着函数使用场合不同,this的值会发生变化.但是总有一个原则,那就是this指的是调用函数的那个对象. this指针在传统OO语言中,是在类中声明的,表示对象本身.在JavaScript中,this表示当前上下文,即调用者的引用 ********this永远指向的是(函数对象)的所有者 this和全局对象: var a = 1; function foo(){ var b = 2; console.log(this.a+b);//3 } foo();

javascript数组输出的两种方式_javascript技巧

本文实例讲述了javascript数组输出的两种方式.分享给大家供大家参考.具体如下: 遍历javascript数组,两种方式: 第一种: 复制代码 代码如下: <script language="javascript" type="text/javascript"> var str = "how are you today"; var arr = str.split(" "); for(var key in ar

JavaScript 原型继承之构造函数继承_javascript技巧

上回说到<JavaScript 原型继承之基础机制>,这一篇将具体说说构造函数的继承. 从一个简单的示例开始,创建描述人类的 People 构造函数: 复制代码 代码如下: function People(){ this.race = '愚蠢的人类'; } 然后,创建描述黄种人的 Yellow 构造函数: 复制代码 代码如下: function Yellow(name, skin){ this.name = name; this.skin = skin; } 要使得黄种人 Yellow 能继承