JS的数据类型
js一共有一下 5 中基本类型
Number string Object undefined boolean
其中,Object是引用类型,其余都是值传递类型。
undefined
undefined可以表示一下3中状态:
- 表示一个未声明的变量,
- 已声明但没有赋值的变量,
- 一个并不存在的对象属性
null
null 是一种特殊的object ,表示无值
NaN
NaN是一种特殊的number ,表示无值
隐式转换
涉及的函数
隐式转换主要涉及三种转换:
- 将值转为原始值,ToPrimitive()。
- 将值转为数字,ToNumber()。
- 将值转为字符串,ToString()。
对象的 valueOf()
Object.prototype 是所有对象原型链顶层原型,他包含了 valueOf方法和toString 方法。
Number、Boolean、String 三种构造函数生成的 Object 通过内置 valueOf 转换后会变成相应的原始值。例码:
var num = new Number('123');
num.valueOf(); // 123
var str = new String('12df');
str.valueOf(); // '12df'
var bool = new Boolean('fd');
bool.valueOf(); // true
Date 这种特殊的对象,通过内置 valueOf函数 将日期转换为日期的毫秒的形式的数值。例码:
var a = new Date();
a.valueOf(); // 1515143895500
除此之外返回的都为this,即对象本身;例码:
var a = new Array();
a.valueOf() === a; // true
var b = new Object({});
b.valueOf() === b; // true
对象的 toString()
Number、Boolean、String、Array、Date、RegExp、Function这几种构造函数生成的对象,通过toString转换后会变成相应的字符串的形式,因为这些构造函数上封装了自己的toString方法。例码:
Number.prototype.hasOwnProperty('toString'); // true
Boolean.prototype.hasOwnProperty('toString'); // true
String.prototype.hasOwnProperty('toString'); // true
Array.prototype.hasOwnProperty('toString'); // true
Date.prototype.hasOwnProperty('toString'); // true
RegExp.prototype.hasOwnProperty('toString'); // true
Function.prototype.hasOwnProperty('toString'); // true
var num = new Number('123sd');
num.toString(); // 'NaN'
var str = new String('12df');
str.toString(); // '12df'
var bool = new Boolean('fd');
bool.toString(); // 'true'
var arr = new Array(1,2);
arr.toString(); // '1,2'
var d = new Date();
d.toString(); // "Wed Oct 11 2017 08:00:00 GMT+0800 (中国标准时间)"
var func = function () {}
func.toString(); // "function () {}"
除了这些对象及其实例化对象之外,其他对象返回的都是该对象的类型,都是继承的 Object.prototype.toString 方法。例码:
var obj = new Object({});
obj.toString(); // "[object Object]"
Math.toString(); // "[object Math]"
ToPrimitive()
可以将输入的值转成 Number 或 String 类型。它接收两个参数:ToPrimitive( input , PreferredType );PreferredType 是可选参数。input 是要转换的值,PreferredType是要转换的类型,只能是 Number 或 String。
转换内部流程
若 PreferredType 是 String:
- 先调用 toString() 方法,若返回的是 原始值,则结束;
- 再调用 valueOf() 方法,若返回的是 原始值,则结束,若不是,返回错误;
若 PreferredType 是 Number:
- 先调用 valueOf() 方法,若返回的是 原始值,则结束;
- 再调用 toString() 方法,若返回的是 原始值,则结束,若不是,返回错误;
若没有指定 PreferredType:
除了Date类型的对象,其余都按照 Number 顺序来。
ToNumber()
根据参数类型进行下面转换:
| 参数 | 结果 |
|---|---|
| undefined | NaN |
| null | +0 |
| 布尔值 | true转换1,false转换为+0 |
| 数字 | 无须转换 |
| 字符串 | 有字符串解析为数字,例如:‘324’转换为324,‘qwer’转换为NaN |
| 对象(obj) | 先进行 ToPrimitive(obj, Number)转换得到原始值,再进行ToNumber转换为数字 |
注意: 对象是如何转换的 是重点。
ToString()
根据参数类型进行下面转换:
| 参数 | 结果 |
|---|---|
| undefined | 'undefined' |
| null | 'null' |
| 布尔值 | 转换为'true' 或 'false' |
| 数字 | 数字转换字符串,比如:1.765转为'1.765' |
| 字符串 | 无须转换 |
| 对象(obj) | 先进行 ToPrimitive(obj, String)转换得到原始值,在进行ToString转换为字符串 |
注意: 对象是如何转换的 是重点。
+ 号隐式转换
涉及隐式转换最多的两个运算符 + 和 ==;- * / 这些运算符只会针对number类型,故转换的结果只能是转换成number类型。
转换流程:
- 首先会 进行 ToPrimitive() 转换,一般为未指定 PreferredType类型;
- 由于 ToPrimitive() 所以执行 valueOf() ,若结果是原始值,返回,若不是,继续;
- 执行 toString() ,返回原始值,结束
例码:
({} + {}) = ? 两个对象的值进行+运算符,肯定要先进行隐式转换为原始类型才能进行计算。
1、进行ToPrimitive转换,由于没有指定PreferredType类型,{}会使默认值为Number,进行ToPrimitive(input, Number)运算。
2、所以会执行valueOf方法,({}).valueOf(),返回的还是{}对象,不是原始值。
3、继续执行toString方法,({}).toString(),返回"[object Object]",是原始值。故得到最终的结果,"[object Object]" + "[object Object]" = "[object Object][object Object]"
= 号隐式转换
类型相同
类型相同的时候只需要注意一点:NaN不与任何值相等,包括它自己,即NaN !== NaN。
类型不同
遵循以下几点规律:
- x,y 为 null、undefined 两者中一个 // 返回true
- x,y为 Number和String 类型时,则转换为Number类型比较。
- 有 Boolean 类型时,Boolean转化为Number类型比较。
- 一个Object类型,一个String或Number类型,将Object类型进行原始转换后,按上面流程进行原始值比较。
例码:
var a = {
valueOf: function () {
return 1;
},
toString: function () {
return '123'
}
}
true == a // true;
首先,x与y类型不同,x为boolean类型,则进行ToNumber转换为1,为number类型。
接着,x为number,y为object类型,对y进行原始转换,ToPrimitive(a, ?),没有指定转换类型,默认number类型。
而后,ToPrimitive(a, Number)首先调用valueOf方法,返回1,得到原始类型1。
最后 1 == 1, 返回true。
例码:
[] == !{}
//
1、! 运算符优先级高于==,故先进行!运算。
2、!{}运算结果为false,结果变成 [] == false比较。
3、根据上面第7条,等式右边y = ToNumber(false) = 0。结果变成 [] == 0。
4、按照上面第9条,比较变成ToPrimitive([]) == 0。
按照上面规则进行原始值转换,[]会先调用valueOf函数,返回this。
不是原始值,继续调用toString方法,x = [].toString() = ''。
故结果为 '' == 0比较。
5、根据上面第5条,等式左边x = ToNumber('') = 0。
所以结果变为: 0 == 0,返回true,比较结束。
转换为 boolean
除了以下六个值,其他都是自动转为true:
- undefined
- null
- -0
- +0
- NaN
- ‘’(空字符串)