javascript中基本类型和引用类型的区别分析


Posted in Javascript onMay 12, 2015

基本类型和引用类型

ECMAScript包含两个不同类型的值:基本类型值和引用类型值。基本类型值指的是简单的数据段;引用类型值指由多个值构成的对象。当我们把变量赋值给一个变量时,解析器首先要做的就是确认这个值是基本类型值还是引用类型值。

常见的五种基本数据类型是:

Undifined、Null、Boolean、Number和String。这五种基本数据类型可以直接操作保存在变量中的实际值。

看下面例子:

var a = 10;
var b = a;
   b = 20;
console.log(a); // 10
    
var bl = true;
var bl1 = bl;
   bl1 = false;
console.log(bl); // true

上面,b获取值是a值的一份拷贝,虽然,两个变量的值是相等,但是两个变量保存两不同的基本数据类型值。b只是保存了a复制的一个副本。所以,当b的值改变时,a的值依然是10;
下面,两个Boolean变量bl和bl1同样是基本数据类型,同样保存两个不同的基本数据据类型值,bl1保存bl复制的一个副本。

下图演示了这种基本数据类型赋值的过程:

javascript中基本类型和引用类型的区别分析

下面看一下引用类型数据:

javascript引用数据类型是保存在堆内存中的对象,与其它语言不同的是,你不可以直接访问堆内存空间中的位置和操作堆内存空间。只能通过操作对象的在栈内存中的引用地址。所以引用类型的数据,在栈内存中保存的实际上是对象在堆内存中的引用地址。通过这个引用地址可以快速查找到保存在堆内存中的对象。

看下下面的例子:

var obj1 = new Object();
var obj2 = obj1;
obj2.name = "我有名字了";
console.log(obj1.name); // 我有名字了

由上面例子,我们声明了一个引用数据类型变量obj1,并把它赋值给了另外一个引用数据类型变量obj2。当我们obj2添加了一个name属性并赋值"我有名字了"。obj1同样拥有了和obj2一样的name属性。说明这两个引用数据类型变量指向同一个堆内存对象。obj1赋值给obj2,实际只是把这个堆内存对象在栈内存的引用地址复制了一份给了obj2,但它们本质上共同指向了同一个堆内存对象。

下面我们来演示这个引用数据类型赋值过程:

javascript中基本类型和引用类型的区别分析

自然,给obj2添加name属性,实际上是给堆内存中的对象添加了name属性,obj2和obj1在栈内存中保存的只是堆内存对象的引用地址,虽然也是拷贝了一份,但指向的对象却是同一个。故而改变obj2引起了obj1的改变。

 一般而言,基本数据类型是有固定数目的字节组成,这些字节可以在解析器的较底层进行操作比如Number和Boolean;而引用数据类型,可以包含任意数目的属性和元素,因此它们无法像基本数据类型那样很容易的操作。由于,引用数据类型的值是会发生变化的,所以通过跟基本数据类型一样的值传递方式,也就没什么意义了,因为会牵涉到大量的内存的复制和比较,效率太低。所以引用数据类型是通过引用传递方式,实际传递的只是对象的一个地址。比如Array和Function因为它们都是特殊的对象所以它都是引用类型。另外,引用类型是可以添加属性,基本类型虽然也可以添加属性,也不会报错,经测试添加完之后却是无法访问的。

看下面代码:

var a = 12;
 a.name = "myname";
console.log(a.name); // undefined

 String一个特殊的基本数据类型

在很多语言中,String是以对象的形式表示的,但在ECMAScript里没有沿用这种传统,String是当作一种基本数据类型,但它是一个比较特殊的基本类型。

看上去好像String应该做为一个引用类型,可实际上它不是,因为它不是对象。那么看起来它应该是基本数据类型,应该是通值传递的方式来操作。

看下面例子:

var stra = "这是一个字符串";
var strb = stra;
   stra = "这是另外一个字符串";
console.log(strb); // 这是一个字符串

 上面例子我们看到,仿佛stra通过值传递的方式复制了一份给了strb。当stra改变的时候,strb并没有改变,似乎我们已经可以下结论,String就是个基本数据类型。

可是,因为String是可以任意长度的,通过值传递,一个一个的复制字节显示效率依然很低,看起来String也可以当作引用类型。

看下面例子:

var a = "myobject";
  a.name = "myname";
console.log(a.name); // undefined

显示String无法当作一个对象来处理。实际上,javascript里的String是不可以改变的,javascript也没有提供任何一个改变字符串的方法和语法。

