详解JavaScript基本类型和引用类型


Posted in Javascript onDecember 09, 2015

一、值的类型
       早在介绍JS的数据类型的时候就提到过基本类型和引用类型,不过在说两种类型之前,我们先来了解一下变量的值的类型。在ECMAScript中,变量可以存在两种类型的值,即原始值和引用值。
(1)原始值
       存储在栈中的简单数据段,也就是说,它们的值直接存储在变量访问的位置。
(2)引用值
       存储在堆中的对象,也就是说,存储在变量处的值是一个指针,指向存储对象的内存处。
       为变量赋值时,ECMAScript的解释程序必须判断该值是原始类型,还是引用类型。要实现这一点,解释程序则需尝试判断该值是否为ECMAScript的基本类型之一,即Undefined类型、Null类型、Boolean类型、Number类型和String类型。由于这些基本类型占据的空间是固定的,所以可将他们存储在较小的内存区域 - 栈中。这样存储便于迅速查寻变量的值。
       在许多语言中,字符串都被看作引用类型,而非基本类型,因为字符串的长度是可变的。ECMAScript打破了这一
传统。
       如果一个值是引用类型的,那么它的存储空间将从堆中分配。由于引用值的大小会改变,所以不能把它放在栈中,否则会降低变量查寻的速度。相反,放在变量的栈空间中的值是该对象存储在堆中的地址。地址的大小是固定的,所以把它存储在栈中对变量性能无任何负面影响。如下图所示:

详解JavaScript基本类型和引用类型

二、基本类型
       ECMAScript有5种基本类型,即Undefined类型、Null类型、Boolean类型、Number类型和String类型。ECMA-262把术语类型定义为值的一个集合,每种基本类型定义了它包含的值的范围及其字面量表示形式。
       ECMAScript提供了typeof运算符来判断一个值是否在某种类型的范围内。可以用这种运算符判断一个值是否表示一种基本类型:如果它是基本类型,还可以判断它表示哪种基本类型。
       基本数据类型和操作符typeof我们在前面的博文中也经常使用到。详细了解的话可以参考这篇文章:详解JavaScript的变量和数据类型

三、类型转换
       所有程序设计语言最重要的特征之一是具有进行类型转换的能力。ECMAScript给开发者提供了大量简单的类型转换方法。大部分类型具有进行简单转换的方法,还有几个全局方法可以用于更复杂的转换。无论哪种情况,在ECMAScript中,类型转换都是简短的一步操作。
(1)转换成字符串
       ECMAScript的Boolean值、数字和字符串的原始值的有趣之处在于它们是伪对象,这意味着它们实际上具有属性和方法。
例如,要获得字符串的长度,可以采用下面的代码:

var sbox = "red"; 
document.write(sbox.length);//输出3

       尽管 "red" 是基本类型的字符串,它仍然具有属性length,用于存放字符串的大小。总而言之,3 种主要的原始类型Boolean 值、数字和字符串都有 toString() 方法,可以把它们的值转换成字符串。您也许会问,“字符串还有toString()方法吗,这不是多余吗?”是的,的确如此,不过ECMAScript定义所有对象都有toString()方法,无论它是伪对象,还是真对象。因为String类型属于伪对象,所以它一定有toString()方法。
1)Boolean 类型的toString()方法只是输出 "true" 或 "false",结果由变量的值决定:

var bage=false; 
document.write(bage.toString());//输出"false"

2)Number类型的toString()方法比较特殊,它有两种模式,即默认模式和基模式。采用默认模式,toString()方法只是用相应的字符串输出数字值(无论是整数、浮点数还是科学计数法),在默认模式中,无论最初采用什么表示法声明数字,Number 类型的 toString() 方法返回的都是数字的十进制表示。因此,以八进制或十六进制字面量形式声明的数字输出的都是十进制形式的。如下所示:

