本文深入讲解JavaScript变量声明关键字(var、let、const)的核心区别、7种原始数据类型与引用类型的特性,并通过内存模型、完整可运行代码示例和类型检测方案帮助读者打牢JS基础。
JavaScript变量声明与数据类型基础代码示例
作者:闭包旅人
时间:2026-10-30
浏览:196
文章目录
JavaScript 作为一门动态弱类型脚本语言,变量声明与类型系统构成了所有逻辑运算与程序结构的基础。理解变量在内存中的分配机制、作用域限制以及各数据类型的运算表现,是编写健壮、可维护前端与 Node.js 应用程序的前提。
一、变量声明关键字:var、let 与 const
在 ECMAScript 6 (ES2015) 规范推出之前,JavaScript 仅支持使用 var 声明变量。ES6 引入了 let 和 const,彻底解决了变量提升、全局污染及缺乏块级作用域等历史遗留设计缺陷。
图 1:var、let 与 const 的核心语法行为差异对比
1. 作用域隔离与暂时性死区 (TDZ) 代码演示
// 示例 1: var 的函数作用域与泄漏问题
if (true) {
var globalLeak = "泄漏到块级外部";
let blockScoped = "仅在块内有效";
}
console.log(globalLeak); // 输出: "泄漏到块级外部"
// console.log(blockScoped); // 报错: ReferenceError: blockScoped is not defined
// 示例 2: 暂时性死区 (Temporal Dead Zone, TDZ)
// 变量在声明前处于死区,无法被访问
function testTDZ() {
// console.log(age); // 抛出 ReferenceError,不会像 var 那样输出 undefined
let age = 28;
console.log(age); // 正常输出: 28
}
testTDZ();
// 示例 3: const 的常量绑定限制
const MAX_LIMIT = 100;
// MAX_LIMIT = 200; // 报错: TypeError: Assignment to constant variable.
// 注意: const 锁定的是变量指针本身,而非引用对象内部属性
const userConfig = { theme: "light" };
userConfig.theme = "dark"; // 完全合法,未改变 userConfig 的引用地址
console.log(userConfig.theme); // 输出: "dark"
二、JavaScript 数据类型系统分类
最新的 ECMAScript 规范定义了 8 种数据类型,分为两大阵营:7 种原始数据类型(Primitive Types) 与 1 种引用数据类型(Reference Type / Object)。
图 2:JavaScript 数据类型系统分层全景
三、原始数据类型实战代码示例
原始值直接存放在调用栈中,属于不可变值(Immutable Values)。对原始类型的修改实际上是在内存中创建了一个新值,而非原处修改。
// 1. Number: 包含整数、浮点数以及特殊数值 NaN 与 Infinity
const integerNum = 42;
const floatNum = 3.14159;
const notANumber = NaN; // 无法计算时的数值结果,类型仍为 "number"
const inf = Infinity; // 超出上限的值(如 1 / 0)
// 2. String: 字符序列,支持单引号、双引号及反引号模板字面量
const greeting = "Hello";
const userName = 'Bob';
const fullMessage = `${greeting}, ${userName}! 计算和为: ${1 + 1}`;
// 3. Boolean: 仅有两个真假字面量
const isProduction = false;
const hasPermission = true;
// 4. Undefined: 声明但未初始化的变量默认值
let assignedLater;
console.log(assignedLater); // 输出: undefined
// 5. Null: 明确表示“空值”或“无对象”
const activeConnection = null; // 手动释放或占位
// 6. Symbol: 生成全局唯一的属性键名,常用于避免命名冲突
const sym1 = Symbol("token");
const sym2 = Symbol("token");
console.log(sym1 === sym2); // 输出: false(即使描述相同也绝不相等)
// 7. BigInt: 超出 Number.MAX_SAFE_INTEGER (2^53 - 1) 的大整数
const safeMax = Number.MAX_SAFE_INTEGER; // 9007199254740991
const largeInt = 9007199254740995n; // 数字尾部追加字母 n
四、内存存储模型:栈内存与堆内存
JavaScript 引擎(如 V8)在运行时将内存划分为执行上下文所在的调用栈(Stack)和存储复杂数据结构的堆内存(Heap)。理解这两种存储方式是掌握深浅拷贝与函数传参的核心。
图 3:栈内存直接存储原始值,引用类型在栈中保存指向堆内存的指针
按值复制与按引用共享的代码对比
// 场景 1: 原始值的独立复制
let a = 10;
let b = a; // 栈中开辟新空间存放 10
b = 20; // 修改 b 对 a 无任何影响
console.log(a); // 10
console.log(b); // 20
// 场景 2: 引用值的浅层地址共享
const originalList = ["React", "Vue"];
const referenceCopy = originalList; // 复制的是内存指针 0x7FFE20
referenceCopy.push("Angular");
// 两个变量指向同一片堆空间,互相受影响
console.log(originalList); // ["React", "Vue", "Angular"]
console.log(referenceCopy); // ["React", "Vue", "Angular"]
五、数据类型判断与避坑指南
JavaScript 提供了 typeof、instanceof 以及 Object.prototype.toString.call() 等多种类型检测手段,各自有不同的适用范围和隐蔽陷阱。
图 4:按需选择最佳数据类型判断方式的操作流程
常见类型检测代码实操
// 1. typeof 运算符及其著名历史遗留 Bug
console.log(typeof 42); // "number"
console.log(typeof "text"); // "string"
console.log(typeof true); // "boolean"
console.log(typeof undefined); // "undefined"
console.log(typeof Symbol()); // "symbol"
console.log(typeof 100n); // "bigint"
console.log(typeof function(){}); // "function"
// 警惕:null 被历史代码标记为了对象类型
console.log(typeof null); // "object"(必须使用 val === null 进行精准比对)
// 2. 数组专用判断
const arr = [1, 2, 3];
console.log(Array.isArray(arr)); // true
console.log(typeof arr); // "object"(typeof 无法识别数组)
// 3. 通用高精度类型检测封装函数
function getExactType(target) {
const rawString = Object.prototype.toString.call(target); // "[object Type]"
return rawString.slice(8, -1).toLowerCase();
}
console.log(getExactType(null)); // "null"
console.log(getExactType(/^[a-z]+$/)); // "regexp"
console.log(getExactType(new Date())); // "date"
console.log(getExactType(new Map())); // "map"
六、工程实践中的声明最佳规范
变量声明原则总结
- 优先使用
const:确保变量在没有二次赋值需求时维持指针不变,不仅能提升代码可读性与意图明确性,还能帮助 JavaScript 引擎进行编译器优化。 - 仅在需重新赋值时使用
let:例如for循环计数器、累加器或在条件分支中逐步赋值的状态变量。 - 彻底弃用
var:现代工程搭配 ESLint(规则如no-var: "error")已全面禁止var,避免全局变量污染和作用域冒泡隐患。
实用工具推荐
电子包浆
使用 ›绿化、压缩、噪点和虚拟水印,自由调节做旧程度。
图片压缩
使用 ›选择画质和输出格式,预览压缩前后的大小。
作者最新文章
相关文章