WinddSnow

JavaScript-Data-Types-Part1-String-Number-Boolean-Type-Conversion

字数统计: 3.3k阅读时长: 14 min
2026/07/29

第44课:JavaScript 数据类型(上)——stringnumberboolean 与类型转换

JavaScript 有七种原始类型和一种对象类型。原始类型是不可变的、按值传递的;对象类型是可变的、按引用传递的。本节课聚焦于三种最基础、使用频率最高的原始类型——字符串(string)数值(number)布尔值(boolean)。你将学习它们的字面量语法、常见操作、边界情况与陷阱,以及 JavaScript 中灵活且容易出错的显式与隐式类型转换机制。这是理解 == vs ===、表单输入处理、API 数据格式化等实际问题的前提。


1. string 类型:文本的表示与操作

字符串是不可变的、有序的 16 位无符号整数值序列,每个值对应一个 Unicode 字符(严格说是 UTF-16 代码单元)。

1.1 三种字面量语法

1
2
3
const single = 'Hello';              // 单引号
const double = "World"; // 双引号
const template = `Hello ${single}`; // 反引号(模板字符串,ES6)
语法 特性 适用场景
单引号 ' 最简洁,内部可包含双引号无需转义。JSON 标准仅支持双引号。 常规字符串,风格偏好。
双引号 " 内部可包含单引号无需转义。与 JSON 一致。 常规字符串,或包含英文缩写(如 It's)。
反引号 ` 支持插值${expression})和多行文本 动态字符串拼接、多行文本、HTML 模板。

模板字符串的核心能力

1
2
3
4
5
6
7
8
9
10
11
12
13
const name = 'Alice';
const age = 25;

// 插值:任意 JavaScript 表达式
const greeting = `你好,我叫 ${name},明年 ${age + 1} 岁。`;

// 多行:保留换行符
const html = `
<div class="card">
<h2>${name}</h2>
<p>年龄:${age}</p>
</div>
`;

1.2 不可变性

字符串一旦创建,其值就不能改变。所有“修改”字符串的操作实际都是返回一个新字符串

1
2
3
4
5
6
7
let str = 'Hello';
str[0] = 'h'; // 无效(严格模式下会报错)
console.log(str); // 'Hello' —— 原字符串未变

const newStr = str.toUpperCase();
console.log(newStr); // 'HELLO' —— 返回了新字符串
console.log(str); // 'Hello' —— 原字符串不受影响

1.3 常用方法速览

方法 作用 返回值
length(属性) 字符串长度(UTF-16 代码单元数量)。 number
charAt(index) 返回指定索引的字符。 string
indexOf(sub) 子串首次出现的索引,找不到返回 -1 number
includes(sub) 是否包含子串(ES6)。 boolean
startsWith(sub) 是否以子串开头。 boolean
endsWith(sub) 是否以子串结尾。 boolean
slice(start, end) 提取子串(支持负数索引)。 string
substring(start, end) 提取子串(不支持负数,会自动交换参数)。 string
toLowerCase() 转为全小写。 string
toUpperCase() 转为全大写。 string
trim() 去除首尾空白字符。 string
replace(old, new) 替换首次匹配。 string
replaceAll(old, new) 替换所有匹配(ES2021)。 string
split(sep) 按分隔符拆分为数组。 string[]
1
2
3
4
5
6
7
8
const email = '  Alice@Example.com  ';
console.log(email.trim().toLowerCase()); // 'alice@example.com'

const csv = 'apple,banana,grape';
console.log(csv.split(',')); // ['apple', 'banana', 'grape']

const url = '/users/123/profile';
console.log(url.slice(url.lastIndexOf('/') + 1)); // 'profile'

2. number 类型:唯一的数值类型

JavaScript 只有一种数值类型:双精度 64 位 IEEE 754 浮点数。它统一了整数和小数,但也带来了精度问题。

2.1 数值范围与安全整数

1
2
3
4
console.log(Number.MAX_VALUE);        // 1.7976931348623157e+308
console.log(Number.MIN_VALUE); // 5e-324(最小正数)
console.log(Number.MAX_SAFE_INTEGER); // 9007199254740991(2^53 - 1)
console.log(Number.MIN_SAFE_INTEGER); // -9007199254740991

安全整数指可以精确表示和比较的整数范围。超过此范围的两个不同整数可能被表示为同一个浮点数。处理大整数时应使用 BigInt(第 45 课介绍)或将数值以字符串形式传递。

2.2 浮点数精度问题(经典陷阱)

1
2
console.log(0.1 + 0.2);        // 0.30000000000000004,不是 0.3
console.log(0.1 + 0.2 === 0.3); // false

原因0.10.2 在二进制中都是无限循环小数,IEEE 754 截断后存储的是它们的近似值,相加后再次截断,与 0.3 的近似值不相等。

解决方案

  • 使用容差值比较:Math.abs(a - b) < Number.EPSILON
  • 将小数转为整数计算后还原(如金额用“分”为单位存储)。
  • 使用第三方库(decimal.jsbig.js)。
1
2
3
4
5
6
// 容差比较
console.log(Math.abs(0.1 + 0.2 - 0.3) < Number.EPSILON); // true

// 分转元
const priceInCents = 1999; // 19.99 元
console.log(priceInCents / 100); // 19.99(精确)

2.3 特殊数值:NaNInfinity-Infinity

产生方式 特征
NaN 0/0parseInt('abc')Number(undefined) 表示“不是一个数字”,但 typeof NaN === 'number'自身不等于自身NaN !== NaN
Infinity 1/0Number.POSITIVE_INFINITY 正无穷大,任何正数除以 0 的结果。
-Infinity -1/0Number.NEGATIVE_INFINITY 负无穷大。

检测 NaN 的正确方式

1
2
3
4
5
6
7
8
9
// ❌ 错误:NaN 不等于自身
if (value === NaN) { } // 永远是 false

// ✅ 使用 Number.isNaN()(ES6,不会先尝试类型转换)
console.log(Number.isNaN(NaN)); // true
console.log(Number.isNaN('abc')); // false(字符串 'abc' 本身不是 NaN)

// ⚠️ 全局 isNaN() 会先转换类型
console.log(isNaN('abc')); // true(先 Number('abc') → NaN)

2.4 数值的显式转换与解析

方法 行为 示例
Number(value) 严格转换,无法转换则返回 NaN Number('123') → 123Number('12px') → NaN
parseInt(str, radix) 从左到右解析整数,遇到非数字字符停止。必须指定第二个参数(进制) parseInt('12px', 10) → 12parseInt('0xFF', 16) → 255
parseFloat(str) 解析浮点数,只认第一个小数点。 parseFloat('3.14.15') → 3.14
+value 一元加号,等同于 Number(value) +'123' → 123
1
2
3
4
5
6
7
8
// 常见场景:从 CSS 取值时去除单位
const width = '320px';
console.log(parseInt(width, 10)); // 320

// 表单输入转数字(推荐用 Number + 校验,而非 parseInt)
const input = ' 42 ';
console.log(Number(input)); // 42(trim 后转换)
console.log(parseInt(input, 10)); // 42(parseInt 自动 trim)

3. boolean 类型:只有 truefalse

布尔值表示逻辑上的真与假,是条件判断和控制流的基础。

3.1 字面量与构造函数的区别

1
2
3
4
5
6
7
8
9
10
const bool1 = true;              // 原始布尔值
const bool2 = new Boolean(true); // ❌ Boolean 对象(不要这样用)
console.log(typeof bool1); // 'boolean'
console.log(typeof bool2); // 'object'
console.log(bool1 === bool2); // false(类型不同)

// Boolean 对象在条件判断中始终为 true(因为它是对象)
if (new Boolean(false)) {
console.log('这行会执行!'); // 因为对象总是 truthy
}

永远使用原始布尔值,避免 new Boolean()

3.2 Falsy 值:8 个假值

在条件判断(ifwhile!)或转换为布尔值时,以下 8 个值被视为 false,其余所有值都是 true

Falsy 值 说明
false 布尔假值本身。
0-0 数字零和负零。
0n BigInt 零。
''"" 空字符串。
null 空值。
undefined 未定义。
NaN 非数字。

常见的 Truthy 但容易误判为假的值

  • 字符串 'false''0'' '(空格)—— 非空字符串都是 truthy。
  • 空数组 []、空对象 {}
  • new Boolean(false)(任何对象都是 truthy)。
1
2
3
4
5
6
7
8
9
10
11
const userInput = ''; // 空字符串
if (userInput) {
console.log('不会执行');
}

const items = []; // 空数组
if (items) {
console.log('会执行!'); // 数组是真值
}
// 正确判断非空数组:
if (items.length > 0) { }

4. 显式类型转换:主动控制类型

JavaScript 提供了多种显式转换类型的方法,这是编写健壮代码的基础。

4.1 转字符串:String().toString()

1
2
3
4
5
6
7
8
9
10
11
12
String(123);        // '123'
String(true); // 'true'
String(null); // 'null'
String(undefined); // 'undefined'
String(NaN); // 'NaN'

(123).toString(); // '123'
// null.toString(); // TypeError: Cannot read properties of null
// undefined.toString(); // TypeError

// 模板字符串隐式调用 String()
const str = `${123}`; // '123'

String() 是全局函数,能安全处理 nullundefined.toString() 是原型方法,对 null/undefined 调用会抛出异常。

4.2 转数值:Number()parseInt()parseFloat()

已在 2.4 节详述。补充对比表:

输入 Number(input) parseInt(input, 10)
'42' 42 42
'42px' NaN 42
'' 0 NaN
' 42 ' 42 42
true 1 NaN
null 0 NaN
undefined NaN NaN

4.3 转布尔值:Boolean()!!

1
2
3
4
5
6
7
8
9
10
Boolean(1);        // true
Boolean(0); // false
Boolean(''); // false
Boolean('hello'); // true
Boolean(null); // false
Boolean([]); // true —— 空数组也是真值!

// 双重否定语法(!!)是 Boolean() 的简写
console.log(!!'text'); // true
console.log(!!0); // false

5. 隐式类型转换:==+ 的规则

JavaScript 在特定操作符下会自动将操作数转换为期望的类型。理解这些规则是规避 Bug 的关键。

5.1 加法运算符 + 的特殊性

+ 既是数值加法,也是字符串连接。当任一操作数是字符串时,另一个也会被转为字符串

1
2
3
4
5
6
7
8
console.log(1 + 2);           // 3(数值加法)
console.log('1' + 2); // '12'(字符串连接)
console.log(1 + '2'); // '12'
console.log('Hello ' + true); // 'Hello true'

// 复杂表达式从左到右
console.log(1 + 2 + '3'); // '33'(先计算 1+2=3,再连接 '3')
console.log('1' + 2 + 3); // '123'('1'+2→'12',再连接 3)

5.2 宽松相等 == 与严格相等 ===

== 在比较前会进行类型转换,规则复杂且容易出错。=== 不转换类型,类型不同直接返回 false

1
2
3
4
5
6
7
8
9
10
11
// == 的隐式转换陷阱
console.log(0 == ''); // true(空字符串转为 0)
console.log(0 == '0'); // true(字符串转为数值)
console.log(false == 0); // true(false 转为 0)
console.log(false == ''); // true(都转为 0)
console.log(null == undefined); // true(特殊规则,它们互相等于)
console.log(null == 0); // false(null 不转为 0)

// === 无类型转换
console.log(0 === ''); // false
console.log(false === 0); // false

实践原则:始终使用 ===(严格相等),除非你明确需要 null == undefined 这种特殊行为(例如同时检查一个变量是否为 nullundefined)。

5.3 比较运算符 <> 的转换

当两个操作数都是字符串时,按字典序比较;否则尝试转为数值比较。

1
2
3
console.log('10' > 2);    // true —— '10' 转为 10
console.log('10' > '2'); // false —— 字典序:'1' < '2'
console.log('abc' > 1); // false —— Number('abc') → NaN,任何与 NaN 的比较都返回 false

课后练习

一、概念自测(选择题 / 填空题)

  1. (单选) 0.1 + 0.2 === 0.3 的结果是?
    A. true
    B. false
    C. TypeError
    D. NaN

  2. (单选) 以下关于 NaN 的说法,正确的是?
    A. typeof NaN === 'NaN'
    B. NaN === NaN 返回 true
    C. Number.isNaN('abc') 返回 true
    D. NaN 是唯一一个不等于自身的 JavaScript 值

  3. (填空) 在 JavaScript 中,空数组 [] 转换为布尔值时是 ______(true/false)。

  4. (多选) 以下哪些值在条件判断中是 falsy(假值)?
    A. 0
    B. 'false'
    C. ''
    D. undefined

二、AI 编程任务:编写面向 AI 的提示词

场景:你需要编写一个 JavaScript 工具函数 safeAdd,用于安全地将两个任意类型的值相加并返回字符串结果。要求如下:

  • 如果两个参数都是数字(或能安全转换为有意义数字的字符串),返回它们的算术和转为字符串。
  • 如果任一参数转换数字失败(如 'abc'),则将二者都转为字符串进行拼接
  • 需要处理 nullundefinedboolean 等边界情况。
  • 使用 const 声明函数,内部变量优先 const,需要重新赋值时用 let
  • 添加 JSDoc 注释,说明参数类型、返回值和转换逻辑。
  • 提供至少 5 个测试用例的输出注释。

任务要求:请写出一段完整的中文提示词,发送给 AI,使其生成符合上述要求的 JavaScript 代码。提示词中需明确指定类型转换的判断逻辑(如何使用 Number()isNaN())、命名规范和代码风格。


课后练习答案

一、概念自测答案

  1. B

    • 解析:IEEE 754 浮点数精度问题,0.1 + 0.2 的结果是 0.30000000000000004
  2. D

    • 解析:A 错误,typeof NaN === 'number';B 错误,NaN !== NaN;C 错误,Number.isNaN 不会先转换类型,'abc' 不是 NaN 值本身。
  3. true

    • 解析:空数组是对象(typeof [] === 'object'),所有对象在布尔上下文中都是 truthy。
  4. A、C、D

    • 解析:0''undefined 都是 falsy 值。'false' 是非空字符串,是 truthy。

二、AI 编程任务参考答案(提示词示例)

示例提示词
“请编写一个 JavaScript 函数 safeAdd(a, b),安全地将两个任意类型的值相加并返回字符串。要求:

  • 函数使用 const 声明。内部变量优先 const,需要重新赋值时用 let,不使用 var
  • 转换逻辑:使用 Number(a)Number(b) 尝试转为数字。若两者转换后都不是 NaN(用 !Number.isNaN() 判断),则返回 (数值a + 数值b).toString()。否则,使用 String(a) + String(b) 进行字符串拼接。
  • 处理边界:null 转为数字是 0undefined 转为数字是 NaNtrue → 1,false → 0。
  • 添加 JSDoc 注释(@param、@returns、@description)。
  • 在代码底部使用注释提供至少 5 个测试用例及其预期输出(例如 safeAdd(1, 2) // '3'safeAdd('1', '2') // '3'safeAdd('a', 1) // 'a1'safeAdd(null, 5) // '5'safeAdd(undefined, 5) // 'undefined5')。
  • 代码简洁,遵循 Airbnb 风格指南。直接输出完整代码。”
CATALOG
  1. 1. 第44课:JavaScript 数据类型(上)——string、number、boolean 与类型转换
    1. 1.1. 1. string 类型:文本的表示与操作
      1. 1.1.1. 1.1 三种字面量语法
      2. 1.1.2. 1.2 不可变性
      3. 1.1.3. 1.3 常用方法速览
    2. 1.2. 2. number 类型:唯一的数值类型
      1. 1.2.1. 2.1 数值范围与安全整数
      2. 1.2.2. 2.2 浮点数精度问题(经典陷阱)
      3. 1.2.3. 2.3 特殊数值:NaN、Infinity、-Infinity
      4. 1.2.4. 2.4 数值的显式转换与解析
    3. 1.3. 3. boolean 类型:只有 true 和 false
      1. 1.3.1. 3.1 字面量与构造函数的区别
      2. 1.3.2. 3.2 Falsy 值:8 个假值
    4. 1.4. 4. 显式类型转换:主动控制类型
      1. 1.4.1. 4.1 转字符串:String() 与 .toString()
      2. 1.4.2. 4.2 转数值:Number()、parseInt()、parseFloat()
      3. 1.4.3. 4.3 转布尔值:Boolean() 与 !!
    5. 1.5. 5. 隐式类型转换:== 与 + 的规则
      1. 1.5.1. 5.1 加法运算符 + 的特殊性
      2. 1.5.2. 5.2 宽松相等 == 与严格相等 ===
      3. 1.5.3. 5.3 比较运算符 <、> 的转换
    6. 1.6. 课后练习
      1. 1.6.1. 一、概念自测(选择题 / 填空题)
      2. 1.6.2. 二、AI 编程任务:编写面向 AI 的提示词
    7. 1.7. 课后练习答案
      1. 1.7.1. 一、概念自测答案
      2. 1.7.2. 二、AI 编程任务参考答案(提示词示例)