变量和数据类型是编程中最基础的概念,它们构成了程序中存储和操作信息的基石。在 JavaScript 中,深入理解这些概念对于编写高效、可读性强的代码至关重要。
掌握 JavaScript 中三种变量声明方式(var、let、const)的区别
理解 JavaScript 的原始类型(Primitive)与非原始类型(Non-primitive)
能够解释常见的 JavaScript 表达式行为(如 null === undefined、"10" < "9" 等)
避免因类型转换和引用比较导致的常见陷阱
变量就像一个容器,用于保存程序中可重用或可更新的数据。JavaScript 提供了三种关键字来声明变量:var、let 和 const。
var 关键字作用域:函数作用域或全局作用域
可重复声明:允许在同一作用域内多次声明
存在变量提升(Hoisting)
var n = 5;
console.log(n); // 输出:5
var n = 20; // 允许重新赋值,甚至重新声明
console.log(n); // 输出:20注意:由于
var的作用域规则较宽松,现代开发中通常推荐使用let或const。
let 关键字ES6 引入
作用域:块级作用域({} 内)
不可重复声明:同一作用域内不能重复声明
可重新赋值
let n = 10;
n = 20; // 允许更新值
// let n = 15; // 报错:不能在同一作用域重复声明
console.log(n); // 输出:20const 关键字ES6 引入
作用域:块级作用域
不可重新赋值:声明时必须初始化,且之后不能指向新值
注意:若值为对象或数组,其内部属性仍可修改
const n = 100;
// n = 200; // 报错:不能重新赋值
console.log(n); // 输出:100最佳实践:优先使用
const,仅在需要重新赋值时使用let。
JavaScript 的数据类型分为两大类:
原始类型(Primitive):不可变,按值传递
非原始类型(Non-primitive / Reference Types):可变,按引用传递
注意:
typeof null返回"object",这是 JavaScript 的历史遗留 bug。
引用类型
所有非原始类型本质上都是
Object的子类型。
以下是一些看似简单却容易出错的 JavaScript 表达式,理解它们有助于避免陷阱。
null === undefined → falseconsole.log(null === undefined); // falsenull 是“有意为空”的对象(类型为 object)
undefined 表示“未定义”(类型为 undefined)
=== 不进行类型转换,因此不相等
正确判断空值:
if (value == null) // 可同时匹配 null 和 undefined(利用 == 的类型转换)5 > 3 > 2 → falseconsole.log(5 > 3 > 2); // false解析过程:
5 > 3 → true
true > 2 → 1 > 2(true 被转为 1)→ false
想表达数学中的连续比较?应写成:
(5 > 3) && (3 > 2)
[] === [] → falseconsole.log([] === []); // false数组是对象,=== 比较的是内存地址(引用)
即使内容相同,两个数组也是不同的对象
深度比较数组需手动实现或使用工具库(如 Lodash 的 _.isEqual)
"10" < "9" → trueconsole.log("10" < "9"); // true字符串按 ** 字典序(Unicode 编码)** 逐字符比较
'1' 的 Unicode 值(49)小于 '9'(57),所以 "10" < "9"
字符串比较 ≠ 数值比较!如需数值比较,先转换类型:
Number("10") < Number("9")
NaN === NaN → falseconsole.log(NaN === NaN); // falseNaN 表示“不是一个数”,根据 IEEE 754 标准,它不等于任何值,包括自己
正确检测 NaN:
Number.isNaN(value); // 推荐
// 或
isNaN(value); // 但会进行类型转换,可能误判true == 1 → trueconsole.log(true == 1); // true== 会进行隐式类型转换:true → 1,然后 1 == 1 → true
建议始终使用
===避免意外转换
undefined > 0 → falseconsole.log(undefined > 0); // falseundefined 在数值运算中被转为 NaN
任何涉及 NaN 的比较都返回 false
"5" === 5 → falseconsole.log('"5" === 5'); // false=== 同时检查值和类型
字符串 "5" 与数字 5 类型不同
若需比较数值,显式转换:
Number("5") === 5; // true[1, 2] == [1, 2] → falseconsole.log([1, 2] == [1, 2]); // false即使使用 ==,数组仍按引用比较(不会深度比较内容)
Infinity > 1000 → trueconsole.log(Infinity > 1000); // trueInfinity 表示正无穷大,大于任何有限数值

为什么 typeof null 返回 "object"?这是否是一个 bug?如何安全地判断一个值是否为 null?
如果你有一个数组 arr = [1, 2, 3],执行 const copy = arr; copy.push(4); 后,arr 的值是什么?为什么?
如何正确判断两个数组的内容是否完全相等?请写出一个简单的函数实现。