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 相关文章推荐
js对象与打印对象分析比较
Apr 23 Javascript
jquery easyui中treegrid用法的简单实例
Feb 18 Javascript
给angular加上动画效遇到的问题总结
Feb 17 Javascript
javaScript事件机制兼容【详细整理】
Jul 23 Javascript
强大Vue.js组件浅析
Sep 12 Javascript
bootstrap table实现x-editable的行单元格编辑及解决数据Empty和支持多样式问题
Aug 10 Javascript
webpack+vue2构建vue项目骨架的方法
Jan 09 Javascript
基于Vuejs的搜索匹配功能实现方法
Mar 03 Javascript
浅谈React Event实现原理
Sep 20 Javascript
javascript浅层克隆、深度克隆对比及实例解析
Feb 09 Javascript
怎么理解wx.navigateTo的events参数使用详情
May 18 Javascript
基于redis的小程序登录实现方法流程分析
May 25 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
从C/C++迁移到PHP——判断字符类型的函数
2006/10/09 PHP
解析phpstorm + xdebug 远程断点调试
2013/06/20 PHP
使用php验证复选框有效性的示例
2013/11/13 PHP
ThinkPHP的URL重写问题
2014/06/22 PHP
Yii框架关联查询with用法分析
2014/12/02 PHP
php实现的验证码文件类实例
2015/06/18 PHP
PHP实现生成推广海报的方法详解
2018/03/14 PHP
Jquery在IE7下无法使用 $.ajax解决方法
2009/11/11 Javascript
(jQuery,mootools,dojo)使用适合自己的编程别名命名
2010/09/14 Javascript
解决jQuery动态获取手机屏幕高和宽的问题
2014/05/07 Javascript
javascript实现完美拖拽效果
2015/05/06 Javascript
jQuery 特性操作详解及实例代码
2016/09/29 Javascript
JS正则表达式判断有效数实例代码
2017/03/13 Javascript
JavaScrpt判断一个数是否是质数的实例代码
2017/06/11 Javascript
vue项目中使用lib-flexible解决移动端适配的问题解决
2018/08/23 Javascript
[52:57]2014 DOTA2国际邀请赛中国区预选赛 LGD-CDEC VS HGT
2014/05/21 DOTA
python多线程之事件Event的使用详解
2018/04/27 Python
Python中交换两个元素的实现方法
2018/06/29 Python
python连接mongodb密码认证实例
2018/10/16 Python
解决在Python编辑器pycharm中程序run正常debug错误的问题
2019/01/17 Python
Python读取指定日期邮件的实例
2019/02/01 Python
浅谈python3.6的tkinter运行问题
2019/02/22 Python
Python3内置模块之json编解码方法小结【推荐】
2020/12/09 Python
详解pandas删除缺失数据(pd.dropna()方法)
2019/06/25 Python
Python 切分数组实例解析
2019/11/07 Python
python 实现socket服务端并发的四种方式
2020/12/14 Python
如何利用python 读取配置文件
2021/01/06 Python
美国隐形眼镜零售商:LensPure
2019/03/10 全球购物
2013年最新自荐信范文
2014/06/23 职场文书
中学生打架检讨书
2014/10/13 职场文书
2015年护士节活动策划方案
2015/05/04 职场文书
联谊活动总结范文
2015/05/09 职场文书
乡镇科协工作总结2015
2015/05/19 职场文书
2019大学生预备党员转正思想汇报
2019/06/21 职场文书
nginx 反向代理之 proxy_pass的实现
2021/03/31 Servers
健身房被搭讪?用python写了个小米计时器助人为乐
2021/06/08 Python