4.1 转换为Number类型
把其他数据类型转换为Number类型
* 1.特定需要转换为Number的
* + Number([val])
* + parseInt、parseFloat([val])
*
* 2.隐式转换(浏览器内部默认要先转换为Number在进行计算的)
* 【基本上都是基于Number([val])来完成的】
* + isNaN([val]) 【isNaN会调用Number(),对val进行隐式转换。】
* + 数学运算(特殊情况:+ 在出现字符串的情况下不是数学运算,是字符串拼接)
* + 在 == 比较的时候,有些值需要转换为数字再进行比较
* + ...
* .......
// ------ Number([val])规则 ------
// 1、把字符串转换为数字,要求字符串中所有字符都必须是有效数字才能转换
console.log(Number("")); // 0
console.log(Number("10")); // 10
console.log(Number("10px")); // NaN
// 2、把布尔转换为数字
console.log(Number(true)); // 1
console.log(Number(false)); // 0
// 3、把空转换为数字
console.log(Number(null)); // 0
console.log(Number(undefined)); // NaN
// 4、把Symbol/BigInt转换为数字
console.log(Number(Symbol(''))); // 不允许转换
console.log(Number(BigInt(10))); // 10
// 5、把对象或者函数转换为数字(先基于toString把对象转换为字符串,再把字符串转换为数字)
console.log(Number({0: 10})); // NaN => 普通对象.toString()是检测数据类型"[object Object]",再转换为数字NaN
console.log(Number([10])); // 10 => 数组.toString()是转换为字符串"10"
console.log(Number([10, 20])); // NaN => "10,20"
console.log(Number([])); // 0 => ""
// ------ parseInt/parseFloat([val])规则 ------
// parseInt/parseFloat([val]) 规则:先把[val]值转换为字符串,再按照从字符串左边第一个字符开始查找,把所有找到的有效数字字符变为数字(直到遇到一个非有效的数字字符则停止查找),如果一个有效数字字符都没有找到,返回结果就是NaN(parseFloat只是比parseInt多识别一个小数点而已)
console.log(parseInt("10px12")); // 10
console.log(parseInt("10.5px")); // 10,parseInt不认小数点
console.log(parseFloat("10.5px")); // 10.5
console.log(parseInt("10px")); // NaN
4.2 转为字符串类型
/*
* 把其它数据类型转换为字符串
* 1. 能使用的办法
* + toString()
* + String()
*
* 2. 隐式转换(一般都是调用其toString)
* + 在加号运算的时候,如果加号的某一边出现字符串,则不是数学运算,而是字符串拼接
* + 把对象转换为数字,需要先toString()转换为字符串,再去转换为数字
* + 基于alert、confirm、prompt、document.write...这些方式输出内容,都是把内容先转换为字符串,然后再输出的
* + ...
* ............
* 除了“普通对象.toString()”是检测数据类型(因为他们调用的是Object.prototype.toString,这个方法是检测数据类型的),其余的都是调用自己类原型上的toString,也就是用来转换字符串的。
console.log(1 + "10"); // "110"
console.log(1 + [10]); // "110" [10].toString() => "10"
let result = 10 + false + undefined + [] + 'Tencent' + null + true + {};
console.log(result);
// 10 + false => 10
// 10 + undefined => NaN
// NaN + [] => "NaN"
// "NaN" + 'Tencent' => "NaNTencent"
// ...
// "NaNTencentnulltrue[object Object]"
4.3 转为布尔类型
/*
* 把其它数据类型转换为布尔
* 1. 基于以下方式可以把其它数据类型转换为布尔
* + ! : 转换为布尔值后,取反
* + !! : 转换为布尔类型
* + Boolean([val])
* 2. 隐式转换
* + 在循环或者条件判断中,条件处理的结果就是布尔类型值
* + ...
*
* 规则:只有 ‘0、NaN、null、undefined、空字符串’ 五个值会变为布尔的false,其余都是true
*/
console.log(!0); // true
console.log(!!0); // false
console.log(!![]); // true
if (1) {
// 要把1先转换为布尔,验证真假
}
// !!({}) true 验证是否为空对象
function isEmptyObject(obj) {
if (obj === null || typeof obj !== "object") return false;
let flag = true;
for (let key in obj) {
if (!obj.hasOwnProperty(key)) break;
flag = false;
break;
}
return flag;
}
4.4 综合题
parseInt("") // NaN
Number("") // 0
isNaN("") // false isNaN(Number("")) -> isNaN(0)
parseInt(null) // NaN parseInt("null")
Number(null) // 0
isNaN(null) // false isNaN(Number(null)) -> isNaN(0)
parseInt("12px") // 12
Number("12px") // NaN
isNaN("12px") // true
parseFloat("1.6px") + parseInt("1.2px") + typeof parseInt(null)
// 1.6 + 1 + "number" => "2.6number"
isNaN(Number(!!Number(parseInt("0.8"))))
// parseInt("0.8") -> 0
// !!Number(0) -> false
// Number(false) -> 0
// isNaN(0) -> false
typeof !parseInt(null) + !isNaN(null)
// MDN优先级:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Operator_Precedence
// typeof !parseInt(null) -> "boolean"
// !isNaN(null) -> true
// "booleantrue"
4.5比 较操作:、=
/*
* 在JS中的比较操作有两种:、=
* ==:比较
* =:绝对比较(switch case基于=比较的)
*
* 如果左右两边数据类型不一致,会默认把数据类型转换为一致的,再去进行比较;= 则直接返回false,因为它要求数据类型和值都一样才相等(严谨);
*
* 在 == 比较的过程中,数据转换的规则:
* 【类型一样的几个特殊点】
* {} == {}:false 对象比较的是堆内存的地址
* [] == []:false
* NaN == NaN:false
*
* 【类型不一样的转换规则】
* 1. null == undefined:true;但是换成 ===,结果是false(因为类型不一致);剩下null、undefined和其它任何数据类型值都不相等
* 2. 字符串 == 对象:要把对象转换为字符串
* 3. 剩下的,如果 == 两边数据类型不一致,都是需要转换为数字,再进行比较
*/
console.log(2 == true); // false => 2 == 1
console.log([] == false); // true
// 规则:比较过程中,两边数据值不一样,都转换为数字再比较
// 0 == 0
console.log(![] == false); // true
// 规则:先算![] => false
// false == false
let result = 100 + true + 21.2 + null + undefined + "Tencent" + [] + null + 9 + false; // 这里的数组[]不会调用 Object.prototype.toString,对象{}才会
console.log(result); // NaNTencentnull9false
{} + 0 、 ({} + 0)的解析:
1、大括号{}中间有木有空格,都一样。
2、大括号{}前面有圆括号(),则{}是对象;否则,是代码块。
3、代码块和后面的代码无关,相当于换行。
0 + {} 、 (0 + {}) 的解析:
1、大括号{}中间有木有空格,都一样。
2、有没有圆括号包裹,{}都是对象,先调用 Object.prototype.toString,转为字符串。
总结:只有大括号{}前面没有圆括号()时,即{} + 0,是代码块,其他都是对象
// 把{}当成代码块 【function fn() {} + 0】
{ } + 0 ? console.log('ok') : console.log('no');
// 放在右侧,把{}当成对象
0 + {} ? console.log('ok') : console.log('no');
let res1 = {} + 0 ? 11 : 22;
let res2 = 0 + {} ? 55 : 66;
console.log(res1, res2); // 11 55
console.log({} + 0 ? 11 : 22); // 11
console.log(0 + {} ? 55 : 66); // 55
{ } + 0 ? alert('ok') : alert('no'); // no
0 + {} ? alert('ok') : alert('no'); // ok
{ } + 0 ? console.log('ok') : console.log('no'); // no
0 + {} ? console.log('ok') : console.log('no'); // ok
let arr = [10.18, 0, 10, 25, 23];
arr = arr.map(parseInt);
console.log(arr); // [10, NaN, 2, 2, 11]
// 我的推导
// parseInt('10.18', 0) => 10
// parseInt('0', 1) => NaN,进制不在2到36之间,结果为NaN
// parseInt('10', 2) => 0 * 2^0 + 1 * 2^1 = 2
// parseInt('25', 3) => 2 *3^0 = 2
// parseInt('23', 4) => 3 + 8 = 11