Skip to main content

数据类型和转换

一、JavaScript 数据类型概述

JavaScript 是一种动态类型语言,变量无需预先声明类型,类型在运行时确定。其数据类型分为两类:

1. 原始数据类型(Primitive Types)

  • Undefined:未初始化的变量默认值(let x; console.log(x); // undefined)。
  • Null:表示空值(const obj = null;)。
  • Booleantruefalse
  • Number:整数和浮点数(const num = 42; const pi = 3.14;)。
  • String:字符串(const str = "Hello";)。
  • Symbol(ES6+):唯一标识符(const id = Symbol("unique");)。
  • BigInt(ES10+):任意精度整数(const big = 12345678901234567890n;)。

2. 引用数据类型(Reference Types)

  • Object:对象(const person = { name: "John" };)。
  • Array:数组(const arr = [1, 2, 3];)。
  • Function:函数(function add(a, b) { return a + b; })。
  • Date:日期对象(const now = new Date();)。
  • RegExp:正则表达式(const re = /abc/gi;)。
  • Error:错误对象(const err = new Error("Something wrong");)。

二、类型检测方法

方法原始类型引用类型注意事项
typeof✅(除 null)部分✅(如 function)typeof null 返回 "object"(历史遗留问题)
instanceof检测对象原型链(如 arr instanceof Array
Object.prototype.toString.call()最准确的检测方式(如 [object String]
Array.isArray()✅(数组)专门检测数组
Symbol.prototype.description✅(Symbol)获取 Symbol 描述

三、类型转换:隐式转换与显式转换

1. 隐式类型转换(自动转换)

JavaScript 会在特定操作中自动转换类型,可能导致意外结果。

  • 字符串拼接(+)

    1 + "2" // "12"(数字转字符串)
    true + "false" // "truefalse"(布尔转字符串)
  • 算术运算(-、*、/)

    "10" - 5 // 5(字符串转数字)
    "abc" * 2 // NaN(无法转数字)
  • 布尔上下文(if、while 等)

    if ("") { console.log("会执行吗?"); } // 不会,"" 转 false
    if (0) { console.log("会执行吗?"); } // 不会,0 转 false
    if (null) { console.log("会执行吗?"); } // 不会,null 转 false
    if (undefined) { console.log("会执行吗?"); } // 不会,undefined 转 false
    if ({}) { console.log("会执行吗?"); } // 会,对象转 true
  • 相等运算符(== 与 ===)

    1 == "1" // true(隐式转换后比较)
    1 === "1" // false(类型不同,直接不相等)
    null == undefined // true(特殊情况)

2. 显式类型转换(手动转换)

  • 转字符串(String() 或 toString())

    String(123) // "123"
    (123).toString() // "123"(注意括号,避免语法错误)
    true.toString() // "true"
  • 转数字(Number()、parseInt()、parseFloat())

    Number("123") // 123
    parseInt("45px") // 45(只解析开头数字)
    parseFloat("3.14cm") // 3.14
    Number("abc") // NaN
  • 转布尔(Boolean())

    Boolean(0) // false
    Boolean("") // false
    Boolean(null) // false
    Boolean(undefined) // false
    Boolean(NaN) // false
    Boolean(1) // true
    Boolean("abc") // true
    Boolean({}) // true

四、特殊值与类型转换

  1. NaN(Not a Number)

    • 任何涉及非数字的算术运算都会返回 NaN(如 "abc" * 2)。
    • NaN === NaN 返回 false,需用 isNaN() 检测:
      isNaN(NaN) // true
      isNaN("abc") // true
  2. Infinity

    • 表示超出 JavaScript 数值范围的数(如 1 / 0)。
    • 分为 Infinity(正数)和 -Infinity(负数)。
  3. null 与 undefined

    • null 是人为设置的空值,undefined 是未初始化的默认值。
    • null 转数字为 0undefined 转数字为 NaN
      Number(null) // 0
      Number(undefined) // NaN

五、类型转换的最佳实践

  1. 避免隐式转换

    • 使用严格相等运算符 === 而非 ==,防止隐式转换导致的错误。
    if (value === 0) { /* 处理 value 为 0 的情况 */ }
  2. 明确转换意图

    • 转数字时优先使用 parseInt/parseFloat(保留整数部分或浮点精度):
      const str = "123.45";
      parseInt(str) // 123
      parseFloat(str) // 123.45
  3. 空值处理

    • nullish coalescing operator(??) 处理 nullundefined
      const value = userInput ?? "默认值"; // 若 userInput 是 null 或 undefined,使用默认值
  4. 布尔值转换技巧

    • !! 快速转布尔:
      const isTrue = !!value; // 等价于 Boolean(value)

六、类型转换的性能考量

  • 频繁转换
    避免在循环中进行大量类型转换(如字符串拼接),可预先转换:

    // 不好的写法
    for (let i = 0; i < 10000; i++) {
    result += i.toString(); // 每次循环都转换
    }

    // 优化写法
    const strI = i.toString();
    for (let i = 0; i < 10000; i++) {
    result += strI; // 预先转换
    }
  • 大数组转换
    使用 map() 等数组方法批量转换,利用引擎优化:

    const numbers = ["1", "2", "3"];
    const parsed = numbers.map(Number); // [1, 2, 3]

七、总结:类型转换的核心原则

  1. 理解自动转换规则:避免因隐式转换导致的逻辑错误(如 "" == falsetrue)。
  2. 使用严格比较:优先用 ===!==,明确类型一致性。
  3. 显式转换意图:用 String()Number() 等方法明确转换目的,提升代码可读性。
  4. 处理边界情况:特别注意 nullundefinedNaN 等特殊值的转换结果。