home

数据类型及相互间的转换规则

2025年4年9日 · 1259

一、ECMA262 数据类型的详细剖析

二、数据类型的标准定义

ECMAScript 是基于对象的语言。它的值分为两类:

原始值类型(值类型 / 基本数据类型)

  • number:数字
  • string:字符串
  • boolean:布尔值
  • null:空对象指针
  • undefined:未定义
  • symbol:唯一值
  • bigint:大整数

引用类型(对象类型)

  • 标准普通对象:object
  • 标准特殊对象:ArrayRegExpDateMathError
  • 非标准特殊对象:NumberStringBoolean...
  • 可调用/执行对象(函数):function

三、Symbol和BigInt的实践运用

  • Symbol 创建一个唯一值

    1. 给对象设置“唯一值”的属性名
      • 字符串
      • Symbol类型
      • Map新的数据结构:可以允许属性名是对象
    2. Symbol.asyncIterator/iterator/hasInstance/toPrimitive/toStringTag...是某些JS知识底层实现的机制
    3. 在派发行为标识统一进行管理的时候,可以基于symbol类型的值,保证行为标识的唯一性
  • BigInt 大数类型

    • Number.MAX_SAFE_INTEGER 9007199254740991 JS中的最大安全数

    • Number.MIN_SAFE_INTEGER -9007199254740991 最小安全数

    • 超过安全数后,进行运算或者访问,结果会不准确!!!

    • 解决方案:

      1. 服务器返回给客户端的大数,按照“字符串”格式返回!
      2. 客户端把其变为 BigInt ,然后按照BigInt进行运算
      3. 最后把运算后的BigInt转换为字符串,在传递给服务器即可

四、typeof 数据类型检测的机制

  • 所有的数据类型值,在计算机底层都是按照 “64位” 的二进制值进行存储的!
  • typeof是按照二进制值进行检测类型的
    1. 二进制的前三位是零,认为是对象,然后再去看有么有实现call方法,如果实现了,返回 'function',没有实现,则返回 'object'
    2. 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.toPrimitivevalueOftoString → 转为 Number
    1. 先调用对象的 Symbol.toPrimitive 这个方法,如果不存在这个方法
    2. 再调用对象的 valueOf 获取原始值,如果获取的值不是原始值
    3. 再调用对象的 toString 把其变为字符串
    4. 最后再把字符串基于Number方法转换为数字

parseInt/parseFloat

parseInt([val],[radix]) / parseFloat([val])

  1. 一般用于手动转换
  2. 规则:[val]值必须是一个字符串,如果不是则先转换为字符串;然后从字符串左侧第一个字符开始找,把找到的有效数字字符最后转换为数字「一个都没找到就是NaN」;遇到一个非有效数字字符,不论后面是否还有有效数字字符,都不再查找了;parseFloat可以多识别一个小数点;

练习题

let arr = [27.2, 0, '0013', '14px', 123];
arr = arr.map(parseInt); // 思考输出结果

2.把其他数据类型转换为 String

String(val); // 或 val.toString()

转化规则:

  1. 拿字符串包起来
  2. 特殊:Object.prototype.toString

出现情况:

  1. String([val]) 或者 [val].toString()
  2. “+”号 除数学运算,还可能代表的字符串拼接
    • "+"号 有两边,一边是字符串
    • "+"号 有两边,一边是对象
    • "+"号 只出现在左边

练习题:

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

出现情况:

  1. Boolean([val]) 或者 !/!!
  2. 条件判断

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'?