首页
/ Web-Dev-For-Beginners 课程笔记:JavaScript 变量、常量的声明规则与 number、string、boolean 三大基础数据类型全解

Web-Dev-For-Beginners 课程笔记:JavaScript 变量、常量的声明规则与 number、string、boolean 三大基础数据类型全解

2026-09-07 11:43:53作者:伍希望

本指南以《Web-Dev-For-Beginners》开源课程中 2-js-basics/1-data-types 一课为骨架展开,系统讲解 JavaScript 中变量与常量的声明语法、赋值语义、number / string / boolean 三类核心数据类型及其配套运算符与格式化技巧。课程所属的 JS 基础模块共 4 课,其余内容见 模块导读。读完本文后,你将能够正确选用 let/const 组织可变与不可变状态,熟练完成算术运算、字符串拼接与模板字符串插值,并准确判断值在条件语境下的 truthy/falsy 行为,为后续函数、分支、数组与循环打好地基。

JavaScript 数据类型教学草图

上图为本课配套的 sketchnote,手绘梳理了 var/let/const 的作用域差异、字符串/数字/布尔三类数据类型、算术运算符与全局/函数/块级作用域的关系。

变量:声明、赋值与重赋值

声明语法:[关键字] [变量名]

创建变量在语法上由两部分组成:

  • 关键字:值会变化时用 let;值保持不变时用 const
  • 变量名:由你自行选择的描述性名称,例如保存某人年龄用 age,追踪用户名用 userName

这里聚焦现代写法。let 是 ES6 引入的,它为变量赋予块级作用域(block scope),官方建议用 letconst 取代更早期的 var(作用域的深入话题留待后续课程)。课程用一个贴近生活的比喻帮助记忆:变量像中世纪炼金术士贴了标签的罐子,需要记住某人年龄就放进名为 age 的罐子,需要追踪用户名就放进名为 userName 的罐子。

动手任务:四步掌握变量的生命周期

  1. 声明变量——创建一个"空"的存储位置:
let myVariable;

效果是:告诉 JavaScript 建立名为 myVariable 的存储位置、为其在内存中分配空间,此刻该变量没有任何值(值为 undefined)。

  1. 给变量赋值——向罐子里放入内容:
myVariable = 123;

这里的 =赋值运算符(assignment operator),表示"把 123 设给变量",不代表数学意义上的相等。赋值后,变量原本的 undefined 被数值 123 取代,之后整份代码中你都能通过 myVariable 引用这个值。

  1. 合并两步(更聪明的做法)
let myVariable = 123;

声明的同时完成初始化,这是开发者的标准实践,缩短代码且保持清晰。

  1. 重赋值——如果想换一个数:
myVariable = 321;

变量现在装的是 321 而不是 123,旧值被整体替换——同一时刻变量只能保存一个值。这种可变性正是 let 声明的关键特征。

动手实验:浏览器中打开开发者工具(DevTools),在 Console 提示符输入 let myVariable = 123 回车,再输入 myVariable 回车,观察返回结果。建议同时思考三个问题:声明与赋值有何区别?在声明之前使用变量会发生什么?什么场景你该选 let 而非 const

快速记忆法:变量是有标签的储物箱——用 let"造箱",用 ="装箱",必要时还能"换货"。

常量:一经赋值,不可再改

有时信息在程序运行期间绝不允许变化,例如数学常量。常量与变量的机制相似,但多了一条硬性限制:一旦赋值,不能再改。声明的语法除关键字换成 const 外与变量相同,且常量通常约定全大写命名

const MY_VARIABLE = 123;

常量两条铁律

  1. 必须立即赋值——不存在"空常量";
  2. 该值永远不可改变——一旦尝试修改,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.jsconst 锁定画布基准尺寸,同时用 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 种stringnumberbigintbooleanundefinednullsymbol。不妨自行想象每种原始类型长什么样:zebra 是什么?0 呢?true 呢?

JavaScript 是一门动态类型语言,两点直接推论值得记住:变量可随时更换类型、类型判断发生在运行期;同时命名区分大小写ageAge 是两个不同的变量)。下面先看最常用的三个类型。

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.jsconst 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.htmlString(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 的二元逻辑

布尔值是最简单也最根本的数据形态:只能取 truefalse 两者之一,源流可追溯至 19 世纪数学家乔治·布尔建立的布尔代数。它支撑着程序的全部决策逻辑——用户是否已登录、按钮是否被点击、条件是否满足等。

声明方式:直接使用 true / false 关键字(不需要引号),并可交给条件语句使用:

let myTrueBool = true;
let myFalseBool = false;

truthy 与 falsy:所有值都可以"像真值"

布尔语境中,只要一个变量求值结果等价于 true,就可称它为 truthy(真值);反之则是 falsy(假值)。有趣的是,JavaScript 中除了被定义为 falsy 的值以外,其余一切都是 truthy

记忆要点:falsy 全家桶只有 6 个——false0""(空字符串)、nullundefinedNaN。其余像 '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?原因正是前面强调的命名区分大小写ageAge 是两个完全不同的变量,比较的是 1 与 2,自然不相等。吃透这类"怪癖"能显著提升排错效率。

五到十分钟即可完成:打开 Console 创建三个不同数据类型的变量 → 跑一遍上面的 age/Age 挑战 → 用你的名字和幸运数字练习字符串拼接 → 试一次"数字加字符串"观察隐式转换。

本时段进阶:做一个加减乘除迷你计算器;用模板字符串写一个姓名格式化函数;对比 ===== 的差异;练习在不同类型间做显式转换。

小结

无论将来写出多少行 JavaScript,变量、常量与数据类型都会贯穿始终。本课需要牢固掌握的要点可浓缩为:let 可变、const 引用不可变(但对象内容可改);7 种原始类型之中 number 搭配 + - * / %string 支持引号与反引号两种书写方式并用 + 拼接或模板插值、boolean 只有 true/false 且全宇宙只有 6 个 falsy 值;JavaScript 动态类型意味着变量可换类型、命名必须区分大小写,并在字符串参与的运算里自动做隐式转换。掌握了这些"字母表",就可以继续进入 函数与方法分支决策数组循环 的篇章,在真实项目中搭建交互式应用。

登录后查看全文
热门项目推荐
相关项目推荐