JS数据类型转换规则
JS的数据类型
基本数据类型(七种)
- Number
- String
- Boolean
- Null
- Undefined
- Symbol
- BigInt
- BigInt数据类型的目的是比Number数据类型支持的范围更大的整数值以任意精度表示整数的能力尤为重要。
- JS 中的Number类型只能安全地表示-9007199254740991和9007199254740991之间的整数
- 使用BigInt,整数溢出将不再是问题。
-
// JS提供Number.MAX_SAFE_INTEGER常量表示最大安全整数,Number.MIN_SAFE_INTEGER常量表示最小安全整数。 const minInt = Number.MIN_SAFE_INTEGER; console.log(minInt); //-9007199254740991 console.log(minInt - 5); //-9007199254740996 // 注意它是如何输出与上面相同的值的 console.log(minInt - 4); // -9007199254740996 console.log(9999999999999999); //10000000000000000 // 注意最后一位的数字 9007199254740992 === 9007199254740993; //true // 解决方案:使用BigInt数据类型 // 要创建BigInt,只需在整数的末尾追加n即可。比如: console.log(9007199254740995n); //9007199254740995n console.log(9007199254740995); //9007199254740996 // 或者可以调用BigInt()构造函数 BigInt("9007199254740995"); //9007199254740995n
引用数据类型(一种)
- Object
- function、array、date日期等...都归属于Object
==和===的区别
-
===
- 如果类型不同返回false,如果类型相同则比较值是否相同。
-
==
- 如果是类型相同,直接进行===比较,如果类型不同,要进行隐式类型转换(下列是转换规则)再比较。
操作符==两边的隐式转换规则
如果两边数据类型不同,需要先转为相同类型,然后再进行比较,以下几种情况需要注意一下:
1、对象==字符串
console.log([1,2,3]=='1,2,3'); // true
// 比较机制
console.log(obj[Symbol.toPrimitive]) //undifined
console.log(obj.valueOf()) // (3) [1, 2, 3]
console.log(obj.toString()) // '1,2,3'
console.log('1,2,3' === '1,2,3'); // true
- 先调用对象的 Symbol.toPrimitive 这个方法,如果不存在这个方法
- 再调用对象的 valueOf 获取原始值,如果获取的值不是原始值
- 再调用对象的 toString 把其变为字符串
- 最后再把字符串基于Number()方法转换为数字
什么是原始值?
答:原始类型(基本数据类型)的值即为原始值,一共有7种,分别是Number、String、Boolean、Null、Undefined、BigInt、Symbol。
2、null/undefined
console.log(null == undefined) // true
console.log(null === undefined) // false
// null/undefined和其他任何值都不相等
3、对象==对象
比较的是堆内存地址,地址相同则相等。
console.log({} == {}); // false 因为比较的是地址
4、NaN
除了以上情况,只要两边类型不一致,剩下的都是转换为数字,然后再进行比较。
JS数据类型转换规则
显式类型转换
通过函数String()、Number()、Boolean() 进行类型转换的机制。
String()
// 基本数据类型通过String()转换后的结果
// 无论什么数据类型,String都转成字符串
console.log(String(1)); // '1'
console.log(String('abc')); // 'abc'
console.log(String(true)); // 'true'
console.log(String(false)); // 'false'
console.log(String(null)); // 'null'
console.log(String(undefined)); // 'undefined'
console.log(String(Symbol(1))); // 'Symbol(1)'
console.log(String(5n)); // '5'
Number()
// 基本数据类型通过Number()转换后的结果
// ''、null、false都转成0
// 数字字符串转成相应的数字,非数字字符串和对象类型转成了NaN
// true转成1、false转成0
// Symbol转成数字会报错
// BigInt去除“n”
console.log(Number(1)); // 1
console.log(Number('')); // 0
console.log(Number('123')) // 123
console.log(Number('abc')); // NaN
console.log(Number(true)); // 1
console.log(Number(false)); // 0
console.log(Number(null)); // 0
console.log(Number(undefined)); // NaN
console.log(Number(Symbol(1))); // test.html:36 Uncaught TypeError: Cannot convert a Symbol value to a number
console.log(Number(5n)); // 5
console.log(Number({a:1})); // NaN
对象转换为数字,会按照下面的步骤去执行:
- 先调用对象的 Symbol.toPrimitive 这个方法,如果不存在这个方法
- 再调用对象的 valueOf 获取原始值,如果获取的值不是原始值
- 再调用对象的 toString 把其变为字符串
- 最后再把字符串基于Number()方法转换为数字
let obj ={
a: 1
}
//运行机制
console.log(obj[Symbol.toPrimitive]) //undifined
console.log(obj.valueOf()) // {a: 1}
console.log(obj.toString()) // [object Object]
console.log(Number("[object Object]")) // NaN
Boolean()
// 基本数据类型通过Boolean()转换后的结果
// 数字0、''、null、undefined会转成false,其余都为true
console.log(Boolean(0)); // false
console.log(Boolean(-1)); // true
console.log(Boolean(1)); // true
console.log(Boolean('')); // false
console.log(Boolean('abc')); // true
console.log(Boolean(true)); // true
console.log(Boolean(false)); // false
console.log(Boolean(null)); // false
console.log(Boolean(undefined)); // false
console.log(Boolean(Symbol(1))); // true
console.log(Boolean(5n)); // true
console.log(Boolean({a:1})); // true
隐式类型转换
隐式类型类型转换大多发生在操作符当中, 比如宽松相等操作符==两端的类型不同的时候, 会发生隐式类型转换。
转成string类型
隐式转换通常在有 + 运算符并且有一个操作数是 string 类型时被触发。
“+”代表的字符串拼接,如果下面的情况存在时会触发转换。
- 1、有两边,一边是字符串,则会变成字符串拼接。
- 2、有两边,一边是对象。
console.log(1 + '123'); // "1123"
console.log(1 + {}); // "1[object Object]"
转成number类型
number 的隐式类型转换比较复杂,因为它可以在下面多种情况下被触发:
- 比较操作(>, <, <=, >=)
- 按位操作(| & ^ ~)
- 算数操作(- + * / %)
- 注意:当 + 操作存在任意的操作数是 string 类型时,不会触发 number 类型的隐式转换
- 一元 + 操作
- 一元加操作符以一个加号表示,放在数值前面,对数值不会产生任何影响。
- 在对非数值应用一元加操作符时,该操作符会像 Number()转型函数一样对这个值执行转换。也就是说,布尔值 false 和 true 将被转换为 0 和 1,字符串值会被按照一组特殊的规则进行解析。
- 而对象是先调用它们的 valueOf()和(或)toString()方法,再转换得到的值。
转成boolean类型
隐式类型转换通常在逻辑判断或者有逻辑运算符时被触发(|| && !)。
if(2) {} // 逻辑判断触发隐式类型转换
console.log(!!2) // true
console.log(2 || 'hello') // 相当于 true || 'hello',结果并不是true,而是2
// 因为逻辑运算符(比如 || 和 &&)是在内部做了 boolean 类型转换,但实际上返回的是原始操作数的值,即使他们都不是 boolean 类型。
// 返回 number 类型 2,而不是 boolean 型 true
面试题
let result = 100 + true + 21.2 + null + undefined + "Tencent" + [] + null + 9 + false;
// result应该是?
// 答:NaNTencentnull9false