数据类型
ES5中的数据类型包括number、string、boolean、null、undefined和object六种,object还可以细分为数组array和函数function。1
2
3
4
5
6
7
8
9
10
11const number = 1;
const string = 'hi';
const boolean = true;
const object = {
first:"white",
second:"yin"
};
const array = [1,2,3];
function f(){
console.log('hello');
}
数据类型反射
已知一个变量,要获取其数据类型,可以使用三种方法:typeof、instanceof和Object.prototype.toString()方法。
typeof
1 | typeof number;//"number" |
所有返回值都是字符串,能够判断number、string、boolean、object、function和undefined六种类型,对array和null操作返回为object。
instanceof
instanceof 运算符用来检测 constructor.prototype 是否存在于参数 object 的原型链上。即实例是否继承于一个类1
2
3
4var arr = [];
arr instanceof Array;//true
arr instanceof Object;//true
arr instanceof Function;//false
这种方法判断数组时,不能判断其他页面声明的数组。不过我觉得这个问题很少见。
Object.prototype.toString()
使用call或apply指定toString方法的this值,获取数据的类型:1
2
3
4
5
6
7
8Object.prototype.toString.apply(1)//"[object Number]"
Object.prototype.toString.apply("1")//"[object String]"
Object.prototype.toString.apply(null)//"[object Null]"
Object.prototype.toString.apply(undefined)//"[object Undefined]"
Object.prototype.toString.apply(true)//"[object Boolean]"
Object.prototype.toString.apply({})//"[object Object]"
Object.prototype.toString.apply([])//"[object Array]"
Object.prototype.toString.apply(function(){})//"[object Function]"
通过这种方法判断数据类型是比较准确的。除非你修改了toString方法。剁手!
其他方法
有些特殊类型会有特定的判断方法,比如NaN。可以使用isNaN()方法对传入的参数进行判断。但是如果参数是非数值,会转换为数值类型,这时会出现问题:isNaN('NIHAO')===true
。所以推荐的方法是利用NaN的自不等性:NaN !== NaN
。
数组类型也有特殊的判断方法:isArray()。传入参数如果是数组则返回true。不过这个方法可能在老版本的浏览器中不支持,所以要先判断是否支持。1
2
3
4
5if (!Array.isArray) {
Array.isArray = function(arg) {
return Object.prototype.toString.call(arg) === '[object Array]';
};
}
数值类型中无穷也是一种特殊情况:-Infinity和Infinity。判断是否有穷,即不为无穷数,可以使用isFinite()方法。无穷返回false。
隐式转换
数据类型可以分为两大类,一类是原始数据类型:number、string、null、undefined和boolean,另一类是引用类型:object。
Object.valueOf()
valueOf方法是返回指定对象的原始值。
对象 | 返回值 |
---|---|
Array | 数组的元素被转换为字符串,由逗号分割。相当于toString()或join(‘’)方法。 |
Boolean | 返回相应的布尔值 |
Date | 从1970年1月1日开始的毫秒数 |
Function | 函数本身 |
Number | 相应的数字 |
Object | 对象本身 |
String | 字符串本身 |
toString()
toString方法返回对象的字符串形式:
对象 | 返回值 |
---|---|
Array | 逗号分割的字符串 |
Boolean | ‘true’或’false’ |
Date | 返回指定日期的字符串表示 |
Function | 返回函数体的字符串 |
Number | 返回数字的字符串形式 |
Object | 返回[object Object] |
String | 字符串本身 |
Number()
1 | // 数值:转换后还是原来的值 |
Number方法比parseInt方法要严格,字符串中若是存在字母或特殊字符,一律返回NaN。
对象调用Number方法的处理逻辑如下:
- 首先调用对象的valueOf方法,如果返回值是原始类型则对该返回值调用Number方法;
- 如果返回值是对象,则调用该对象的toString()方法,如果返回原始类型的值则对该值调用Number方法;
- 如果返回对象,报错。
根据上面的规则,我们让一些不相等的值相等:1
2
3
4
5
6var a = {
valueOf:function(){
return 10;
}
}
a==10;//true
String()方法
String方法将数据转为字符串:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20//数值:转为相应字符串
String(123) // "123"
//字符串:原值
String('abc') // "abc"
//布尔值:相应的字符串
String(true) // "true"
//undefined:"undefined"
String(undefined) // "undefined"
//null:"null"
String(null) // "null"
//对象:
String({x:1}) //"[object Object]"
//数组
String([1,2,3]) //"1,2,3"
String()的处理逻辑与Number()相反:
- 调用对象toString()方法,如果返回原始类型值对其调用String();
- 如果返回对象,调用其valueOf()方法,如果返回原始类型,对返回值调用String();
- 如果返回对象,报错。
Boolean()
Boolean()方法可以将数据转为布尔值。我们需要记忆的是下面几个转换为false的falsy值:1
2
3
4
5Boolean(undefined) //false
Boolean(null) //false
Boolean(0) //false
Boolean("") //false
Boolean(NaN) //false
其他值转换成true。空对象或数组也都转换为true。
自动转换
如果运算符的运算子的数据类型与预期不符,就会出现自动类型转换的情况。比如+、==等等,比较简单,不举例了。