Web-Dev-For-Beginners JavaScript 数据类型详解:变量、常量与核心类型实战指南
本文是 Web-Dev-For-Beginners 课程(12 周、24 课时)中第 04 课"JavaScript Basics: Data Types"的完整技术解析。内容聚焦 JavaScript 数据类型这一语言基石:let/const 声明与赋值语义、7 种原始类型、算术运算符、字符串拼接与模板字符串、布尔值与 truthy/falsy 规则,并结合本课程 typing game、terrarium 项目的真实源码,验证这些基础知识在实际 Web 项目中的用法。读完后你将能够独立声明与使用变量、区分常量的"引用保护"与"值可变性"、解释 '1' + '1' === '11' 等隐式类型转换行为,并能用浏览器控制台快速验证一切概念。
课程定位:数据类型在 Web 开发中的角色
在课程的 JavaScript 基础模块总览 中,数据类型是 4 个 JS 基础课时中的第一课,后续依次是函数与方法、条件判断、数组与循环。数据类型之所以被放在最前面,是因为"不同运算作用于不同类型的数据":正如无法对人的姓名做算术运算,JavaScript 也要求每种操作使用恰当的数据类型。理解这一点能避免错误、让代码更可靠——这是后续所有 JS 课程(以及 terrarium、typing game、space game 等项目)的前提。
本课的学习路径可概括为三个阶段:
| 阶段 | 掌握目标 |
|---|---|
| Foundation(基础) | 变量与常量、声明语法、赋值概念 |
| Core Types(核心类型) | 数字与数学运算、字符串与文本、布尔与逻辑 |
| Apply Knowledge(应用) | 类型转换、真实场景示例、最佳实践 |
原课程配有课前/课后测验与配套视频;本仓库中所有课程测验均收录在 quiz-app 目录下(共 48 套、每套 3 题),可本地运行或部署,参见 quiz-app 说明。
变量:声明、赋值与重新赋值
变量是编程的基本构件,让你把信息存起来并起一个描述性名字以便日后引用:记一个人的年龄,就存在 age 里;追踪用户名,就存在 userName 里。
创建并声明变量的语法为 [关键字] [名字],由两部分组成:
- 关键字:会变化的值用
let,固定不变的值用const; - 变量名:自己选择的、有描述性的名字。
let 是 ES6 引入的关键字,为变量提供所谓的"块级作用域"(block scope),因此推荐用 let 或 const 代替老旧的 var(块级作用域在课程后续章节深入讲解)。
声明 → 赋值 → 重新赋值
原课程将变量操作拆成四个递进步骤,完整继承如下:
1. 声明变量:
let myVariable;
这一步完成的事:告诉 JavaScript 创建一个叫 myVariable 的存储位置;JavaScript 为它在内存中分配空间;此时变量还没有值(即 undefined)。
2. 赋初值:
myVariable = 123;
=是赋值运算符,把值 123 赋给变量(注意:这里的=不是数学里的"相等",而是"赋值");- 变量不再处于 undefined 状态;
- 之后可以在代码任何位置用
myVariable引用这个值。
3. 一步到位(标准做法):
let myVariable = 123;
声明和赋值合并为一条语句,是开发者的标准实践,代码更短且保持清晰。
4. 重新赋值(可变性):
myVariable = 321;
变量现在包含 321 而非 123——变量同一时刻只保存一个值,旧值被替换。"可被重新赋值"正是 let 声明变量的核心特征。
原课程给出的变量状态流转可表述为:let myVar(声明,无值)→ myVar = 123(含值 123)→ myVar = 456(更新值)。
动手验证:在浏览器中打开开发者工具(F12)的控制台,输入
let myVariable = 123,回车后再输入myVariable,即可看到 123。控制台是本课程所有概念的天然实验场。
变量自检问题
- 能否解释"声明变量"与"给变量赋值"的区别?
- 在未声明前就使用变量会发生什么?
- 什么场景下你选
let而不是const?
常量:引用受保护,但值不一定不可变
需要存储"程序运行期间绝不应改变"的信息时,用常量。常量的不可变性防止关键值被意外修改。常量声明与变量概念相同,只是关键字换成 const,且命名惯例是全大写:
const MY_VARIABLE = 123;
这行代码创建了名为 MY_VARIABLE 的常量,值为 123,并禁止后续任何更改。常量有两条核心规则:
- 必须立即赋值——不允许"空常量";
- 值永远不能变——JavaScript 会抛错。
但这里的"值"需要精确理解,原课程用三组对比代码讲清楚了边界:
简单值:重新赋值不允许
const PI = 3;
PI = 4; // 报错(not allowed)
- 对常量重新赋值的尝试会引发错误;
- 保护重要值免于被意外更改;
- 确保值在整个程序中保持一致。
对象引用:替换整个对象不允许
const obj = { a: 3 };
obj = { b: 5 } // 报错(not allowed)
- 防止用新对象替换整个对象;
- 保护的是"对原对象的引用";
- 维持该对象在内存中的身份不变。
对象内容:修改属性允许
const obj = { a: 3 };
obj.a = 5; // 允许(allowed)
- 修改的是对象内部的属性值;
- 对象引用保持不变;
- 说明对象内容可以变化,而引用保持恒定。
关键结论:
const保护的是引用不被重新赋值,值本身并非 immutable——尤其当它是对象这类复杂结构时。这一点在 space game 课程 处理游戏状态时会被反复用到。
7 种原始数据类型
JavaScript 把信息组织成不同类别,即数据类型。变量可以存储数字、文本等不同类型的值,这些值的"种类"就是数据类型。数据类型之所以重要,是因为它帮助开发者决定代码如何写、软件如何运行;且某些类型有独特能力,帮助转换值或从中提取更多信息。
原始类型(primitive,JavaScript data primitives)是语言提供的最底层数据类型,共 7 种:
| 类型 | 示例 | 说明 |
|---|---|---|
string |
"Hello"、'World'、`Template` |
文本,单引号、双引号或反引号界定 |
number |
42、3.14、-5 |
整数与浮点数统一处理 |
bigint |
9007199254740991n |
超大整数(进阶) |
boolean |
true、false |
二值逻辑 |
undefined |
undefined |
声明了但未赋值的变量 |
null |
null |
有意表示"空" |
symbol |
Symbol('id') |
唯一标识符(进阶) |
(本课程的后续课时还会引入两种引用类型:object 与 array,可先预习 数组与循环 与 函数与方法。)
数字(number)
数字是最直接的数据类型:整数 42、小数 3.14、负数 -5,JavaScript 一律统一处理。前面 let myVariable = 123; 里的 123 就是一个 number 类型。
关键特征:JavaScript 自动识别数值;无需显式声明类型;这些变量可直接参与数学运算。变量可以存储所有类型的数字,包括小数和负数。
算术运算符
数字与算术运算符配合,运算符遵循传统数学规则:
| 符号 | 说明 | 示例 |
|---|---|---|
+ |
加法:计算两个数的和 | 1 + 2,预期结果 3 |
- |
减法:计算两个数的差 | 1 - 2,预期结果 -1 |
* |
乘法:计算两个数的积 | 1 * 2,预期结果 2 |
/ |
除法:计算两个数的商 | 1 / 2,预期结果 0.5 |
% |
取余:除法后的余数 | 1 % 2,预期结果 1 |
动手验证:在浏览器控制台里试一条算术运算,看看结果是否出乎意料(比如 10 % 3 是 1 而不是 3.33…)。
实用价值:
%取余运算符在判断奇偶、生成图案、数组轮转(cycling)中极其常用。
字符串(string)
JavaScript 中的文本数据用字符串表示。"string" 一词源于字符"串"在一起的概念。字符串对 Web 开发至关重要——网站上显示的每一段文字:用户名、按钮标签、错误信息、正文内容——都作为字符串数据处理。
字符串是位于单引号或双引号之间的一组字符:
'This is a string'
"This is also a string"
let myString = 'This is a string value stored in a variable';
要点:
- 用单引号
'或双引号"界定字符串; - 可以包含字母、数字和符号;
- 赋值给变量以便后续使用;
- 必须加引号——否则 JavaScript 会把它当成变量名。
字符串格式化:拼接与模板字符串
字符串操作用于组合文本、嵌入变量、构造随程序状态变化的动态内容。
拼接(concatenation):用 + 运算符把两个或多个字符串连起来。
let myString1 = "Hello";
let myString2 = "World";
myString1 + myString2 + "!"; // HelloWorld!
myString1 + " " + myString2 + "!"; // Hello World!
myString1 + ", " + myString2 + "!"; // Hello, World!
逐行理解:第一段无空格直接相连得到 HelloWorld!;中间插入 " " 空格得到 Hello World!;插入 ", " 得到 Hello, World!。
原课程此处埋了一个思考题:为什么 1 + 1 = 2,而 '1' + '1' = 11?再想想 '1' + 1 会怎样?(提示:+ 遇到字符串时执行拼接而非加法,这是隐式类型转换的典型体现。)
模板字符串(template literals):另一种格式化方式,用反引号 ` 代替引号,非纯文本部分放入 ${ } 占位符(包括变量):
let myString1 = "Hello";
let myString2 = "World";
`${myString1} ${myString2}!` // Hello World!
`${myString1}, ${myString2}!` // Hello, World!
逐部分理解:
- 用反引号
`而非普通引号创建模板字符串; - 通过
${}占位符语法直接嵌入变量; - 精确保留所写的空格与格式;
- 为"含变量的复杂字符串"提供了更干净的写法。
两种方法都能达成格式化目标,但模板字符串会尊重空格与换行——构建复杂字符串时通常优先选择它,因为它更易读,且能优雅处理多行文本。
布尔(boolean)与 truthy / falsy
布尔是最简单的数据:只能取 true 或 false 两个值。
let myTrueBool = true;
let myFalseBool = false;
要点:
- 创建了存储布尔值
true的变量,并演示了如何存储false; - 使用的正是关键字
true/false,不需要引号(加了引号的'true'是字符串); - 这些变量为条件语句做准备——布尔帮助程序决定"满足某些条件时运行哪些代码行"。
在很多场景,运算符(如比较运算符)会帮助设置布尔值,你会经常看到变量用运算符初始化或更新。
truthy 与 falsy:一个变量如果"求值结果为 true",就称为 truthy。JavaScript 的有趣之处在于:几乎所有值都是 truthy,只有 6 个值天生是 falsy:
| falsy 值 | 说明 |
|---|---|
false |
布尔假值 |
0 |
数字零(注意:字符串 "0" 是 truthy!) |
"" |
空字符串 |
null |
有意为空 |
undefined |
未定义 |
NaN |
Not-a-Number |
其余一切("hello"、42、[]、{} 甚至 "false" 这个字符串)都是 truthy。这条规则在 条件判断课程 编写 if 语句时是核心知识。
仓库实证:课程项目源码中的数据类型
上述概念并非纸上谈兵——本课程后续项目的参考实现里随处可见数据类型的典型用法。
typing game 参考实现(4-typing-game/solution/index.js)几乎是一份"数据类型速查表":
- 第 4 行
const quotes = [...]——常量数组存放引用文本; - 第 15–17 行
let words = []、let wordIndex = 0、let startTime = 0——会随游戏进程变化的状态用let,初始值分别为空数组和数字 0,正是 number 与数组类型的实际落地; - 第 27 行
success: (seconds) => \🎉 Congratulations! You finished in ${seconds.toFixed(2)} seconds.``——模板字符串嵌入数字运算结果,正是本课"字符串格式化"的直接应用; - 第 71 行
(Date.now() - startTime) / 1000——除法运算符求耗时,第 69 行typedValue === currentWord则依赖字符串比较返回布尔值驱动分支逻辑。
terrarium 参考实现(3-terrarium/solution/script.js)展示了数值与字符串的交互:
- 第 25–28 行
let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;——4 个位置变量用let声明并初始化为数字 0,随拖动事件不断重新赋值,体现了let的可变性; - 第 55–56 行
terrariumElement.style.top = terrariumElement.offsetTop - pos2 + 'px';——这是本课"'1' + 1" 思考题的真实工程版:数字与字符串'px'相加发生隐式类型转换,得到"123px"这样的合法 CSS 值。若顺序写成'px' + (offsetTop - pos2),同样得到正确字符串——这正是"类型决定运算行为"的实例。
从源码结构看,整个课程的 JS 参考实现(terrarium、typing game、space game)一致地遵循本课倡导的现代实践:只使用 let/const,不出现 var。
综合挑战与练习
原课程提供了三层练习,完整保留如下。
经典陷阱挑战
在浏览器控制台输入:
let age = 1; let Age = 2; age == Age
结果是 false——能解释为什么吗?(提示:变量名是区分大小写的,age 和 Age 是两个不同变量;而 == 的宽松比较与 === 的严格比较之间的差异,值得用一小时深入探索。)
熟悉这些"怪癖"行为,会帮助你写出更可靠的代码、更高效地排查问题。
Copilot Agent 实战挑战
课程在各章节新增了 "GitHub Copilot Agent Challenge"。本章的挑战是:构建一个个人信息管理器,要求创建用户资料对象,包含:姓名(string)、年龄(number)、是否学生(boolean)、最喜欢的颜色(数组)、以及包含 street/city/zip code 属性的地址对象;并编写函数展示资料、更新单个字段;同时演示字符串拼接、模板字符串、对年龄做算术运算、基于学生状态的布尔逻辑。这道题恰好覆盖本课全部核心类型。
配套作业:电商购物车
课后作业要求你以"电商购物车系统"为场景,逐一分析 7 种原始类型 + 对象 + 数组 在真实业务中的用途,每个类型需说明:用途(Purpose)、为何选它(Why)、可运行的代码示例(Code Example)、真实场景(Real-world Usage)、与其他数据的交互(Interactions),并覆盖类型强制转换(如 "5" + 10)、数据校验、性能权衡三个加项挑战。详细要求与评分标准见 购物车作业。
分阶段练习清单
5 分钟内可做:
- 打开浏览器控制台,创建 3 个不同数据类型的变量;
- 完成上面的
age == Age挑战并解释原因; - 用字符串拼接处理你的名字和喜欢的数字;
- 测试"数字 + 字符串"会发生什么。
1 小时内可做:
- 完成课后测验,复盘模糊概念;
- 写一个迷你计算器,对两个数做加减乘除;
- 用模板字符串实现一个姓名格式化器;
- 探索
==与===的差异; - 练习不同类型之间的转换。
一周内可做:
- 完成作业并发挥创意;
- 用本课全部数据类型构建个人档案对象;
- 用布尔逻辑做一个简单表单校验器;
- 预告性实验:数组与对象类型;
- 构建管理不同类型用户数据的小型应用。
小结
本课的知识地图可以浓缩为四组要素:
- 变量:
let(可变)、const(引用不可变);=是赋值而非相等; - 数字:
42、3.14、-5统一处理,配+ - * / %五个算术运算符; - 字符串:
'单引号'、"双引号"、`模板字符串 ${}`,拼接与模板插值两种方式; - 布尔:
true/false驱动条件逻辑,牢记仅有的 6 个 falsy 值:false、0、""、null、undefined、NaN。
以及四条关键结论:类型决定运算行为;JavaScript 是动态类型语言;变量的类型可以改变;变量命名区分大小写。理解数据类型如同"写故事前先学字母表"——你将编写的每一个 JavaScript 程序都会用到这些基础概念。下一步,进入 函数与方法,把本课的"存储"能力封装成"行为"。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0627
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
