分为
显示强制类型转换
和隐式强制类型转换
[] == false
结果为ture???
'true' == true
结果为false???
[] == ![]
结果为true???
[3] - [1]
结果为2???
想知道原因吗?下面来一探究竟吧!
自己显示调用类型转换的方法,被称为
显示强制类型转换
调用
Number()
,处理失败返回NaN
number
转换为number
// 结果不变 console.log(Number(1)); // 1
string
转换为number
// 可解析成数字 -> 数字 console.log(Number('1')); // 1 // 空字符串 -> 0 console.log(Number('')); // 0 里面有空格也是0 // 不可解析成数字 -> NaN console.log(Number('str')); // NaN
boolean
转换为number
// true -> 1 console.log(Number(true)); // 1 // false -> 0 console.log(Number(false)); // 0
null
转换为number
// null -> 0 console.log(Number(null)); // 0
undefined
转换为number
// undefined -> NaN console.log(Number(undefined)); // NaN
object
转换为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()
是强制转换,转换的字符串中,出现非数字字符会转换失败,返回NaN
console.log(Number('1a')); // NaN
console.log(Number('1.3')); // 1.3
parseInt()
是解析,允许解析的字符串中包含非数字字符。从左到右解析,遇到非数字字符就停止。
parseInt()
先将参数强制转换成字符串
再进行解析(即便传递的是数字)parseInt()
方法第二个参数,表示要解析的数字的基数。该值介于 2 ~ 36 之间
console.log(parseInt('1a')); // 1
console.log(parseInt('1.3')); // 1
调用
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()
或者!!
- 转为
false
的值undefined
null
NaN
-0
/+0
''
- 转为
true
的值- 转为
false
之外的值,都转为true
- 转为
有两种方法把
类数组
或字符串
转换为数组
-
.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
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 == 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]'