隐式转换介绍
· 1.2 隐式转换规则
· 1.3 坑一:字符串连接符与算术运算符隐式转换规则混淆
· 1.4 坑二:关系运算符:会把其他数据类型转换成number之后再比较关系
· 1.5 坑三:复杂数据类型在隐式转换时会先转成String,然后再转成Number运算
· 1.6-坑四:逻辑非隐式转换与关系运算符隐式转换搞混淆
1.1-隐式转换介绍
· 在js中,当运算符在运算时,如果两边数据不统一,CPU就无法计算,这时我们编译器会自动将运算符两边的数据做一个数据类型转换,转成一样的数据类型再计算
o 这种无需程序员手动转换,而由编译器自动转换的方式就称为隐式转换
· 例如1 > "0"这行代码在js中并不会报错,编译器在运算符时会先把右边的"0"转成数字0`然后在比较大小
1.2-隐式转换规则
1. 转成string类型:
+(字符串连接符)
2..转成number类型:
++ / --(自增自减运算符)
+ - * / %(算术运算符)
> < >= <= = = != = = = != = = (关系运算符)
3. 转成boolean类型:!(逻辑非运算符)
1.3-坑一:字符串连接符与算术运算符隐式转换规则混淆
· 常见面试题如下
·
原理分析
1.4-坑二:关系运算符:会把其他数据类型转换成number之后再比较关系
常见面试题如下
· 原理分析
charCodeAt() 方法可返回指定位置的字符的 Unicode 编码。
console.log(NaN==NaN)//false
1.5-坑三:复杂数据类型在隐式转换时会先转成String,然后再转成Number运算
var a = ? ? ? ;
if (a == 1 && a == 2 && a == 3) {
console.log(1)
}
· 原理分析
1.6-坑四:逻辑非隐式转换与关系运算符隐式转换搞混淆
· 前方高能,请注意~
o 空数组的toString()方法会得到空字符串,而空对象的toString()方法会得到字符串`[object Object]` (注意第一个小写o,第二个大写O哟)
· 常见面试题
·
原理分析
在什么条件下会触发隐式转换机制?
在进行比较运算,或者进行四则运算时,常常会触发JS中的隐式转换机制。
首先要记住JS设计者的初衷是美好的,他希望 == 是美好的操作选择,但是在美好的希望也是希望。
小案例
- 为什么 [] == false ?
- 类型不同比较时,需要先做类型转换,==比较时有布尔值参与时,需要比较双方均转为数字,[ ]是非原值,需要转换为原值二者才能进行比较,大部分对象转换为原值最后都是调用的toString方法,[] --> toString() —> ‘’,当字符串和数字比较时,会把字符串转换为数字,而空字符串转换为数字结果是0,而 0 == 0,所以结果为true
- 为什么NaN ! = = NaN?
- 这是隐式转换的一个很大的弊端,es6的includes方法可以检测出NaN等于NaN,这是一大进步 ES6提供了一个新的 Number.isNaN() 函数
- null = = 0 结果为false
- 这时候两边的类型也不同,但是却没有做类型转换,why?因为这时候二者都已经是基本数据类型了,没有办法在进行转换了,所以二者的类型都不可能相同,结果自然为false
- 为什么null = = undefined 结果为true
- 这是一种规定
if x is null and y is undefined, return true
if y is null and x is undefined, return true - 为什么 !![] = true
这里并没有涉及 = = 比较,只需要判断 [] 是true还是false即可
注意,字符串转换为数字调用的是Number方法,NaN也是数字,某些方面来说布尔类型也属于一种int类型
隐式转换的最大弊端
NaN不等于NaN
几种为false的情况,只要不是这几组值,结果均为true
0,’’,NaN,false,null,undefined, -0,document.all()
涉及隐式转换最多的两个运算符
+ ,==
三种隐式转换
- 将值转为原始值
- 将值转为数字
- 将值转为字符串
>[]+[]
>" "(空的什么都没有)
加号操作符会将preferedType看成Number,调用ES内部的toPrimitive(input,Number)方法,得到空字符串
>[]+{}
>"[object Object]"
最终会调用双方的toString()方法,再做字符串加法
>{}+[]
>"[object Object]"
主要因为是复杂数据类型,先调用valueOf()再调用toString()方法
{}转换后变成‘’(空字符)
[]转换后变成"[object Object]"
所以是"[object Object]"
总结:
相关面试题有
1.
var a = ? ? ? ;
if (a == 1 && a == 2 && a == 3) {
console.log(1)
}
答案:
var a = {
i: 0,
valueOf: function() {
return ++a.i
}
};
2.if (x = = !x) {
console.log('yeah');
}
答案 []==![]
var x = new Boolean(false);
if (x == !x) {
console.log('yeah');
}
2.if (a = = true && a = = false) {
console.log('yeah');
}
答案:
var a = {
flag: false,
toString() {
return this.flag = !this.flag;
}
}
或者使用 valueOf():
var a = {
flag: false,
valueOf() {
return this.flag = !this.flag;
}
}
if (a = = true && a = = false) {
console.log('yeah');
}