var iNum1 = 10; 
var iNum2 = 10.0; 
document.write(iNum1.toString());//输出 "10" 
document.write(iNum2.toString());//输出 "10"

采用Number类型的 toString()方法的基模式,可以用不同的基输出数字,例如二进制的基是2,八进制的基是8,十六进制的基是16。
       基只是要转换成的基数的另一种加法而已,它是 toString() 方法的参数:

var iNum = 10; 
document.write(iNum.toString(2));//输出 "1010" 
document.write(iNum.toString(8));//输出 "12" 
document.write(iNum.toString(16));//输出 "a"

(2)转换成数字
       ECMAScript提供了两种把非数字的原始值转换成数字的方法,即parseInt()和parseFloat()。前者把值转换成整数,后者把值转换成浮点数。只有对String类型调用这些方法,它们才能正确运行;对其他类型返回的都是NaN。
1)parseInt()
       在判断字符串是否是数字值前,parseInt()和 parseFloat()都会仔细分析该字符串。parseInt()方法首先查看位置0处的字符,判断它是否是个有效数字;如果不是,该方法将返回NaN,不再继续执行其他操作。但如果该字符是有效数字,该方法将查看位置1处的字符,进行同样的测试。这一过程将持续到发现非有效数字的字符为止,此时parseInt()将把该字符之前的字符串转换成数字。
       例如,如果要把字符串 "12345red" 转换成整数,那么parseInt()将返回12345,因为当它检查到字符r 时,就会停止检测过程。
       字符串中包含的数字字面量会被正确转换为数字,比如 "0xA" 会被正确转换为数字10。不过,字符串 "22.5" 将被转换成22,因为对于整数来说,小数点是无效字符。

var iNum1 = parseInt("12345red"); 
var iNum2 = parseInt("0xA"); 
var iNum3 = parseInt("56.9"); 
var iNum4 = parseInt("red"); 
document.write("iNum1="+iNum1);//返回12345 
document.write("iNum2="+iNum2);//返回10 
document.write("iNum3="+iNum3);//返回56 
document.write("iNum3="+iNum4);//返回NaN

        parseInt()方法还有基模式,可以把二进制、八进制、十六进制或其他任何进制的字符串转换成整数。基是由parseInt()方法的第二个参数指定的。

var iNum1 = parseInt("AF", 16); 
var iNum2 = parseInt("10", 2); 
var iNum3 = parseInt("10", 8); 
var iNum4 = parseInt("10", 10); 
document.write("iNum1="+iNum1);//返回175 
document.write("iNum2="+iNum2);//返回2 
document.write("iNum3="+iNum3);//返回8 
document.write("iNum4="+iNum4);//返回10

2)parseFloat()方法
        parseFloat()方法与parseInt()方法的处理方式相似,从位置0开始查看每个字符,直到找到第一个非有效的字符为止,然后把该字符之前的字符串转换成整数。不过,对于这个方法来说,第一个出现的小数点是有效字符。如果有两个小数点,第二个小数点将被看作无效的。parseFloat()会把这个小数点之前的字符转换成数字。这意味着字符串"11.22.33"将被解析成11.22。
       使用parseFloat()方法的另一不同之处在于,字符串必须以十进制形式表示浮点数,而不是用八进制或十六进制。该方法会忽略前导0,所以八进制数0102 将被解析为102。对于十六进制数0xA,该方法将返回 NaN,因为在浮点数中,x不是有效字符。此外,parseFloat() 方法也没有基模式。
      下面是使用 parseFloat() 方法的一些示例:

var fNum1 = parseFloat("12345red"); 
var fNum2 = parseFloat("0xA"); 
var fNum3 = parseFloat("11.2"); 
var fNum4 = parseFloat("11.22.33"); 
var fNum5 = parseFloat("0102"); 
var fNum6 = parseFloat("red"); 
document.write("iNum1="+iNum1);//返回12345 
document.write("iNum2="+iNum2);//返回NaN 
document.write("iNum3="+iNum3);//返回11.2 
document.write("iNum4="+iNum4);//返回11.22 
document.write("iNum5="+iNum5);//返回102 
document.write("iNum6="+iNum6);//返回NaN

