js隐式类型转换学习总结
本文于986天之前发表,文中内容可能已经过时。
为什么会写这篇博客,因为自己类型转换规则实在记不住,直接先看练习题,都没问题就直接pass。
前置知识点:
- js基本数据类型比较的是值是否相等
- js引用数据类型比较的是引用的地址是否相等
==比较会进行类型转换,===必须类型相同值也相等
==比较类型转换规则:
首先排除特殊的
null,undefined类型:1
2
3null == undefined; // true
0 == undefined; // false
0 == null; // false比较双方的类型相同,则进行值的判断:
1
[] == []; // false(类型相同但引用的地址不同)
比较双方的类型不同,进行类型转换,规则如下:
若其中一方为
object且另一方为string、number或者symbol, 将object转为基本类型再进行判断1
2
3
4[] == ''; // true
[] == 0; // true
[null] == 0; // true
[undefined] == 0; // true若其中一方为
boolean, 将boolean转为number再进行判断1
2true == 1; // true
false == 0; // true若双方类型为
string和number, 将string转换成number1
'12' == 12; // true
object转换成基本类型规则:
object这种复杂类型转换成基本类型时,会调用对象的valueOf和toString方法。
1 | {}.toString(); // '[object Object]' |
valueOf和toString方法调用顺序:
- 若显示定义了
[Symbol.toPrimitive]属性,只调用该接口,若返回的不是基本数据类型,抛出错误。- 默认的调用规则:
- 非
Date类型对象,hint是default时,调用顺序为:valueOf>>>toString,即valueOf返回的不是基本数据类型,才会继续调用toString,如果toString返回的还不是基本数据类型,那么抛出错误。- 如果
hint是string(Date对象默人的hint是string) ,调用顺序为:toString>>>valueOf,即toString返回的不是基本数据类型,才会继续调用valueOf,如果valueOf返回的还不是基本数据类型,那么抛出错误。- 如果
hint是number,调用顺序为:valueOf>>>toString。
1 | (new Date()).toString(); // 'Sun Jun 30 2019 16:53:46 GMT+0800 (中国标准时间)' |
关于
hint,[Symbol.toPrimitive]示例可访问上文引用链接
关于[Symbol.toPrimitive]可参考:- 阮一峰·ECMAScript 6 入门
string转换成number规则:
Number()和parseInt()方法
1 | Number('12abc'); // NaN |
parseInt()经典面试题
String()和toString()方法
1 | undefined.toString(); // TypeError: Cannot read property 'toString' of undefined |
radix为2时,NumberObject会被转换为二进制值表示的字符串1
2var num = 13;
console.log(num.toString(2));
typeof判断类型:
typeof方法返回值:undefined, boolean, number, string, symbol, function, object
1 | typeof null; // 'object' |
练习题
[]开辟了一块堆内存,地址存在栈内存,![]返回false1
2
3if ([]) {
... // true
}比较双方的类型相同,则进行值的判断,栈内存地址不同
1
2[] == []; // false
{} == {}; // false解题参考:- 【面试篇】寒冬求职季之你必须要懂的原生JS(上)
1
2
3[] == ![] // true
{} == !{} // false
{} == '[object Object]' // true
疑惑:文中最后一步Number([])确实为0,但是和object转换成基本类型规则:似乎有冲突。
- 运算符进行隐式类型转换
1
2
3
4
5
6
7
8
9
10
11
12
13
14'12' + 1; // '121'(String)
1 + 'true'; // '1true'
1 + true; // 2
1 + undefined; // NaN
1 + null; // 1
'12' * 1; // 12(Number)
'12' - 1; // 11(Number)
'a' - 1; // NaN
2 > '10'; //false
'2' > '10'; // true
'abc' > 'b'; // false
'abc' > 'aad'; // true
[] + {}; // '[object Object]'
[] + []; // ''
- 字符串连接符
+:只要+号两边有一边是字符串 - 算术运算符
+:+号两边都是数字
特殊类型比较
null,undefined,NaN的比较1
2
3undefined == null; // true
NaN == NaN; // false
NaN == null; // falseCan (a== 1 && a ==2 && a==3) ever evaluate to true?
1
2
3if (a == 1 && a == 2 && a == 3) {
// ...
}
解答:
- 利用数组的
toString会隐含调用Array.join方法
1 | a = [1,2,3]; |
- 重写
Object的toString或者valueOf
1 | const a = { |
参考文章:
微信打赏
赞赏是不耍流氓的鼓励