Tancky's  Blog

JavaScript中的数据类型

今天继续夯实基础,写一写Js中的数据类型,理清楚概念才能少踩一些没必要的坑,特别是对于很多初学者而言(好吧,包括我在内)很容易弄混淆的东西。

两类数据类型

众所周知,JS中有六种数据类型,按全球JS顶尖专家Nicholas Zakas的说法,JS中数据类型又分成两大类:第一种是简单的数据类型(原始类型):Undefined,Null,Boolean,Number以及String,其二是复杂的数据类型(引用类型)——object,而object本质上是由一组无序的名值对组成的。在ECMAScript中不支持任何创建自定义类型的机制,所有的值最终都将是上述的6种数据类型之一。

1
2
3
4
5
6
7
8
9
var a=100; //此时a为number类型
a=true; //此时a为boolean类型
a="Hello,JavaScript!"; //此时a为string类型
a={}; //此时a为object类型
a=function(){} //此时a为function类型,也是属于对象类型

typeof操作符

由于JS是一种弱类型的编程语言,所以需要有一种手段来检测给定变量的数据类型——typeof操作符。举个栗子:

1
2
3
4
var msg="Hello World"
alert(typeof msg); //"string"
alert(typeof(msg)); //"string"
alert(typeof 37); //"number"

原始类型

  • Undefined类型

Undefined类型只有一个值叫—不存在!这个不存在在JS中就是undefined, 就是英文的原意:『未定义』,但我总觉得这个文绉绉的词其实不好理解。不如把它理解为不存在更然人明白些。在使用var 声明变量但没有初始化的时候,这个变量的值就是undefined。再举个栗子:

1
2
var msg;
alert(msg == undefined); //true;

A. 如果一个函数没有返回值,其实就是它的返回值为undefined,即它的返回值不存在。
B. 访问一个对象所没有的属性?对不起,得到的是undefined, 即这个属性不存在。
C. 代码中写了:var a; console.log(a); 得到undefined, 即这个a不存在,你会争辩:可我明明写了var a;a在我的代码中啊,对的!但这就好比我们人类在这个世界可以把那些没法证实已经存在的东西专门起个名字–叫『不存在』一样。你可以提到它,但它真的不存在。它的名字就叫:不存在。

  • Null类型

之前看过一个大神的文章里面,他是这么来谈null类型的:

很多书上喜欢把程序中的变量比喻成一个盒子,里面装的内容就是变量的值。盒子中装的内容是可以变化的,所以叫变量。这个比喻很形象。先赞一下。

如果你送个你女朋友一个礼物盒,里面装得有礼物,用JS的话来说,你给了她一个变量(因为下次你可能用同样的礼物盒子,但装另外的礼物),如果你只是给了她一个空盒子,用JS的话来比喻,你给了她一个空值,就是null,里面什么也没有装(当然你会被她痛扁的),但这个盒子是存在的,不是undefined的。

但这个空盒子的类型是什么?typeof(null), 返回居然是’object’, 它是对象类型?它不是原始类型?它居然是引用类型?有没有搞错?是的,但不是我们搞错了,是JS的设计者搞错了,但他就是这么设计的。

由于JS是一个外国大牛仅仅花了十天的时间便创造出来的一门编程语言,现在已经发展到满世界这么流行了,此人已经灰常牛了,如果他不犯一点点错误,还叫我们这样智力平平但又靠写代码为生的码农怎么混?还要不要我们活了?他犯错了,说明他是人,不是神!

虽然很多书中把null叫做空对象, 但按照Nicholas Zakas这样全球顶尖JS高手的归类,它不是引用类型,它应该归于原始类型,只是它是一种特殊的原始类型,尽管typeof(null)返回’object’。

  • Boolean类型

Boolean类型(又叫布尔类型)是JS种使用的最多的一种数据类型。他只会返回两个值(布尔值):ture或者false,且只能是小写。其他混合大小的形式都不是布尔值,只是标识符。

其它类型是可以转换成布尔类型的。转换规则如下:

A. 正零、负零、浮点零(0.0)、空字符串、false本身、NaN、null、undefined 被转换为假值(false)
B. 其它值被转换为真值(true), 特别是对象—哪怕是空对象,也会被转换成真值true
C. 如果x是要转换成布尔类型的值,就调用Boolean(x),你也可以写成:!!x 即可。

  • Number类型

JS中不管整数还是浮点数,统一归于number类型(数值类型),不像Java那样分为整形和浮点型,整形里面又分为byte,short,int,long 类型,浮点数里面又分为float,double类型,总之,JS中,数值都是number类型,可以用类型操作符typeof(x)来判断,如果返回的是一个字符串’number’, 则表明x 就是number类型。

