详解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 相关文章推荐
jQuery Selector选择器小结
May 06 Javascript
JsDom 编程小结
Aug 09 Javascript
动态加载iframe时get请求传递中文参数乱码解决方法
May 07 Javascript
JavaScript中对象介绍
Dec 31 Javascript
JavaScript 对象深入学习总结(经典)
Sep 29 Javascript
JavaScript+Java实现HTML页面转为PDF文件保存的方法
May 30 Javascript
纯JS前端实现分页代码
Jun 21 Javascript
node.js 和HTML5开发本地桌面应用程序
Dec 13 Javascript
JavaScript你不知道的一些数组方法
Aug 18 Javascript
详解vue-cli脚手架build目录中的dev-server.js配置文件
Nov 24 Javascript
Bootstrap导航菜单点击后无法自动添加active的处理方法
Aug 10 Javascript
微信小程序按顺序同步执行的两种方式
Dec 20 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
mysql+php分页类(已测)
2008/03/31 PHP
基于PHP后台的Android新闻浏览客户端
2016/05/23 PHP
php获取flash尺寸详细数据的方法
2016/11/12 PHP
使用JavaScript构建JSON格式字符串实现步骤
2013/03/22 Javascript
打印json对象的内容及JSON.stringify函数应用
2013/03/29 Javascript
jquery实现table鼠标经过变色代码
2013/09/25 Javascript
javascript禁制后退键(Backspace)实例代码
2013/11/15 Javascript
新增加的内容是如何将div的scrollbar自动移动最下面
2014/01/02 Javascript
jquery ajax 局部刷新小案例
2014/02/08 Javascript
js获取ajax返回值代码
2014/04/30 Javascript
js获取及判断键盘按键的方法
2015/12/01 Javascript
jQuery实现伪分页的方法分享
2016/02/17 Javascript
Bootstrap学习笔记之css样式设计(1)
2016/06/07 Javascript
浅谈JavaScript 数据属性和访问器属性
2016/09/01 Javascript
JavaScript定义数组的三种方法(new Array(),new Array('x','y')
2016/10/04 Javascript
基于Three.js插件制作360度全景图
2016/11/29 Javascript
使用socket.io制做简易WEB聊天室
2018/01/02 Javascript
微信小程序网络封装(简单高效)
2018/08/06 Javascript
使用微信小程序开发弹出框应用实例详解
2018/10/18 Javascript
利用React高阶组件实现一个面包屑导航的示例
2020/08/23 Javascript
python自动zip压缩目录的方法
2015/06/28 Python
Python 修改列表中的元素方法
2018/06/26 Python
基于python实现从尾到头打印链表
2019/11/02 Python
html5的画布canvas——画出弧线、旋转的图形实例代码+效果图
2013/06/09 HTML / CSS
煤矿班组长岗位职责
2013/12/29 职场文书
高中数学教学反思
2014/01/30 职场文书
校庆活动方案
2014/03/31 职场文书
捐款倡议书
2014/04/14 职场文书
大学生志愿者活动总结
2014/06/27 职场文书
国庆节慰问信
2015/02/15 职场文书
年会主持人开场白台词
2015/05/29 职场文书
致运动员加油稿
2015/07/21 职场文书
高中班主任培训心得体会
2016/01/07 职场文书
2016年幼儿园教研活动总结
2016/04/05 职场文书
使用 Apache Superset 可视化 ClickHouse 数据的两种方法
2021/07/07 Servers
对讲机的最大通讯距离是多少
2022/02/18 无线电