类型

6种基本类型null undefined number stringify boolean symbol
1种引用类型object

对象转换为基本类型

  • 对象转换为字符串
1
2
3
4
5
6
7
8
9
10
11
//模拟toString返回的不是基本类型值,value0f返回的基本类型值
var obj = {
tostring:function ()
return {}
},

valueof:function (){
return null
}
}
String(obj)//"null"

对象转为数字

先判断valueOf方法, 再判断toString方法

1
2
3
4
5
6
7
8
9
10
//value0f和toString返回的都不是基本类型值
var obj = {
valueof:function (){
return {}
}
toString:function (){
return {}
}
}
Number(obj)//Uncaught TypeError:Cannot convert object to primitive value

Object.create(null)创建的对象没有valueOf和toString方法,因此转换报错
一般情况,我们不会重写valueOf和toString,大部分对象valueOfi返回的仍然是对象,因此对象转换为基本类型值
可以直接看toString返回的值

显式强制类型转换

  • 转换为字符串
    如果对象有自定义toString方法,则返回toString.方法的结果,若是toString返回的结果不是基本类型值,报错TypeError
1
2
3
4
5
6
7
8
var obj = {
toString: function() {
return {}
}
}
String(obj)//Uncaught TypeError:Cannot convert object to primitive value
obj +""//Uncaught TypeError:Cannot convert object to primitive value
obj.toString()//{}

-转换为boolean类型
null undefined false +0 -0 NaN “”
其他情况都是真值

  • 转换为数字类型
1
2
3
4
5
Number('')//0
Number(null)//0
Number(undefined)//NaN
Number(true)//1
Number(false)//0

对象首先被转换为相应基本类型值,再转换

1
2
Number([])//0
// [] value0f返回的是[],因此继续调用toString得到基本类型值"",转换为数字为0

隐式强制类型转换

  • 转换为字符串
1
2
3
4
5
6
7
8
9
var obj = {
valueof:function ()
return 1
},
toString:function ()
return 2
}
}
obj+''//'1'
1
2
3
console.log("123" == 123)
console.log(true == 1)
console.log(false == 0)

x+”,会将x转换为字符串,+运算符其中一个操作数是字符串,会执行字符串拼接操作
对象和字符串拼接时,对象转为基本类型按转为数字转换,先判断valueOf,再判断toString

  • 转换为布尔值

发生布尔值隐式强制类型转换的情况
1.if()语句中的条件判断表达式
2.for(…;…;…)语句中的条件判断表达式(第二个)
3.while()和do..while(..)循环中的条件判断表达式
4.?:中的条件判断表达式
5.逻辑运算符||(逻辑或)和&&(逻辑与)左边的操作数(作为条件判断表达式)

  • 转换为数字类型
1
2
3
4
5
6
7
8
9
10
+'2'//2
'2'-0//2
'2'/1//2
'2'*1//2
+'x'//NaN
'x'-0//NaN
'x'/1//NaN
'x'*1//NaN
1+'2'//12
1++'2'//3即:1+(+2')

优先将数字转为字符串进行拼接

1
2
console.log(3 + '4'); // 输出 "34"
console.log('3' + 4); //输出 "34"
1
2
3
4
5
6
7
8
9
10
11
const obj = {
valueOf() {
return 42;
},
toString() {
return "I am an object";
}
}

console.log(obj + 1);
console.log("Hello, " + obj);
1
2
3
4
5
6
7
8
9
10
11
const obj = {
valueOf() {
return {};
},
toString() {
return "I am an object";
}
}

console.log(obj + 1);
console.log("Hello, " + obj);

当一个操作数是布尔值时,布尔值会被先转换为数字(true被转换为1, false被转换为0),然后按照前面的规则执行加法运算。

1
2
console.log(true + 3); // 4
console.log(false + '3');// "false3"

当一个操作数是null或undefined时,null和undefined分别被转换为数字0和NaN,然后按照前面的规则执行加法运算。

