1、其他数据类型转换为number类型
把其他数据类型转换为数字的方法
- 强转换(基于底层机制转换的)Number([value])
- 隐式转换:浏览器内部默认要先转换为Number再进行计算的
- isNaN('12px'); 先把其他类型值转换为数字再检测
- 数学运算 '12'-13;
- 字符串==数字 两个等号的比较很多时候也是要把其他值转换为数字
- 隐式转换:浏览器内部默认要先转换为Number再进行计算的
- 弱转换(基于一些额外的方法转换)
- parseInt([value])
- parseFloat([value])
转换规律
-
parseInt()处理的值是字符串,从字符串的左侧第一个字符开始查找有效数字字符(遇到非有效数字字符则停止查找)。把找到的有效数字字符转换为数字,如果一个都没找到结果就是NaN。如果处理的值不是字符串,需要先转换为字符串然后再开始查找。
-
Number()直接调用浏览器底层的数据类型检测机制来完成
- true => 1
- false => 0
- null => 0
- '' => 0
- undefined => NaN
- 字符串中必须保证全部是有效数字才会转换为数字,否则都是NaN
-
+号运算符遇到字符串(或者对象,因为对象就是先转换为字符串然后再处理),做拼接处理
举个例子
parseInt(''); // NaN => ''不是有效数字
Number(''); // 0
Number(true); // 1
Number(false); // 0
Number(null); // 0
Number(undefined); // NaN
Number('12px'); // NaN => 有无效数字,因此结果为NaN
isNaN(''); // false => isNaN使用Number()隐式转换 => isNaN(0),0是有效数字,因此结果为false
parseInt(null); // NaN => parseInt()把里面的值转换为字符 => parseInt('null') => NaN
isNaN(null); // false => isNaN使用Number()隐式转换 => isNaN(0),0是有效数字,因此结果为false
parseInt('12px'); // 12 => 查找有效数字为止,因此结果为12
isNaN('12px'); // true => isNaN使用Number()隐式转换 => isNaN(NaN),因此结果为true
parseFloat('1.6px') + parseInt('1.2px') + typeof parseInt(null); // "2.6number" => 1.6 + 1 + typeof NaN => 因此结果为"2.6number"
typeof !parseInt(null) + isNaN(null); // 'booleanfalse' => typeof !NaN + false => "boolean" + false => 因此结果为'booleanfalse'
[]==true; // false => 都转换为数字 Number([]) => Number('') => 0,因此 0==1为false
![]; // false => 这是个表达式,先把[]转换为布尔值,只有0,空字符串,null,undefined,NaN
转换为布尔值是false,其他都是true,因此!true取反,结果为false
let res = 10 + false + undefined + [] + 'Tencent' + null + true + {};
console.log(res);
// 10 + 0; // 没有遇到字符串,false转换为0
// 10 + undefined; // 没有遇到字符串,做数学运算,undefined转换为NaN
// NaN + []; // 没有遇到字符串,做数学运算,[]属于对象,于是先通过toString([])把[]转为字符串'',+号遇到字符串做拼接处理,隐藏'NaN'
// 'NaN' + 'Tencent'; // 字符串拼接
// 'NaNTencent' + null; // 字符串拼接
// 'NaNTencentnull' + true; // 字符串拼接
// 'NaNTencentnulltrue' + {}; // Object.prototype.toString({}) => [object Object]
// 结果为 'NaNTencentnulltrue[object Object]'
即使一边是字符串,遇到++/+也不一定是字符串拼接,以下三种情况是数学运算。
let l = '10';
console.log(l++); // 10
let n = '10';
console.log(++n); // 11
let m = '10';
console.log(+m); // 10
其他情况
{}+0; // 0 => 这种情况,{}会被认为是代码块,不参与运算,+0结果就是0
({}+0); // '0[object Object]' => 用括号包起来,是一个整体,就参与数学运算了
0+{}; // '0[object Object]'
+{}; // 'NaN' => +只有右侧有,一定是做数学运算
{}+{}; // 'NaN' => 不理解
let arr = [10, 18, 0, 10, 25, 23];
arr = arr.map(parseInt);
console.log(arr);
有些我以为的但结果并不是的点:
null == 0; // false => 除了undefined,null与其他值都不相等
null == false; // false => 除了undefined,null与其他值都不相等
null == ''; // false => 除了undefined,null与其他值都不相等
undefined == 0; // false => 除了null,undefined与其他值都不相等
undefined == false; // false => 除了null,undefined与其他值都不相等
undefined == ''; // false => 除了null,undefined与其他值都不相等
Number([]); // 0
Number({}); // NaN
Number(); // 0
Number(''); // 0
Number(null); // 0
Number(undefined); // NaN
2、其他数据类型转换为字符串
- 能直接使用的方法
- toString()
- String()
- 隐式转换(一般都是调用其toString)
- 加号运算的时候,如果某一边出现字符串,再去转换为数字
- 把对象转换为数字,需要先toString()转换为字符串,再去转换为数字
- 基于alert/confirm/prompt/document.write等这些方法输出内容,都是要把累充先转换为字符串,然后再输出
把其他类型转换为字符串,一般都是直接用""包起来,只有{}普通对象调取toString是调取Object.prototype.toString,不是转换为字符串,而是检测数据类型,返回结果是"[object Object]"
3、其他数据类型转换为布尔
- 基于以下方法可以把其他数据类型转换为布尔
- ! 转换为布尔值后取反
- !! 转换为布尔类型
- Boolean([value])
- 隐式转换
- 在循环或者条件判断中,条件处理的结果就是布尔类型值
规则:只有0,NaN,null,undefined,空字符串 这五个值会变为布尔值false,其余都是true
4、==运算符比较的转换规律:
- 类型一样的几个特殊点:
- {}=={} => false,对象比较的是堆内存的地址
- []==[] => false
- NaN==NaN => false
- 类型不一样的转换规则
- 对象==字符串 => 对象转化为字符串
- null==undefined => 值为true。但是换成===结果是false(类型不一致),剩下null/undefined和其他任何数据类型值都不相等
- 剩下两边只要类型不同都转换为数字再进行比较
console.log([]==false); // true
// 对象==布尔,都转换为数字(隐式转换)
// 对象转数字,先toString转换为字符串(应该是先基于valueOf获得原始值,没有原始值再去toString),再转换为数字的 -> toString([]) => '' => 0
// false转换为数字为0
// 因此 0==0为true
console.log(![]==false); // true
// !的优先级比==高,先运行左侧
// 左侧是一个表达式,只有0,空字符串,null,undefined,NaN转换为布尔值false,其他都转换为true,因此![]得到结果是false,false与false比较结果为true
[55]==55; // true
// 对象==数字,两边类型不同,转换为数字再进行比较,其中对象先要转为字符串
// 因为[55].toString()结果是'55',在转成数字为55,因此结果是true
5、Object.is([value1], [value2]);
检测两个值是否相等。
Object.is(NaN, NaN); // true