其实,JS中的数值都是浮点数,例如有:10===10.0 //true.

需要注意的有:
(1) NaN(Not a Number—非数值)是一种特殊的数值类型, typeof(NaN),得到的还是’number’ 它不应该参与任何数值类型的运算。它和自己都不相等,无论NaN == NaN, 还是NaN === NaN,得到的都是false. 任何其它的数值类型和NaN进行运算,得到的都是NaN.

(2) 正无穷大表示为Infinity, 负无穷大表示为-Infinity, 它们也是特殊的number类型。

(3) 四则运算中任何一个数值类型除以0,得到Infinity, 但0/0会得到NaN, 这些也不必死记,需要时可以打开Node的命令行验证一下即可。

(4)不是所有的其它类型都可以转化为数值类型,这个需要看情况而定。转换时,如果要转换为整数,可以用parseInt()函数,如果要转换为浮点数,可以用parseFloat(), 注意没有parseDouble()函数,也可以用函数Number(),但某些值和用parseInt()/parseFloat()函数有一些区别。拿不准时,可以先用Node命令行简单测试一些,采用最合理的转换函数,避免bug.

(5)最后请记住:浮点数的运算始终会有误差,能用整数时,尽量用整数。

  • String类型

A. JS中没有单独的字符类型,无论单个的字符还是一个字符串都是属于string类型,string类型在JS中属于原始类型,并不像其他语言例如Java中那样,字符串是对象,这是一个很显著的区别。

B. JS中的字符串可以用英文的单引号或双引号包裹起来,如’A’, “ABCD”,’Hello,world’.

C. JS中的空字符串就是’’或””,单引号和双引号之间什么也没有,连空格也不能有。

D. 字符串类型有一个属性叫length,它表示这个字符串的长度(字符的个数),无论中英文字符串中,每个字符都只算一个占位,(千万别混淆:中文字符占2个字节),

举个栗子:

1
2
3
4
5
6
var s1='abcd';
var s2="中国人民";
console.log(s1.length); //4
console.log(s2.length); //4

JS中的原始类型也有一些属性和方法,例如这次说的字符串类型,还有toUpperCase(),toLowerCase()方法等等。字符串类型也可以通过方括号语法,用下标来读取位于某个位置的字符,如: var s=’abcde’, 则可以用s[3]来读取下标是3的字符,即:’d’, 字符串的下标仍以0开始,和数组下标一样的开始位置,但JS中字符类型完全不同于JS中的数组类型。后者是引用类型,后面再说吧。

其他任何的类型都可以转化为字符串类型,使用函数String(x), 注意:S要大写,前面不加new运算符,x是要转化为字符串类型的一个值。至于null, undefined,函数等可以转化为字符串类型吗?当然可以,你自己用String( )函数试试看吧。

如果要判断一个变量或一个值是否为字符串类型,可以使用类型操作符typeof x, 也可以写成typeof(x), 如果得到的返回是一个字符串:’string’, 那x就是字符串类型了。此处要注意typeof(x)的写法并不是函数调用,只是这种书写看起来像函数调用罢了,别混淆了,提醒你,JS中处处有坑。

引用类型

引用类型是一种用于将数据和功能组织在一起的数据结构(也常被成为类),引用类型的值(对象)是引用类型的一个实例。

但是JS中没有类的概念,因此引用类型也可以被称为对象定义,因为他们描述的是一类对象所具有的属性和方法。

对象是某个特定引用类型的实例,新对象是使用new操作符后跟一个构造函数来创建的,构造函数本身就是一个函数,只不过该函数是出于创建新对象的目的而定义的。

Object是最基本的类型,其他所有类型都继承了它的行为。在举个栗子:

1.Array类型

除了Object之外,Array算是JS最常用最常用的类型。js中的数组与其他语言的数组都是数据的有序列表,但是,数组的每一项可以保存任何类型的数据

2.Date类型

Js中用于构建日期对象的引用类型

3.RegExp类型

Js通过RegExp类型来支持正则表达式

4.Function类型

Js中的函数实际上是对象,每个函数都是Function类型的实例,而且都与其他引用类型一样具有属性和方法。由于函数是对象,因此函数名实际上也是一个指向函数对象的指针,不会与某个函数绑定。例如:

1
2
3
function sum(num1,num2){
return num1 + num2;
}

这与使用函数表达式定义函数的方法几乎相差无几:

1
2
3
var sum = function(num1,num2){
return num1 + num2;
}

本文完!

热评文章