JavaScript 变量
变量是 JavaScript 中存储数据的容器。本章节将介绍 JavaScript 变量的声明、作用域和使用方法。
🎯 变量的重要性
变量是编程的基础概念,掌握变量的使用是学习任何编程语言的第一步。在 JavaScript 中,正确使用变量可以使你的代码更加清晰、高效。
变量的声明
在 JavaScript 中,有三种声明变量的方式:
1. var 声明
var 是 ES5 中声明变量的方式,具有函数作用域:
// 声明变量
var name = "John";
var age = 30;
// 重新赋值
name = "Jane";
age = 25;
// 声明多个变量
var x = 10, y = 20, z = 30;
// 声明但未初始化
var message;
console.log(message); // undefined
2. let 声明
let 是 ES6 中新增的声明变量的方式,具有块级作用域:
// 声明变量
let name = "John";
let age = 30;
// 重新赋值
name = "Jane";
age = 25;
// 声明多个变量
let x = 10, y = 20, z = 30;
// 声明但未初始化
let message;
console.log(message); // undefined
3. const 声明
const 也是 ES6 中新增的声明变量的方式,用于声明常量,具有块级作用域:
// 声明常量
const PI = 3.14;
const name = "John";
// 常量不能重新赋值
// PI = 3.14159; // 报错:Assignment to constant variable.
// 但对象和数组的内容可以修改
const person = {name: "John", age: 30};
person.age = 31; // 允许
const fruits = ["apple", "banana"];
fruits.push("orange"); // 允许
var、let 和 const 的区别
| 特性 | var | let | const |
|---|---|---|---|
| 作用域 | 函数作用域 | 块级作用域 | 块级作用域 |
| 变量提升 | 是 | 否(但声明会被提升,初始化不会) | 否(但声明会被提升,初始化不会) |
| 重新赋值 | 允许 | 允许 | 不允许 |
| 重复声明 | 允许 | 不允许 | 不允许 |
| 必须初始化 | 否 | 否 | 是 |
变量的作用域
变量的作用域是指变量在代码中可以被访问的范围:
1. 全局作用域
在函数外部声明的变量具有全局作用域,可以在代码的任何地方访问:
// 全局变量
var globalVar = "Global";
let globalLet = "Global Let";
const globalConst = "Global Const";
function myFunction() {
console.log(globalVar); // 可以访问
console.log(globalLet); // 可以访问
console.log(globalConst); // 可以访问
}
myFunction(); // 输出: Global, Global Let, Global Const
2. 函数作用域
在函数内部使用 var 声明的变量具有函数作用域,只能在函数内部访问:
function myFunction() {
// 函数作用域变量
var functionVar = "Function Var";
console.log(functionVar); // 可以访问
}
myFunction(); // 输出: Function Var
console.log(functionVar); // 报错: functionVar is not defined
3. 块级作用域
在块(如 if、for 等)内部使用 let 或 const 声明的变量具有块级作用域,只能在块内部访问:
if (true) {
// 块级作用域变量
let blockLet = "Block Let";
const blockConst = "Block Const";
var blockVar = "Block Var"; // var 没有块级作用域
console.log(blockLet); // 可以访问
console.log(blockConst); // 可以访问
console.log(blockVar); // 可以访问
}
console.log(blockLet); // 报错: blockLet is not defined
console.log(blockConst); // 报错: blockConst is not defined
console.log(blockVar); // 可以访问,因为 var 没有块级作用域
变量提升
变量提升是 JavaScript 的一个特性,指变量声明会被提升到作用域的顶部:
var 变量提升
console.log(x); // undefined,变量声明被提升,但初始化没有
var x = 5;
console.log(x); // 5
let 和 const 的变量提升
let 和 const 也会被提升,但在声明之前访问会导致 "暂时性死区" 错误:
console.log(y); // 报错: Cannot access 'y' before initialization
let y = 10;
console.log(z); // 报错: Cannot access 'z' before initialization
const z = 20;
变量的命名规则
JavaScript 变量的命名规则:
- 变量名必须以字母、下划线(_)或美元符号($)开头
- 变量名不能以数字开头
- 变量名只能包含字母、数字、下划线和美元符号
- 变量名区分大小写(name 和 Name 是不同的变量)
- 变量名不能是 JavaScript 关键字或保留字
有效的变量名
let name = "John";
let _age = 30;
let $salary = 5000;
let firstName = "Jane"; // 驼峰命名法
let last_name = "Doe"; // 下划线命名法
无效的变量名
// 无效的变量名
// let 1name = "John"; // 以数字开头
// let name-1 = "John"; // 包含连字符
// let if = "John"; // 是 JavaScript 关键字
// let true = "John"; // 是 JavaScript 关键字
变量的最佳实践
- 使用 let 和 const,避免使用 var:let 和 const 提供了更清晰的作用域规则
- 优先使用 const:对于不需要重新赋值的变量,使用 const 可以防止意外修改
- 使用有意义的变量名:变量名应该描述变量的用途
- 使用一致的命名风格:如驼峰命名法(camelCase)
- 避免全局变量:全局变量容易导致命名冲突,应尽量避免
- 声明变量时初始化:避免使用未初始化的变量
变量的类型转换
JavaScript 是一种动态类型语言,变量的类型可以在运行时改变:
1. 自动类型转换
let x = 5; // 数字
let y = "10"; // 字符串
console.log(x + y); // "510",数字转换为字符串
console.log(x - y); // -5,字符串转换为数字
console.log(x * y); // 50,字符串转换为数字
console.log(x / y); // 0.5,字符串转换为数字
2. 显式类型转换
// 转换为字符串
let x = 5;
let str = String(x);
let str2 = x.toString();
// 转换为数字
let y = "10";
let num = Number(y);
let num2 = parseInt(y);
let num3 = parseFloat(y);
// 转换为布尔值
let z = "";
let bool = Boolean(z); // false
变量的解构赋值
ES6 引入了解构赋值,可以从对象或数组中提取值并赋给变量:
1. 数组解构
// 数组解构
const fruits = ["apple", "banana", "orange"];
const [first, second, third] = fruits;
console.log(first); // apple
console.log(second); // banana
console.log(third); // orange
// 跳过某些元素
const [, , thirdFruit] = fruits;
console.log(thirdFruit); // orange
// 剩余参数
const [firstFruit, ...rest] = fruits;
console.log(rest); // ["banana", "orange"]
2. 对象解构
// 对象解构
const person = {name: "John", age: 30, city: "New York"};
const {name, age, city} = person;
console.log(name); // John
console.log(age); // 30
console.log(city); // New York
// 重命名变量
const {name: firstName, age: personAge} = person;
console.log(firstName); // John
console.log(personAge); // 30
// 默认值
const {name, age, city, country = "USA"} = person;
console.log(country); // USA
变量的作用域链
当在 JavaScript 中访问一个变量时,JavaScript 引擎会从当前作用域开始查找,如果找不到,会向上查找父级作用域,直到找到该变量或到达全局作用域:
// 全局变量
const globalVar = "Global";
function outerFunction() {
// 外部函数变量
const outerVar = "Outer";
function innerFunction() {
// 内部函数变量
const innerVar = "Inner";
console.log(innerVar); // 内部作用域
console.log(outerVar); // 外部作用域
console.log(globalVar); // 全局作用域
}
innerFunction();
}
outerFunction();
💡 学习提示
在 JavaScript 中使用变量时,建议:
- 尽量使用
const声明变量,除非你确实需要重新赋值 - 使用
let声明需要重新赋值的变量 - 避免使用
var,因为它的作用域规则可能会导致意外行为 - 使用有意义的变量名,提高代码可读性
- 理解变量的作用域,避免变量泄露和命名冲突
📝 学习检查
通过本章节的学习,你应该掌握:
- JavaScript 中三种声明变量的方式(var、let、const)
- var、let 和 const 的区别
- 变量的作用域(全局作用域、函数作用域、块级作用域)
- 变量提升的概念
- 变量的命名规则
- 变量的解构赋值
- 变量的作用域链