Web-Dev-For-Beginners 课程笔记:JavaScript 变量、常量的声明规则与 number、string、boolean 三大基础数据类型全解
本指南以《Web-Dev-For-Beginners》开源课程中 2-js-basics/1-data-types 一课为骨架展开,系统讲解 JavaScript 中变量与常量的声明语法、赋值语义、number / string / boolean 三类核心数据类型及其配套运算符与格式化技巧。课程所属的 JS 基础模块共 4 课,其余内容见 模块导读。读完本文后,你将能够正确选用 let/const 组织可变与不可变状态,熟练完成算术运算、字符串拼接与模板字符串插值,并准确判断值在条件语境下的 truthy/falsy 行为,为后续函数、分支、数组与循环打好地基。
上图为本课配套的 sketchnote,手绘梳理了
var/let/const的作用域差异、字符串/数字/布尔三类数据类型、算术运算符与全局/函数/块级作用域的关系。
变量:声明、赋值与重赋值
声明语法:[关键字] [变量名]
创建变量在语法上由两部分组成:
- 关键字:值会变化时用
let;值保持不变时用const。 - 变量名:由你自行选择的描述性名称,例如保存某人年龄用
age,追踪用户名用userName。
这里聚焦现代写法。let 是 ES6 引入的,它为变量赋予块级作用域(block scope),官方建议用 let 或 const 取代更早期的 var(作用域的深入话题留待后续课程)。课程用一个贴近生活的比喻帮助记忆:变量像中世纪炼金术士贴了标签的罐子,需要记住某人年龄就放进名为 age 的罐子,需要追踪用户名就放进名为 userName 的罐子。
动手任务:四步掌握变量的生命周期
- 声明变量——创建一个"空"的存储位置:
let myVariable;
效果是:告诉 JavaScript 建立名为 myVariable 的存储位置、为其在内存中分配空间,此刻该变量没有任何值(值为 undefined)。
- 给变量赋值——向罐子里放入内容:
myVariable = 123;
这里的 = 是赋值运算符(assignment operator),表示"把 123 设给变量",不代表数学意义上的相等。赋值后,变量原本的 undefined 被数值 123 取代,之后整份代码中你都能通过 myVariable 引用这个值。
- 合并两步(更聪明的做法):
let myVariable = 123;
声明的同时完成初始化,这是开发者的标准实践,缩短代码且保持清晰。
- 重赋值——如果想换一个数:
myVariable = 321;
变量现在装的是 321 而不是 123,旧值被整体替换——同一时刻变量只能保存一个值。这种可变性正是 let 声明的关键特征。
动手实验:浏览器中打开开发者工具(DevTools),在 Console 提示符输入 let myVariable = 123 回车,再输入 myVariable 回车,观察返回结果。建议同时思考三个问题:声明与赋值有何区别?在声明之前使用变量会发生什么?什么场景你该选 let 而非 const?
快速记忆法:变量是有标签的储物箱——用
let"造箱",用="装箱",必要时还能"换货"。
常量:一经赋值,不可再改
有时信息在程序运行期间绝不允许变化,例如数学常量。常量与变量的机制相似,但多了一条硬性限制:一旦赋值,不能再改。声明的语法除关键字换成 const 外与变量相同,且常量通常约定全大写命名:
const MY_VARIABLE = 123;
常量两条铁律:
- 必须立即赋值——不存在"空常量";
- 该值永远不可改变——一旦尝试修改,JavaScript 会抛出错误。
用代码演示三种情形,务必分清"不允许"与"允许"的边界:
情形一:修改简单值——不允许
const PI = 3;
PI = 4; // 不允许
情形二:整体替换对象引用——不允许
const obj = { a: 3 };
obj = { b: 5 } // 不允许
情形三:修改对象内部的属性值——允许
const obj = { a: 3 };
obj.a = 5; // 允许
需要厘清一个高频误区:const 保护的只是引用本身不被重新绑定(情形二被禁止),它并不保证值不可变。当保存的是对象这类复杂结构时,内部属性依然可以修改(情形三),因此 const obj 不代表 obj 是一个真正的"不可变对象"。
仓库印证:常量在真实游戏代码中的用法
太空射击游戏 app.js 用 const 锁定画布基准尺寸,同时用 const 保存对象常量,其中既有 number 也有 boolean:
const BASE_WIDTH = 1024;
const BASE_HEIGHT = 768;
const settings = {
difficulty: 'normal', // easy | normal | hard | insane
graphics: 'medium', // low | medium | high | ultra
musicVolume: 0.6, // 0..1
sfxVolume: 0.8, // 0..1
controlScheme: 'wasd',
muted: false // boolean
};
这正是"引用受保护、内容可变"的典型结构:settings 整体不会被重新赋值,但运行中可随时改写 settings.difficulty 等内部字段。
数据类型总览:JavaScript 如何组织信息
JavaScript 把信息划分成不同类别,也就是数据类型(data types)。类型之所以重要,是因为不同的操作只适配不同的信息种类——你无法对一个人的名字做算术,也无法把方程式按字母排序;只有为每次操作配上正确的数据类型,代码才可靠。
类型术语补充:这些最底层的类型常被称为 JavaScript 原始类型(primitives),一共 7 种:string、number、bigint、boolean、undefined、null 与 symbol。不妨自行想象每种原始类型长什么样:zebra 是什么?0 呢?true 呢?
JavaScript 是一门动态类型语言,两点直接推论值得记住:变量可随时更换类型、类型判断发生在运行期;同时命名区分大小写(age 与 Age 是两个不同的变量)。下面先看最常用的三个类型。
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 |
随手在浏览器 Console 里敲一条运算验证结果是否出乎意料。理解自测:/(除法)与 %(取余)的区别是什么?10 % 3 的答案是什么(提示:不是 3.33…)?为什么取余在编程里很有用?
实战洞察:% 非常擅长判断奇偶、构造循环图案,或在数组中循环取位。在打字游戏里,随机挑选句子的底层正是"取整 + 索引"的组合——见 打字游戏 index.js:const getRandomQuote = () => quotes[Math.floor(Math.random() * quotes.length)];。这里 Math.random() 返回 0~1 的小数、Math.floor() 向下取整到合法下标,是 number 运算的典型应用。
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 会把裸文本当成变量名去解析。
字符串对象自带能力,例如通过 .length 取长度、通过 .split() 分词、通过 .startsWith() / .endsWith() / .padStart() 做文本判断与格式化——打字游戏渲染引用句时就用到了 .split(" ") 与模板字符串拼 span,见 打字游戏 index.js。
格式化字符串(一):用 + 做拼接(concatenation)
拼接即用 + 把多个字符串连起来:
let myString1 = "Hello";
let myString2 = "World";
myString1 + myString2 + "!"; // "HelloWorld!"
myString1 + " " + myString2 + "!"; // "Hello World!"
myString1 + ", " + myString2 + "!"; // "Hello, World!"
逐行拆解:第一个例子把字符串直接连在一起、没有空格;第二例显式插入空格字符 " " 增强可读性;第三例再补上逗号等标点做正规排版。
思考题:为什么 JavaScript 里 1 + 1 = 2,而 '1' + '1' = '11'?那么 '1' + 1 呢?(答案见后文"动态类型与隐式转换"。)
格式化字符串(二):模板字符串(template literals)
模板字符串是 ES6 提供的第二种格式化手段:用反引号 ` 包裹字符串,凡不是纯文本的部分都必须放进 ${ } 占位符里(包括可能为字符串的变量):
let myString1 = "Hello";
let myString2 = "World";
`${myString1} ${myString2}!` // "Hello World!"
`${myString1}, ${myString2}!` // "Hello, World!"
逐点理解:
- 用反引号替代普通引号;
- 变量经
${}占位符语法直接嵌入; - 完全保留书写时的空格与换行格式;
- 构造含变量的复杂字符串时更干净。
两种方法都能达到目的,但模板字符串会严格尊重所有空格与换行。专业建议:处理复杂的多行字符串时优先模板字符串,可读性更好。
仓库印证一:打字游戏 index.html 用 String(now.getDate()).padStart(2, '0') 归一化日期后,再以模板字符串拼出 日期/月/年 与 时:分 AM/PM 文案。
仓库印证二:打字游戏 index.js 把不同场景文案定义成包含模板字符串的对象:
const messages = {
success: (seconds) => `🎉 Congratulations! You finished in ${seconds.toFixed(2)} seconds.`,
error: "⚠️ Oops! There's a mistake.",
start: "⌨️ Start typing to begin the game."
};
字符串与数字在同一模板字符串内无缝插值,seconds.toFixed(2) 又是 number 方法调用的典型例子。
Boolean:只有 true / false 的二元逻辑
布尔值是最简单也最根本的数据形态:只能取 true 或 false 两者之一,源流可追溯至 19 世纪数学家乔治·布尔建立的布尔代数。它支撑着程序的全部决策逻辑——用户是否已登录、按钮是否被点击、条件是否满足等。
声明方式:直接使用 true / false 关键字(不需要引号),并可交给条件语句使用:
let myTrueBool = true;
let myFalseBool = false;
truthy 与 falsy:所有值都可以"像真值"
布尔语境中,只要一个变量求值结果等价于 true,就可称它为 truthy(真值);反之则是 falsy(假值)。有趣的是,JavaScript 中除了被定义为 falsy 的值以外,其余一切都是 truthy。
记忆要点:falsy 全家桶只有 6 个——false、0、""(空字符串)、null、undefined 与 NaN。其余像 'hello'、42、空数组 []、空对象 {} 统统是 truthy。
自测:0、"0"、[]、"false" 这四者中哪些是 falsy?(答案是只有 0。"0" 是非空字符串、[] 与 "false" 均为 truthy。)
常见使用场景:条件逻辑分支、用户状态追踪、功能开关(feature toggle)与输入校验。太空游戏设置对象中的 muted: false 就是一枚典型的功能开关,见 太空射击游戏 app.js。
仓库印证:打字游戏的胜负与对错分支就是布尔逻辑的完整示范——typedValue === currentWord && wordIndex === words.length - 1 判定游戏结束,typedValue.trim() === currentWord 判定单词完成,见 打字游戏 index.js。
动态类型:为什么 '1' + 1 等于 '11'
承接上文的悬念:+ 一旦遇到字符串就变成"拼接"而非"加法",于是 '1' + '1' 得到 '11'、'1' + 1 同样得到 '11'(number 被自动转成 string 再拼接)。JavaScript 会自动在这类场景里做隐式类型转换(implicit type coercion);与之相对的,用 String()、Number()、Boolean() 等函数强转则是显式转换(explicit conversion)。
仓库印证:植物景观(terrarium)拖拽实现 script.js 里,number 位移量必须拼上 'px' 单位才能写入样式:
terrariumElement.style.top = terrariumElement.offsetTop - pos2 + 'px';
terrariumElement.style.left = terrariumElement.offsetLeft - pos1 + 'px';
这就是"数字 + 字符串 → 字符串"隐式转换在真实项目中的典型日常。而判断值的真实类型,可用 typeof 运算符;在"学生成绩处理器"练习里,正是用 typeof grade === 'number' 区分数字制与字母制成绩并走不同判定逻辑的,详见 决策分支课的作业。
动手挑战:结合真实场景巩固掌握
本课配套作业是"电商购物车"练习(2-js-basics/1-data-types/assignment.md):要求为 7 种原始类型外加 object / array 各找出一个购物车场景——字符串管商品名与描述、数字管价格与数量、布尔管库存与偏好、null 表示"折扣码空缺"、undefined 表示未初始化数据、symbol 做唯一标识、bigint 处理大额财务计算,并分别说明选型理由、给出可运行代码与类型间交互。
经典排错挑战:在 Console 输入并观察:
let age = 1;
let Age = 2;
age == Age; // 返回 false
结果为什么是 false?原因正是前面强调的命名区分大小写:age 与 Age 是两个完全不同的变量,比较的是 1 与 2,自然不相等。吃透这类"怪癖"能显著提升排错效率。
五到十分钟即可完成:打开 Console 创建三个不同数据类型的变量 → 跑一遍上面的 age/Age 挑战 → 用你的名字和幸运数字练习字符串拼接 → 试一次"数字加字符串"观察隐式转换。
本时段进阶:做一个加减乘除迷你计算器;用模板字符串写一个姓名格式化函数;对比 == 与 === 的差异;练习在不同类型间做显式转换。
小结
无论将来写出多少行 JavaScript,变量、常量与数据类型都会贯穿始终。本课需要牢固掌握的要点可浓缩为:let 可变、const 引用不可变(但对象内容可改);7 种原始类型之中 number 搭配 + - * / %、string 支持引号与反引号两种书写方式并用 + 拼接或模板插值、boolean 只有 true/false 且全宇宙只有 6 个 falsy 值;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 StartedRust0624
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
