JS基础知识-数据类型篇
js是松散类型,本篇主要整理ECMAScript中的数据类型,包括5种简单数据类型与1中复杂数据类型。
typeof操作符
首先,我们可以根据typeof
操作符检测给定变量的数据类型。typeof
的返回值主要为:1
2
3
4
5
6undefined 该值未定义
boolean 布尔值
string 字符串
number 数值
object 对象
function 函数
需要注意的是,以上返回值中,function
并不是js的数据类型,function
似乎应该归于object
类型。
少了的那个数据类型为null
,在现代化浏览器中,typeof null
返回object
,因为浏览器将null
作为空对象的引用。想一想好像确实是这样。
(其实function
与object
还是有不同的,比如参数啥的)
(不太常见的旧浏览器中,typeof null
返回的是function
)
Undefined类型
Undefined
类型只有一个值undefined,当声明的变量未初始化时,该变量的值即为undefined。
判断一个变量是否为Undefined
类型,可以使用等于直接与undefined
比较:1
2
3var aaa;
console.log(aaa === undefined);
> true
需要注意的是,未初始化的变量与未声明的变量是两个概念:1
2
3
4
5
6var aaa;
> undefined
aaa
> undefined
bbb
> VM136:1 Uncaught ReferenceError: bbb is not defined
可以看到,未初始化的变量直接使用会返回undefined
,而未声明的变量会报错。
更需要注意的是:1
2
3
4typeof aaa
> "undefined"
typeof bbb
> "undefined"
未初始化与未声明的变量使用typeof
操作符检测都返回undefined
再次提示未声明的变量不可直接使用:1
2
3
4console.log(aaa === undefined);
> true
console.log(bbb === undefined);
> Uncaught ReferenceError: bbb is not defined
Null类型
Null
类型只有一个值:null
。null
看起来似乎很奇怪,它表示的是一个空对象指针,使用typeof
操作符返回的是object
。
null
作为空对象指针也很实用,在准备用一个变量保存对象时,可以先将该对象初始化/赋值为null
,将空对象赋值为null
的操作是很优良的习惯:1
var apple = null;
这样在判断一个变量是否保存了对象的引用(即本身不再为null)时,可以这样判断:1
2
3
4
5
6
7apple === null;
> true
apple = new Object();
apple === null;
> false
apple !== null;
> true
需要注意的是:1
2
3
4var banana = null;
console.log(banana === null)
console.log(banana === undefined)
console.log(banana == undefined)
思考5s……
以上输出分别为:1
2
3true
false
true
关于==
(相等)与===
(全等)的关系会在后面“操作符篇”进行说明,现在先解释一下为何console.log(banana == undefined)
会成立。因为undefined
是派生自null
值,因此undefined == null
。
(注意上面一句话中提到了派生,因为js是支持继承的,这是一个很深入的话题,后面应该会有一篇“继承篇”来整理这个绝对算得上很核心的话题)
Boolean类型
值为true
跟false
,记得千万不要写成True
与False
(尤其是一边写python一边写js的时候-_-!)
其他类型与Boolean
类型转化是值得学习的点:1
2
3
4
5
6
7
8
9
10
11为true的情况:
String类型:任何非空字符串
Number类型:任何非零数字值(包括无穷大)
Object类型:任何非空对象
Undefined:n/a(即不适用)
为false的情况
String类型:""空字符串
Number类型:0和NaN
Object类型:null
Undefined:undefined
Number类型
与java等类似,有十进制、八进制(0开头)、十六进制(0x开头)这些。
浮点数也是Number类型的一部分,只是浮点数占用的内存空间是整数值的两倍,所以js会不失时机的将浮点数转化为整数值:1
2ccc = 1.0
> 1
可以使用e表示的科学技术法
数值范围
Number类型表示的范围通常不会太注意,但是在大数据量的情况下,往往会一不留神就会掉入Infinity
(正无穷)中(也许会掉到(-Infinity)负无穷中)。Number表示的范围可以使用Number.MIN_VALUE
与Number.MAX_VALUE
查看:1
2
3
4Number.MIN_VALUE
> 5e-324
Number.MAX_VALUE
> 1.7976931348623157e+308
(可以用IsFinite()
函数来检查一个数值是否处于最小、最大之间)
NaN(not a number)
需要注意如何判断一个操作数返回值是否为NaN(比如在用一个数值除以一个非数值的操作):1
2
3
4
5
6
7
8错误示范:
NaN == NaN
> false
因为NaN与任何值都不相等
正确示范:
isNaN(NaN)
如果启用了ESLint,在ES6中最好使用:
Number.isNaN(NaN)
数值转化
主要涉及到三个函数Number()
、parseInt()
、parseFloat()
,还有一个很XX的操作符+
。
Number()
1 | Boolean->true:0 false:1 |
字符串类型的比较有意思:1
2
3
4
5
6只包含数字的(包括+、-、进制表示与浮点数),直接转化为数字
字符串为空:0
字符串包含其他字符:NaN
var ddd = '123aaa';
Number(ddd);
> NaN
parseInt()
在ESLint中,更推荐使用parseInt()
,与Number()
比:1
21、支持转换时传入基数(进制)参数。强烈建议在转化时指定基数
2、若字符串开头为数字,则对字符串进行最大解析。若开头不为数值,则与Number()转化一致
第二条规则样例:1
2
3
4
5var ddd = '123aaa';
Number(ddd);
> NaN
parseInt(ddd);
> 123
parseFloat()
只需要注意它支持十进制
+操作符
这个操作符其实跟Number()是一样的效果。
String类型
与java比较类似,字符串是不可变的。
对字符串做加法,基本会经历:
1、创建一个新的字符串
2、将原字符串与待加入字符串填充到新字符串中
3、销毁原字符串(浏览器后台自行销毁)
对于字符串拼接,相较于旧浏览器,现代浏览器会做优化。
字符串转化
主要有toString()
方法与String()
方法,也有一个很XX的+
操作符(这次得需要与空字符串联合使用)。
toString()
方法与String()
方法区别在于null
与undefined
由于没有toString()
方法,所以只能使用String()
String()
在执行非null
与undefined
参数时也是调用的toString()
通过空字符串与+
操作符结合变量,与变量直接使用toString()
一致
Object类型
创建方式为:1
var obj = new Object(); // 虽然括号可以省略,但没必要
作为对象,有一些自己的基础方法:1
2
3
4
5
6
7constructor:构造函数
hasOwnProperty(propertyName):分析属性是否存在于当前实例,而不是原型中
isPrototypeOf(object):分析传入的对象是否为当前实例的原型
propertyIsEnumerable(propertyName):分析属性是否为可枚举属性
toLocaleString():返回对象字符串表示,与执行环境地区对应
toString():返回对象的字符串表示
valueOf():返回对象的字符串、数值或布尔值表示。通常与toString()返回结果一致
涉及到的实例与原型的概念,应该会在后面的“继承篇”里总结。
Object转化为String
一般会使用JSON进行Object与String的互转:1
2
3var obj = {a: 1};
var targetStr = JSON.stringify(obj);
var targetObj = JSON.parse(targetStr);
Object转化为Number
对象转化为Number,可以调用Number()
或者parseInt()
方法,或者是一元加法(就是上面那个很XX的+
操作符),转化流程主要为:1
21、调用valueOf()方法,将对象转化为字符串、数值或布尔值,再根据字符串、数值、布尔值的相应的规则转化为Number
2、若valueOf()方法返回NaN,则调用对象的toString()方法,将对象转化为字符串,再转化为Number