分为
显示强制类型转换和隐式强制类型转换
[] == false结果为ture???
'true' == true结果为false???
[] == ![]结果为true???
[3] - [1]结果为2???
想知道原因吗?下面来一探究竟吧!
显示强制类型转换
自己显示调用类型转换的方法,被称为
显示强制类型转换
转为number
调用
Number(),处理失败返回NaN
number转换为number// 结果不变 console.log(Number(1)); // 1string转换为number// 可解析成数字 -> 数字 console.log(Number('1')); // 1 // 空字符串 -> 0 console.log(Number('')); // 0 里面有空格也是0 // 不可解析成数字 -> NaN console.log(Number('str')); // NaNboolean转换为number// true -> 1 console.log(Number(true)); // 1 // false -> 0 console.log(Number(false)); // 0null转换为number// null -> 0 console.log(Number(null)); // 0undefined转换为number// undefined -> NaN console.log(Number(undefined)); // NaNobject转换为number- 调用自身的
valueOf()(Object的valueOf()如果没有被改写,返回自身)- 返回
基本类型值,对返回值调用Number() - 返回
对象类型值,重新调用自身的toString()- 返回
基本类型值,对返回值调用Number() - 返回
对象类型值,抛出TypeError
- 返回
- 返回
// 模拟 Object 转换数字的过程 var obj = {}; // 调用valueOf() var val = obj.valueOf(); // {} // 返回对象类型,再调用toString() var res = obj.toString(); // '[object Object]' // 返回基本类型 字符串 console.log(Number(res)); // NaN // 与直接调用结果一直 console.log(Number(obj)); // NaN- 调用自身的
Number() 和 parseInt() 的区别是什么?
Number()
Number()是强制转换,转换的字符串中,出现非数字字符会转换失败,返回NaN
console.log(Number('1a')); // NaN
console.log(Number('1.3')); // 1.3
parseInt()
parseInt()是解析,允许解析的字符串中包含非数字字符。从左到右解析,遇到非数字字符就停止。
parseInt()先将参数强制转换成字符串再进行解析(即便传递的是数字)parseInt()方法第二个参数,表示要解析的数字的基数。该值介于 2 ~ 36 之间
console.log(parseInt('1a')); // 1
console.log(parseInt('1.3')); // 1
转为string
调用
String()
number转换为string// 转为对应string console.log(String(1)); // '1'string转换为string// 保持不变 console.log(String('str')); // 'str'boolean转换为string// true -> 'true' console.log(String(true)); // 'true' // false -> 'false' console.log(String(false)); // 'false'null转换为string// null -> 'null' console.log(String(null)); // 'null'undefined转换为string// undefined -> 'undefined' console.log(String(undefined)); // 'undefined'object转换为string- 调用自身的
toString()(数组的toString()是例外,将元素转为字符串后用,连接)- 返回
基本类型值,对返回值调用toString() - 返回
对象类型值,重新调用自身的valueOf()- 返回
简单类型值,对返回值调用toString() - 返回
对象类型值,抛出TypeError
- 返回
- 返回
// 模拟 Object 转换字符产的过程 var obj = {}; // 调用toString() var res = obj.toString(); // '[object Object]' // 返回基本类型 字符串 console.log(res.toString()); // '[object Object]' // 与直接调用结果一直 console.log(String(obj)); // '[object Object]'- 调用自身的
转为boolean
调用
Boolean()或者!!
- 转为
false的值undefinednullNaN-0/+0''
- 转为
true的值- 转为
false之外的值,都转为true
- 转为
转为Array
有两种方法把
类数组或字符串转换为数组
-
.split()
/** * 把 字符串 分割成 字符串数组,不改变原字符串 * * 常用的第一个参数:字符串或正则表达式,从该参数指定的地方分割。 * 若值为''则每个字符之间都会被分割 */ var str = 'ab'; var str1 = 'a, b'; console.log(str.split('')); // [a, b] console.log(str1.split(',')); // [a, b] -
Array.prototype.slice.call()/** .slice()方法根据传递的参数截取数组, * 并把结果以新数组的形式返回,不改变原数组 * * 根据这个特性,可以对非数组形式的数组, * 调用Array的slice方法,实现转换 */ var str = 'ab' var arr = Array.prototype.slice.call(str); console.log(arr); // [a, b] -
Array.from()/** Array.from()方法对一个类似数组或可迭代对象创建一个新的, * 浅拷贝的数组实例 **/ var set = new Set(); set.add('a'); set.add('b'); var arr = Array.from(set); console.log(arr); // [a, b]
隐式强制类型转换
系统默认根据一定的规则,自行转换的模式称为
隐式强制类型转换。
总是返回简单类型值。发生在运行时。
作用:减少冗余,让代码更简洁,但不正确的使用会增加阅读难度,请酌情使用
四则运算的隐式转换逻辑
加(+)
由于
+既能用于数字相加,也能用于字符拼接,所以有两种处理情况
一元形式
+运算符的
一元形式,会把+后的值转换为数字
console.log(+"23333"); // 23333
拼接操作
多个值拼接,其中
有一个值是字符串或可以根据ToPrimitive规则转为字符串,+将进行拼接操作,否则执行number + number
ToPrimitive规则:
- 调用自身的
valueOf()- 返回
基本类型值,对返回值调用toString() - 返回
对象类型值,重新调用自身的toString()- 返回
简单类型值,对返回值调用toString() - 返回
对象类型值,抛出TypeError
- 返回
- 返回
ToPrimitive规则与object转string不同,object转string先调用toString(),再调用valueOf()
var str = 66 + ''; // 或者 '' + 66
console.log(str); // '66'
// 数组转换
var str1 = [1, 2] + [2, 3];
console.log(str1); // '1,22,3'
减乘除(- * /)
-*/只能用于数字运算
console.log('66' - 0); // 66
// 数组转换
var num = [3] - [1];
console.log(num); // 2
var num1 = [3, 1] - [1, 2];
console.log(num1); // NaN
隐式转为Boolean的场景
if()、for()、while()、(三目运算 ? :)、||和&&、===和==
隐式转换的规则与显示转换的规则一致
-
if()和while ():括号内不是boolean,转为boolean -
for (..; ..; ..):第二个位置不是boolean,转为boolean -
? ::?前面不是boolean,转为boolean -
||和&&:左边的操作数,不是boolean,转为boolean -
===和==:操作的结果为boolean宽松相等和严格相等的区别: `===`比`==`强制类型转换确实要多花点时间,但仅仅是微秒级的差别(百万分之一秒)。两者使用相同算法,除了JS引擎实现上的细微差别,两者并没有什么不同
==的隐式转换逻辑
==允许在比较中进行强制类型转换
字符串 == 数字 转换逻辑
字符串的转为数字进行比较
console.log('1.23' == 1.23); // true
其它类型 == 布尔值 转换逻辑
Boolean值转为数字进行比较
会有以下几种情况:
字符串 == 布尔值(走字符串 == 数字 转换逻辑)/** * '0' == false; // false转数字 Number(false) * => * '0' == 0; // '0'转数字 Number('0') * => * 0 == 0; // true */ console.log('0' == false); // true;数字 == 布尔值/** * 0 == false; // false转数字 Number(false) * => * 0 == 0; // true **/ console.log(0 == false); // true;对象 == 布尔值(走对象 == 非对象 转换逻辑)/** * [] == false; // false转数字 Number(false) * => * [] == 0; // []使用ToPrimitive规则 * => * '' == 0; // ''转数字 Number('') * => * 0 == 0; // true */ console.log([] == false); // true;
非对象 == 对象 转换逻辑
有对象,把对象用
ToPrimitive()规则转换成字符串
数字 == 对象/** * 33 == [33]; // [33]使用ToPrimitive规则 * => * 33 == '33'; // '33'转数字 Number('33') * => * 33 == 33; // true */ console.log(33 == [33]); // true字符串 == 对象/** * '33' == [33]; // [33]使用ToPrimitive规则 * => * '33' == '33'; // true */ console.log('33' == [33]); // true
对象 == 对象 转换逻辑
对象是进行
地址比较,不发生强制类型转换
// 会开辟两个空间,地址不同
console.log([1,2] == [1,2]); // false
// 地址相同情况
var a = [1,2];
var b = a;
console.log(a == b); // true
null == undefined 转换逻辑
null == undefinef结果为true,其他值没这种情况。
console.log(null == undefined); // true
// 可以判断a为null和undefined
var a;
console.log(a == null); // true
===的隐式转换逻辑
不允许在相等比较中进行强制类型转换。
先判断类型,类型不同直接false。
建议:(因为会出现一些不能直观理解的场景)
- 两边值中有
true或false不要用== - 两边值中有
[]或0不要用==
常见隐式转换题目
/**1
* 'true' == true; // true转为数字
* =>
* 'true' == 1; // 'true'转为数字
* =>
* NaN == 1; // false
*/
console.log('true' == true); // false
/**2
* [] == ![]; // ![]转为布尔值
* =>
* [] == false; // false转为数字
* =>
* [] == 0; // [] 使用ToPrimitive规则
* =>
* '' == 0; // ''转为数字
* =>
* 0 == 0; // true
*/
console.log([] == ![]); // true
/**3
* [] + []; // []使用ToPrimitive规则
* =>
* '' + ''; // ''
*/
console.log([] + []); // ''
/**4
* [] + {}; // []和{}使用ToPrimitive规则
* =>
* '' + '[object Object]'; // '[object Object]'
*/
console.log([] + {}); // '[object Object]';
/**5
* 根据浏览器不同,有两种情况
* chrome:
* {} + []; // {}和[]使用ToPrimitive规则
* =>
* '[object Object]' + ''; // '[object Object]'
*
* FireFox
* {} + []; // {}被当成代码块执行
* =>
* +[]; // []转为数字
* =>
* +0; // 0
*/
console.log({} + []); // '[object Object]' 或者 0;
/**6
* 根据浏览器不同,有两种情况
* chrome:
* {} + {}; // {}使用ToPrimitive规则
* =>
* '[object Object]' + '[object Object]'; // '[object Object][object Object]'
*
* FireFox:
* {} + {}; // 第一个{}被当成代码块
* =>
* + {}; // {}转为数字
* => +NaN; //NaN
*/
console.log({} + {}); // '[object Object][object Object]' 或者 NaN
/**7
* true + true; // 此情况执行number + number。true转为数字
* =>
* 1 + 1; // 2
*/
console.log(true + true); // 2
/**8
* 1 + { a: 1 }; // { a: 1 }使用ToPrimitive规则
* =>
* 1 + '[object Object]'; // 1转为字符串
* =>
* '1' + '[object Object]'; // '1[object Object]'
*/
console.log(1 + { a: 1 }); // '1[object Object]'
如果觉得内容对你有帮助,请点个赞和关注,你们的鼓励是我持续更新下去的动力,比心。
如需转载请注明出处,感恩。
更多内容可先关注GitHub