1
2
3
4
console.log(null+2); //2
console.log(undefined+2); //NaN
console.log('Hello, '+ null); //Hello, null
console.log('Hello, '+ undefined);//Hello, undefined
1
2
3
4
5
6
7
8
9
10
11
12
13
//减法运算符的规则
console.log(5 - "2");//3
console.log("5" - 2);//3
console.log(true - 3);//-2
console.log(null - 2);//-2
console.log(undefined - 2);//NaN

//乘法运算符的规则
console.log(5 * "2");//10
console.log("5" * 2);//10
console.log(true * 3);//3
console.log(null * 2);//0
console.log(undefined * 2);//NaN
1
2
3
4
5
console.log(10 / "2"); // 输出5 ('2'被转换为数字2)
console.log("10" / 2); // 输出5 ('10'被转换为数字10)
console.log(true / 2); // 输出0.5 (true被转换为数字1)
console.log(null / 2); // 输出0 (null被转换为数字0)
console.log(undefined / 2); // 输出NaN (undefined被转换为数字NaN)

if语句后的隐式类型转换
以下类型会被转换为false, 其他类型会被转换为true

  • false
  • 0
  • NaN
  • null
  • undefined
  • 空字符串(“”)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
let emptyString = "";
if (emptyString) {
console.log("不执行代码块");
} // 空字符串转换为false,因此不执行代码块

let nonEmptyString = "Hello";
if (nonEmptyString) {
console.log("执行代码块");
} // 非空字符串转换为true,因此执行代码块

let nullValue = null;
if (nullValue) {
console.log("不执行代码块");
} // null转换为false,因此不执行代码块

let objectValue = {};
if (objectValue) {
console.log("执行代码块");
} // 对象转换为true,因此执行代码块
1
2
3
4
5
6
console.log(["1", "2", "3"].map(parseInt))
//[
// 1,
// NaN,
// NaN
//]

==和===

==允许在相等比较中进行强制类型转换,而===不允许
比较规则
1、字符串和数字比较,字符串先转换为数字,再比较
2、其他类型和布尔类型比较,布尔类型转换为数字,再比较
3、对象和非对象比较,对象转换成基本类型值,按转换为数字的流程转换后进行比较。对象转换优先级最高

1
2
3
4
5
6
7
8
9
10
let myObject = {
valueOf() {
return 1;
},
toString() {
return "2"
}
}
console.log(myObject == "2");// false
console.log(myObject == 1);// true

如果一个操作数是对象,另一个操作数是字符串或者数字,会首先调用对象的valueOf方法, 将对象转化为基本类型,再进行比较。

当valueOf()返回的不是基本类型的时候,才会调用toString()方法。

1
2
3
4
5
6
7
8
9
10
let myObject = {
valueOf() {
return {};
},
toString() {
return "2"
}
}
console.log(myObject == "2");// true
console.log(myObject == 1);// false
1
2
3
4
5
6
7
8
9
10
11
12
let a = {
value: 1,
valueOf() {
return this.value++;
},
toString() {
return this.value++;
}
}
if(a == 1 && a == 2 && a == 3){
console.log("条件语句返回值为true");
}

4、null和undefined,nul==undefined,其他类型和null均不相等,undefined也是如此
5、特殊情况

1
2
NaN =NaN /false
-0==+0//true

两个对象比较,判断的是两个对象是否是同一个引用

1
2
3
4
5
6
7
8
9
10
"0"==false //true
//第2条规则,false转换为数字,结果为0,等式变为"0"=0
//两边类型不一致,继续转换,第1条规则,"0”转换为数字,结果为0,等式变为0=0
false =[]//true
//第3条规则,[】转换基本类型值,[].toString(),结果为"",等式变为"=false
//两边类型不一致,继续转换,第2条规则,false转换为数字,结果为0,等式变为"==0
//两边类型不一致,继续转换,第1条规则,"转换为数字,结果为0,等式变为0==0
0=[]//true
//第3条规则,[]转换基本类型值,[].toString(),结果为",等式变为0=""
//两边类型不一致,继续转换,第1条规则,“”转换为数字,结果为0,等式变为0=0