一、数据类型 “7+1”
1.1 概念
- 7 种原始类型(不可变): Boolean、Undefined、Number、String、Null、Symbol(ES6)、BigInt(ES6)
- 1 种对象类型Object: 包含了Function、Array、特殊对象(RegExp、Date)
Symbol: 表示独一无二的值,如对象的key,常量
BigInt: 可以表示超出Number限制的整数(253 -1)
1.2 应用场景
1.2.1 null的场景
- 作为原型链的终点
- 作为函数的参数,表示该函数的参数不是对象
1.2.2 undefined的场景
- 声明了一个变量但并未为该变量赋值,此变量的值默认为
undefined
- 函数没有明确写
return
,默认返回undefined
- 调用函数时,没有传参数,默认参数值为
undefined
- 对象的某个属性没有赋值,默认值为
undefined
二、类型的判断
2.1 typeof
typeof 操作符返回一个字符串,表示未经计算的操作数的类型。
1 | // 1、数值 |
2.2 constructer、instanceof
自定义类型的判断
1 | //constructor |
2.3 Object.prototype.toString.call()
可以检测所有类型toString
是Object
原型对象上的一个方法,该方法默认返回其调用者的具体类型,更严格的讲,是 toString
运行时this指向的对象类型, 返回的类型格式为[object,xxx],xxx
是具体的数据类型,其中包括:
String,Number,Boolean,Undefined,Null,Function,Date,Array,RegExp,Error,HTMLDocument,… 基本上所有对象的类型都可以通过这个方法获取到。
1 | Object.prototype.toString.call(null) //"[object Null]" |
类型判断工具函数:
1 | function type(data) { |
2.4 特殊判断
2.4.1 例子
1 | var str1 = '1'; |
2.4.2 空对象判断
1 | 空对象判断 |
三、类型转换
3.1 显示强制类型转换
valueOf() 与 toString要点:
toString()
和valueOf()
都是对象的方法toString()
返回的是字符串,而valueOf()
返回的是原对象undefined
和null
没有toString()
和valueOf()
方法- 包装对象的
valueOf()
方法返回该包装对象对应的原始值 - 使用
toString()
方法可以区分内置函数和自定义函数
3.1.1 ToString:将值转为字符串
参数 | 结果 |
---|---|
1. undefined | ‘undefined’ |
2. null | ‘null’ |
3. 布尔值 | 转换为’true’ 或 ‘false’ |
4. 数字 | 数字转换字符串,比如:1.765转为’1.765’ |
5. 字符串 | 无须转换 |
6. 对象(obj) | 先进行 ToPrimitive(obj, String)转换得到原始值,在进行ToString转换为字符串 |
1 | [1,2,3].toString() // '1,2,3' |
Number、Boolean、String、Array、Date、RegExp、Function
这几种构造函数生成的对象,通过toString
转换后会变成相应的字符串的形式,因为这些构造函数上封装了自己的toString
方法1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25Number.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
方法1
2
3
4var obj = new Object({});
obj.toString(); // "[object Object]"
Math.toString(); // "[object Math]"
3.1.2 ToNumber:将值转为数字
参数 | 结果 |
---|---|
1. undefined | NaN |
2. null | +0 |
3. 布尔值 | true转换1,false转换为+0 |
4. 数字 | 无须转换 |
5. 字符串 | 有字符串解析为数字,例如:‘324’转换为324,‘qwer’转换为NaN |
6. 对象(obj) | 先进行 ToPrimitive(obj, Number)转换得到原始值,在进行ToNumber转换为数字 |
1 | Number('42') //42 |
3.1.3 ToBoolean
1 | Boolean([]) //true |
3.1.4 ToPrimitive:将值转换为原始值
3.1.5 TvalueOf()方法
Number、Boolean、String
这三种构造函数生成的基础值的对象形式,通过valueOf
转换后会变成相应的原始值1
2
3
4
5
6
7
8var num = new Number('123');
num.valueOf(); // 123
var str = new String('12df');
str.valueOf(); // '12df'
var bool = new Boolean('fd');
bool.valueOf(); // trueDate
这种特殊的对象,其原型Date.prototype
上内置的valueOf
函数将日期转换为日期的毫秒的形式的数值。1
2var a = new Date();
a.valueOf(); // 1515143895500- 除此之外返回的都为
this
,即对象本身1
2
3
4
5var a = new Array();
a.valueOf() === a; // true
var b = new Object({});
b.valueOf() === b; // true
3.2 隐式强制类型转换
热门题目:怎么定义a,可以使a==1&&a==2&&a==3?
1 | const a = { |
3.2.1 if
判断中
1 | if(XXX){ |
这里就发生了隐式转换,if
的判断条件是Boolean
类型,代码在执行到if
判断时,js将XXX转换成了Boolean
类型。
3.2.2 比较操作符 "=="
1 | [] == [] // false |
3.2.3 加号"+"
与 减号 "-"
1 | var add = 1 + 2 + '3' |
1 | "a" + "b" // "ab" |
3.2.4 .
点号操作符
1 | var a = 2; |
3.2.5 关系运算符比较时
1 | 3 > 4 // false |
如果比较运算符两边都是数字类型,则直接比较大小。如果是非数值进行比较时,则会将其转换为数字然后在比较,如果符号两侧的值都是字符串时,不会将其转换为数字进行比较,而是分别比较字符串中字符的Unicode编码。
3.2.6 ==
运算符隐式转换
原始类型之间相比较
- 字符串类型与数字类型相比较
- 当字符串类型与数字类型相比较时,
字符串类型
会被转换为数字类型
- 当字符串是由纯数字组成的字符串时,转换成对应的数字,字符串为空时转换为
0
,其余的都转换为NaN
。1
2
3
4
5"1" == 1 //true
"" == 0 //true
"1.1e+21" == 1.1e+21 //true
"Infinity" == Infinity //true
NaN == NaN //false 因为NaN与任何值都不相等,包括自己
- 布尔类型与其他类型相比较
- 只要
布尔类型
参与比较,该布尔类型
就会率先被转成数字类型
- 布尔类型
true
转为1
,false
转为0
1
2
3
4
5true == 1 // true
false == 0 // true
true == 2 // false
"" == false // true
"1" == true // true
null
类型和undefined
类型与其他类型相比较1
2
3
4
5
6
7
8
9
10
11null == null //true
undefined == undefined //true
null == undefined //true
null == 0 //false
null == false //false
undefined == 0 //false
undefined == false //false
null == [] //false
null == {} //false
unfefined == [] //false
undefined == {} //false
对象与原始类型的相比较
对象与原始类型相比较时,会把对象按照对象转换规则转换成原始类型,再比较。
1 | {} == 0 // false |
{}
的原始值为"[object object]"
,比较变成"[object object]" == 0
,接着根据字符串与数字类型相比较规则,先将字符串转换成数字类型,可知[object object]
转为数字为NaN
,比较变成NaN == 0
,因为NaN
与任何值都不想等,故结果为false
。[]
的原始值为空字符串””,比较变成"" == 0
,接着根据字符串与数字类型相比较规则,先将字符串转换成数字类型,可知""
转为数字为0
,比较变成0 == 0
,故结果为true
。
对象与对象相比较
如果两个对象指向同一个对象,相等操作符返回 true,否则为false。
1 | [] == ![] // true |
四、示例
1 | [] == ![] // true |
1 | undefined == !undefined //false |
1 | [] + [] // "" |
1 | [] + {} // "[object Object]" |
1 | {} + {} //"[object Object][object Object]" |