(3)强制类型转换
        使用强制类型转换来处理转换值的类型。使用强制类型转换可以访问特定的值,即使它是另一种类型的。ECMAScript 中可用的3种强制类型转换如下:

  •        1)Boolean(value) - 把给定的值转换成 Boolean 型;
  •        2)Number(value) - 把给定的值转换成数字(可以是整数或浮点数);
  •        3)String(value) - 把给定的值转换成字符串;

       这些应该很好理解,在学习那些高级程序设计语言的时候经常会能使用到这些。
四、引用类型
       引用类型通常叫做类,也就是说,遇到引用值,所处理的就是对象。从传统意义上来说,ECMAScript并不真正具有类。事实上,除了说明不存在类,在ECMA-262中根本没有出现“类”这个词。ECMAScript定义了“对象定义”,逻辑上等价于其他程序设计语言中的类。
       对于JS对象的详细解释在前面的博文中也有,参考:轻松学习JavaScript九:JavaScript对象和数组。
       我们再来了解一个判断引用类型的操作符instanceof,在使用typeof运算符时采用引用类型存储值会出现一个问题,无论引用的是什么类型的对象,它都返回 "object"。ECMAScript引入了另一个Java运算符 instanceof 来解决这个问题。instanceof运算符与typeof运算符相似,用于识别正在处理的对象的类型。与typeof方法不同的是,instanceof方
法要求开发者明确地确认对象为某特定类型。
       例如:

var oStringObject = new String("hello world"); 
document.write(oStringObject instanceof String);//输出 "true"

       这段代码问的是“变量oStringObject是否为 String 对象的实例?”oStringObject的确是 String对象的实例,因此结果是 "true"。尽管不像typeof方法那样灵活,但是在typeof方法返回 "object" 的情况下,instanceof方法还是很有用的。
       此外,ECMAScript还有伪对象一说,也就是其他的基本类型,使用new创建时也是可以作为对象的,比如:String对象,Boolean对象和Number对象。它们是基本类型的引用类型。详细了解参考:ECMAScript引用类型。ECMAScript还包含了许多对象,本地对象,内置对象和宿主对象。这些我们会在后面的面向对象的时候具体了解。
五、复制变量值
      在变量复制方面,基本类型和引用类型有所不同,基本类型是复制的是值本身,而引用类型复制的是地址。
      我们来看具体的实例:

var box="Lee"; 
var box2=box; 
box2="Amy";//重新赋值后,两个基本类型变量操作时互不影响,还是保持各自的独立性 
document.write("box2="+box2+"<br/>"); 
document.write("box="+box);

 输出的结果为:Amy
                        Lee

详解JavaScript基本类型和引用类型

var box=new Object(); 
box.name="Lee"; 
var box2=box;//把引用地址值复制给box2 
box2.name="Amy";//重新赋值后,两个引用类型都指向同一个对象。name属性只要发生改变都会更改原值。 
document.write(" box2.name="+box2.name+"<br/>"); 
document.write("box.name="+box.name);

输出的结果为:Amy
                       Amy

详解JavaScript基本类型和引用类型

以上就是关于JavaScript基本类型和引用类型的详细介绍,希望对大家的学习有所帮助。

