数据类型及相互间的转换规则
2025年4年9日 · 1259 字
一、ECMA262 数据类型的详细剖析
二、数据类型的标准定义
ECMAScript 是基于对象的语言。它的值分为两类:
原始值类型(值类型 / 基本数据类型)
number
:数字string
:字符串boolean
:布尔值null
:空对象指针undefined
:未定义symbol
:唯一值bigint
:大整数
引用类型(对象类型)
- 标准普通对象:
object
- 标准特殊对象:
Array
、RegExp
、Date
、Math
、Error
- 非标准特殊对象:
Number
、String
、Boolean
... - 可调用/执行对象(函数):
function
三、Symbol和BigInt的实践运用
-
Symbol 创建一个唯一值
- 给对象设置“唯一值”的属性名
- 字符串
- Symbol类型
- Map新的数据结构:可以允许属性名是对象
- Symbol.asyncIterator/iterator/hasInstance/toPrimitive/toStringTag...是某些JS知识底层实现的机制
- 在派发行为标识统一进行管理的时候,可以基于symbol类型的值,保证行为标识的唯一性
- 给对象设置“唯一值”的属性名
-
BigInt 大数类型
-
Number.MAX_SAFE_INTEGER 9007199254740991 JS中的最大安全数
-
Number.MIN_SAFE_INTEGER -9007199254740991 最小安全数
-
超过安全数后,进行运算或者访问,结果会不准确!!!
-
解决方案:
- 服务器返回给客户端的大数,按照“字符串”格式返回!
- 客户端把其变为 BigInt ,然后按照BigInt进行运算
- 最后把运算后的BigInt转换为字符串,在传递给服务器即可
-
四、typeof 数据类型检测的机制
- 所有的数据类型值,在计算机底层都是按照 “64位” 的二进制值进行存储的!
- typeof是按照二进制值进行检测类型的
- 二进制的前三位是零,认为是对象,然后再去看有么有实现call方法,如果实现了,返回 'function',没有实现,则返回 'object'
- null是64个零 typeof null -> 'object' 「局限性」
- 检测未被声明的变量,值是'undefined'
console.log(a); //Uncaught ReferenceError: a is not defined
console.log(typeof a); //'undefined'
typeof typeof typeof [1,2,3]; // "string"
五、数据类型之间的转换规则
1.把其他数据类型转换为 Number
Number(val); // 浏览器中的隐式转换
一般用于浏览器的隐式转换中
1.数学运算 --- 2.isNaN检测 --- 3.==比较
转换规则:
- 字符串:空字符串转 0,非数字字符为 NaN
- 布尔:true → 1,false → 0
- null → 0,undefined → NaN
- Symbol → 报错(无法转换为数字)
- BigInt → 去除 n 后转换(超过安全数字的,会按照科学计数法处理)
- 对象 → 调用
Symbol.toPrimitive
→valueOf
→toString
→ 转为 Number- 先调用对象的 Symbol.toPrimitive 这个方法,如果不存在这个方法
- 再调用对象的 valueOf 获取原始值,如果获取的值不是原始值
- 再调用对象的 toString 把其变为字符串
- 最后再把字符串基于Number方法转换为数字
parseInt/parseFloat
parseInt([val],[radix]) / parseFloat([val])
- 一般用于手动转换
- 规则:[val]值必须是一个字符串,如果不是则先转换为字符串;然后从字符串左侧第一个字符开始找,把找到的有效数字字符最后转换为数字「一个都没找到就是NaN」;遇到一个非有效数字字符,不论后面是否还有有效数字字符,都不再查找了;parseFloat可以多识别一个小数点;
练习题
let arr = [27.2, 0, '0013', '14px', 123];
arr = arr.map(parseInt); // 思考输出结果
2.把其他数据类型转换为 String
String(val); // 或 val.toString()
转化规则:
- 拿字符串包起来
- 特殊:Object.prototype.toString
出现情况:
- String([val]) 或者 [val].toString()
- “+”号 除数学运算,还可能代表的字符串拼接
- "+"号 有两边,一边是字符串
- "+"号 有两边,一边是对象
- "+"号 只出现在左边
练习题:
let result = 100 + true + 21.2 + null + undefined + "Tencent" + [] + null + 9 + false;
console.log(result); // 输出什么?
3.把其他数据类型转换为 Boolean
Boolean(val); // 或 !!val
转换规则:
只有以下值为 false
:
- 0
- NaN
- 空字符串 ""
- null
- undefined
其他全为 true
出现情况:
- Boolean([val]) 或者 !/!!
- 条件判断
4.== 比较时的隐式转换
4.1 “==”相等,两边数据类型不同,需要先转为相同类型,然后再进行比较
- 对象 == 字符串:对象先转字符串(Symbol.toPrimitive → valueOf → toString)
- null == undefined →
true
, null/undefined和其他任何值都不相等, null === undefined ->false
- 对象==对象 比较的是堆内存地址,地址相同则相等
- NaN 永远不等于 NaN
- 除了以上情况,只要两边类型不一致,剩下的都是转换为数字,然后再进行比较的
4.1 “===”绝对相等,如果两边类型不同,则直接是false,不会转换数据类型「推荐」
推荐使用 ===
(全等)避免隐式转换。
练习题:
console.log([] == false); // true
console.log(![] == false); // true
🧠 综合练习题
var a = ?;
if (a == 1 && a == 2 && a == 3) {
console.log('OK');
}
// 请你思考 a 如何赋值才会输出 'OK'?