02 JS 中的数据类型转换规则
1、把其它类型「原始值」转为对象
js
// 方法:
Object([value])2、其它类型转为数字
js
// 1. Number([value])
* 隐式转换「数学运算、isNaN、==比较」
* 字符转 ->> 数字:
空字符串对应的结果是 0
只要字符串中包含非有效数字,结果就是 NaN
* 布尔 ->> 数字:
true ->> 1
false ->> 0
* null ->> 0
* undifined ->> NaN
* Symbol ->> 报错
* 对象 ->> 数字:
遵循规则:Symbol.toPrimitive/valueOf/toString
// 2. parserInt([value]) / parseFloat([value])
首先会把[value]变为字符串,从字符串左侧第一个字符开始查找,
直到找到一个非有效数字字符为止,把找到的结果转换为数字,
一个都没找到,结果就是NaN「parseFloat多识别一个小数点」3、把其它类型转换为字符串
js
// 1. 原始值直接用引号包起来「BigInt去除n」,对象转为字符串是比较特殊的
// 2. toString「排除Object.prototype.toString(检测数据类型用的)」
// 3. 字符串/模板字符串拼接「‘+’号除了数学运算还有字符串拼接(其他运算符一般都是数学运算)」
// CASE1: "+"号只有一边
let n = '10'
console.log(+n) // 转换为数字
console.log(++n) // 11: 转换为数字后累加1
console.log(n++) // 10: 转换为数字后累加1
let i = 10;
console.log(5 + (++i)); //先i累加1,累加后的结果运算 16 i->11
console.log(5 + (i++)); //先运算 再累加1 15 i->11
// CASE2: “+”号有一边出现对象
let n = 10;
{}+n ->> 10 把左侧的{}当做代码块,不参与运算,运算的只有 +n
n+{} ->> '10[object Object]' 字符串拼接
// CASE3: 不是所有对象都是字符串拼接
// 规则:
* 先去调取对象的 Symbol.toPrimitive 属性值,如果没有这个属性
* 再去调取对象的 valueOf 获取原始值,如果不是原始值
* 再去调用对象的 toString 转换为字符串「如果是想转换为数字,则还会调用Number处理」
console.log(10 + [10, 20]);
[10, 20][Symbol.toPrimitive] ->> undefined
[10, 20].valueOf() ->> [10, 20] (非原始值)
[10, 20].toString() ->> "10,20"
10 + [10, 20] = 10 + "10,20" = "1010,20"
console.log(10 + new Number(10));
new Number(10)[Symbol.toPrimitive] ->> undefined
new Number(10).valueOf() ->> 10 (是原始值)
10 + new Number(10) = 10 + 10 = 20
console.log(+new Date()); // 1629171828461
let obj = { x: 10 }
console.log(10 + obj) ->> "10[object Object]"
let obj2 = {
x: 10,
[Symbol.toPrimitive](hint) {
return this.x
}
}
console.log(10 + obj2) // 20
// “+”左右两边,有一边出现了 字符串或者部分对象 则都是按照字符串拼接处理的
console.log(1 + 1); //->2
console.log(1 + '1'); //->'11'
console.log(1 - '1'); //->04、其他类型转为布尔类型
js
// 1. 规则:
只有 0、-0、null、undifined、空字符串、NaN 这几个结果是false,其余都是true
// 2. 转换方式
* Boolean([value])
* ![value]
* 条件判断:例如:if([value])
* A || B, A && B(逻辑或,逻辑与)练习
let result = 100 + true + 21.2 + null + undefined + "Tencent" + [] + null + 9 + false;
- 101 + 21.2 + null + undefined + "Tencent" + [] + null + 9 + false
- 122.2 + null + undefined + "Tencent" + [] + null + 9 + false
- 122.2 + undefined + "Tencent" + [] + null + 9 + false
- NaN + "Tencent" + [] + null + 9 + false
- "NaNTencent" + [] + null + 9 + false
- "NaNTencent" + null + 9 + false
- "NaNTencentnull" + 9 + false
- "NaNTencentnull9" + false
- "NaNTencentnull9false"
let a = ? if (a == 1 && a == 2 && a == 3) { console.log('OK'); }
js
// 方法一
let a = {
i: 1,
[Symbol.toPrimitive](hint) {
return this.i++
}
}
// 方法二
let a = [1, 2, 3]
a.toString = a.shift
// 方法三:我们可以劫持对象的成员访问
// + 全局下声明的变量是window的一个属性
// + Object.defineProperty数据劫持的办法
let i = 0
Object.defineProperty(window, a, {
get() {
return ++i
}
})