var a = "myobject";
  a = a.substring(3,5)
  console.log(a); // bj

记住这样做,就没有改变String字符串"myobject",只a引用了另一个字符串"bj","myobject"被回收了。

所以可以这样讲,String实际上并不符合上面两种数据类型分类。它是具有两方面属性介于两都之间的一种特殊类型。

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

Javascript 相关文章推荐
JavaScript中去掉数组中的重复值的实现方法
Aug 03 Javascript
提升PHP安全:8个必须修改的PHP默认配置
Nov 17 Javascript
Jquery操作cookie记住用户名
Mar 29 Javascript
jQuery实现鼠标选文字发新浪微博的方法
Apr 02 Javascript
jQuery实现响应鼠标事件的图片透明效果【附demo源码下载】
Jun 16 Javascript
浅谈javascript:两种注释,声明变量,定义函数
Oct 05 Javascript
AngularJS路由Ui-router模块用法示例
May 29 Javascript
使用百度地图实现地图网格的示例
Feb 06 Javascript
VUE搭建手机商城心得和遇到的坑
Feb 21 Javascript
javascript删除数组元素的七个方法示例
Sep 09 Javascript
使用layui实现树形结构的方法
Sep 20 Javascript
js实现双色球效果
Aug 02 Javascript
JavaScript模拟可展开、拖动与关闭的聊天窗口实例
May 12 #Javascript
Javascript中typeof 用法小结
May 12 #Javascript
js/jquery判断浏览器类型的方法小结
May 12 #Javascript
js实现div层缓慢收缩与展开的方法
May 11 #Javascript
JS实现定时自动关闭DIV层提示框的方法
May 11 #Javascript
最精简的JavaScript实现鼠标拖动效果的方法
May 11 #Javascript
JavaScript实现表格点击排序的方法
May 11 #Javascript
You might like
PHP根据IP判断地区名信息的示例代码
2014/03/03 PHP
php类中的各种拦截器用法分析
2014/11/03 PHP
Yii2.0建立公共方法简单示例
2019/01/29 PHP
extjs 为某个事件设置拦截器
2010/01/15 Javascript
JS获取屏幕,浏览器窗口大小,网页高度宽度(实现代码)
2013/12/17 Javascript
JavaScript日期时间格式化函数分享
2014/05/05 Javascript
js中使用replace方法完成某个字符的转换
2014/08/20 Javascript
原生javascript获取元素样式
2014/12/31 Javascript
js使用onmousemove和onmouseout获取鼠标坐标的方法
2015/03/31 Javascript
利用jQuery及AJAX技术定时更新GridView的某一列数据
2015/12/04 Javascript
详解js跨域原理以及2种解决方案
2015/12/09 Javascript
js实现分割上传大文件
2016/03/09 Javascript
bootstrap datetimepicker2.3.11时间插件使用
2016/11/19 Javascript
微信小程序 在线支付功能的实现
2017/03/14 Javascript
javascript 中的继承实例详解
2017/05/05 Javascript
详解Angular 开发环境搭建
2017/06/22 Javascript
webpack@v4升级踩坑(小结)
2018/10/08 Javascript
使用Node.js写一个代码生成器的方法步骤
2019/05/10 Javascript
vue-router路由模式详解(小结)
2019/08/26 Javascript
在Python3中使用asyncio库进行快速数据抓取的教程
2015/04/02 Python
python开发中range()函数用法实例分析
2015/11/12 Python
用Python将IP地址在整型和字符串之间轻松转换
2017/03/22 Python
python 截取XML中bndbox的坐标中的图像,另存为jpg的实例
2020/03/10 Python
Python文件时间操作步骤代码详解
2020/04/13 Python
完美解决torch.cuda.is_available()一直返回False的玄学方法
2021/02/06 Python
详解通过变换矩阵实现canvas的缩放功能
2019/01/14 HTML / CSS
美国领先的汽车轮胎和轮毂供应商:TireBuyer
2016/07/21 全球购物
阿波罗盒子:Apollo Box
2017/08/14 全球购物
应聘医学检验人员自荐信
2013/09/27 职场文书
法律专业应届生自荐信范文
2014/01/06 职场文书
本科毕业生专业自荐书范文
2014/02/05 职场文书
民政局个人整改措施
2014/09/24 职场文书
小学英语教学随笔
2015/08/14 职场文书
如何让2019年上半年的工作总结更出色!
2019/07/01 职场文书
Redis数据结构之链表与字典的使用
2021/05/11 Redis
Pygame Time时间控制的具体使用详解
2021/11/17 Python