Javascript 相关文章推荐
JAVASCRIPT IE 与 FF中兼容问题小结
Feb 18 Javascript
javascript 闭包
Sep 15 Javascript
原生Js实现元素渐隐/渐现(原理为修改元素的css透明度)
Jun 24 Javascript
JavaScript实现复制功能各浏览器支持情况实测
Jul 18 Javascript
javascript中的undefined和not defined区别示例介绍
Feb 26 Javascript
开发中可能会用到的jQuery小技巧
Mar 07 Javascript
jquery动态添加元素事件失效问题解决方法
May 23 Javascript
简介JavaScript中的italics()方法的使用
Jun 08 Javascript
谷歌Chrome浏览器扩展程序开发小记
Jan 06 Javascript
WEB前端实现裁剪上传图片功能
Oct 17 Javascript
10分钟上手vue-cli 3.0 入门介绍
Apr 04 Javascript
基于elementUI使用v-model实现经纬度输入的vue组件
May 12 Javascript
jQuery中serializeArray()与serialize()的区别实例分析
Dec 09 #Javascript
jQuery实现form表单元素序列化为json对象的方法
Dec 09 #Javascript
jQuery实现页面顶部显示的进度条效果完整实例
Dec 09 #Javascript
深入浅析react native es6语法
Dec 09 #Javascript
JavaScript程序设计之JS调试
Dec 09 #Javascript
js实现的星星评分功能函数
Dec 09 #Javascript
JavaScript中的this到底是什么(一)
Dec 09 #Javascript
You might like
Windows下IIS6/Apache2.2.4+MySQL5.2+PHP5.2.1安装配置方法
2007/05/03 PHP
php UTF8 文件的签名问题
2009/10/30 PHP
PHP学习笔记 用户注册模块用户类以及验证码类
2011/09/20 PHP
一个简单安全的PHP验证码类 附调用方法
2016/06/24 PHP
javascript 浏览器检测代码精简版
2010/03/04 Javascript
safari,opera嵌入iframe页面cookie读取问题解决方法
2010/06/23 Javascript
Javascript中自动切换焦点实现代码
2012/12/15 Javascript
js的[defer]和[async]属性
2014/11/24 Javascript
javascript原型链继承用法实例分析
2015/01/28 Javascript
jQuery实现给页面换肤的方法
2015/05/30 Javascript
SVG描边动画
2017/02/23 Javascript
深入剖析Express cookie-parser中间件实现示例
2018/02/01 Javascript
JS处理一些简单计算题
2018/02/24 Javascript
微信小程序实现人脸检测功能
2018/05/25 Javascript
vue2.0 element-ui中el-select选择器无法显示选中的内容(解决方法)
2018/08/24 Javascript
vue实现pdf导出解决生成canvas模糊等问题(推荐)
2018/10/18 Javascript
javascript数据类型中的一些小知识点(推荐)
2019/04/18 Javascript
如何在Angular8.0下使用ngx-translate进行国际化配置
2019/07/24 Javascript
element的el-table中记录滚动条位置的示例代码
2019/11/06 Javascript
python如何通过protobuf实现rpc
2016/03/06 Python
transform python环境快速配置方法
2018/09/27 Python
使用Python 正则匹配两个特定字符之间的字符方法
2018/12/24 Python
解决django后台管理界面添加中文内容乱码问题
2019/11/15 Python
python读取配置文件方式(ini、yaml、xml)
2020/04/09 Python
Keras设定GPU使用内存大小方式(Tensorflow backend)
2020/05/22 Python
Django如何实现密码错误报错提醒
2020/09/04 Python
HTML5 b和i标记将被赋予真正的语义
2009/07/16 HTML / CSS
canvas实现滑动验证的实现示例
2020/08/11 HTML / CSS
澳洲女装时尚在线:Blue Bungalow
2018/05/05 全球购物
美国优质马术服装购买网站:Breeches.com
2019/12/16 全球购物
机电专业体育教师求职信
2013/09/21 职场文书
毕业生的自我评价分享
2013/12/18 职场文书
联谊活动总结
2014/08/28 职场文书
班子查摆四风个人对照检查材料思想汇报
2014/10/04 职场文书
2015年乡镇民政工作总结
2015/05/13 职场文书
2016年党员干部廉政承诺书
2016/03/24 职场文书