JavaScript 变量声明
变量是编程语言中最基本的概念之一,用于存储和操作数据。在 JavaScript 中,变量声明是一个重要的主题,因为它涉及到作用域、生命周期和内存管理等多个方面。在本章节中,我们将深入学习 JavaScript 中的变量声明方式及其特点。
变量声明的历史演变
JavaScript 的变量声明方式随着语言的发展而演变:
- ES5 及之前:只有一种声明方式
var - ES6 (ES2015):引入了
let和const - 现代 JavaScript:推荐使用
let和const,避免使用var
var 声明
var 是 JavaScript 最早的变量声明方式,但它有一些特殊的特性,现在通常不推荐使用。
基本用法
javascript
var name = "张三";
var age = 25;
var isStudent = true;
// 可以声明多个变量
var x = 1, y = 2, z = 3;
// 可以先声明后赋值
var greeting;
greeting = "你好";var 的特点
1. 函数作用域
javascript
function example() {
if (true) {
var x = 1;
}
console.log(x); // 1(可以访问)
}
example();
// 在块级作用域外无法访问
// console.log(x); // ReferenceError: x is not defined2. 变量提升(Hoisting)
javascript
console.log(name); // undefined(不是报错)
var name = "张三";
console.log(name); // "张三"
// 上面的代码实际上等同于:
// var name;
// console.log(name); // undefined
// name = "张三";
// console.log(name); // "张三"3. 可以重复声明
javascript
var a = 1;
var a = 2; // 不会报错
console.log(a); // 2let 声明
let 是 ES6 引入的块级作用域变量声明方式,解决了 var 的一些问题。
基本用法
javascript
let name = "李四";
let age = 30;
let isEmployed = true;
// 可以声明多个变量
let x = 1, y = 2, z = 3;
// 可以先声明后赋值
let greeting;
greeting = "你好";let 的特点
1. 块级作用域
javascript
function example() {
if (true) {
let x = 1;
}
// console.log(x); // ReferenceError: x is not defined
}
example();2. 暂时性死区(Temporal Dead Zone)
javascript
console.log(name); // ReferenceError: Cannot access 'name' before initialization
let name = "李四";
// let 声明的变量在声明之前是不可访问的3. 不可重复声明
javascript
let a = 1;
// let a = 2; // SyntaxError: Identifier 'a' has already been declared4. 循环中的作用域
javascript
// 使用 var
for (var i = 0; i < 3; i++) {
setTimeout(() => {
console.log("var:", i); // 输出三次 "var: 3"
}, 100);
}
// 使用 let
for (let j = 0; j < 3; j++) {
setTimeout(() => {
console.log("let:", j); // 输出 "let: 0", "let: 1", "let: 2"
}, 100);
}const 声明
const 用于声明常量,一旦声明就不能重新赋值。
基本用法
javascript
const PI = 3.14159;
const NAME = "王五";
const IS_ACTIVE = true;
// 必须在声明时初始化
// const AGE; // SyntaxError: Missing initializer in const declarationconst 的特点
1. 必须初始化
javascript
const name = "赵六"; // 正确
// const age; // 错误:必须初始化2. 不可重新赋值
javascript
const MAX_SIZE = 100;
// MAX_SIZE = 200; // TypeError: Assignment to constant variable.3. 块级作用域
javascript
if (true) {
const MESSAGE = "Hello";
}
// console.log(MESSAGE); // ReferenceError: MESSAGE is not defined4. 对象和数组的特殊情况
javascript
// 对象本身不可重新赋值,但属性可以修改
const person = { name: "张三", age: 25 };
person.age = 26; // 正确
console.log(person.age); // 26
// person = { name: "李四" }; // 错误:Assignment to constant variable.
// 数组也是如此
const numbers = [1, 2, 3];
numbers.push(4); // 正确
console.log(numbers); // [1, 2, 3, 4]
// numbers = [5, 6, 7]; // 错误:Assignment to constant variable.声明方式的选择
现代 JavaScript 推荐做法
- 优先使用
const:当变量不需要重新赋值时 - 必要时使用
let:当变量需要重新赋值时 - 避免使用
var:除非需要兼容老版本浏览器
javascript
// 好的做法
const userName = "张三"; // 不会改变
let userAge = 25; // 可能会改变
userAge = 26; // 正确
// 不推荐的做法
var oldStyle = "过时的写法";实际应用示例
javascript
// 配置常量
const API_URL = "https://api.example.com";
const MAX_RETRY_COUNT = 3;
// 循环变量
for (let i = 0; i < 10; i++) {
console.log(i);
}
// 条件变量
let isLoggedIn = false;
if (someCondition) {
isLoggedIn = true;
}
// 对象引用
const config = {
theme: "dark",
language: "zh-CN"
};
// 可以修改属性
config.theme = "light";变量提升(Hoisting)
变量提升是 JavaScript 执行上下文的工作方式。
var 的提升
javascript
console.log(a); // undefined
var a = 5;
console.log(a); // 5
// 实际执行顺序:
// var a;
// console.log(a); // undefined
// a = 5;
// console.log(a); // 5let 和 const 的提升
javascript
console.log(b); // ReferenceError: Cannot access 'b' before initialization
let b = 10;
console.log(c); // ReferenceError: Cannot access 'c' before initialization
const c = 15;作用域(Scope)
作用域决定了变量的可访问范围。
全局作用域
javascript
const globalVar = "全局变量";
function example() {
console.log(globalVar); // 可以访问
}函数作用域
javascript
function outer() {
var functionVar = "函数作用域变量";
function inner() {
console.log(functionVar); // 可以访问
}
inner();
}块级作用域
javascript
{
let blockVar = "块级作用域变量";
const blockConst = "块级作用域常量";
console.log(blockVar); // 可以访问
console.log(blockConst); // 可以访问
}
// console.log(blockVar); // ReferenceError
// console.log(blockConst); // ReferenceError变量命名规范
命名规则
javascript
// 正确的命名
let userName = "张三";
let $price = 99.99;
let _private = "私有变量";
let camelCase = "驼峰命名法";
// 错误的命名
// let 123name = "错误"; // 不能以数字开头
// let my-variable = "错误"; // 不能包含连字符
// let let = "错误"; // 不能使用保留关键字命名约定
javascript
// 普通变量使用驼峰命名法
let firstName = "张";
let lastName = "三";
// 常量使用全大写字母和下划线
const MAX_SIZE = 100;
const DEFAULT_CONFIG = {
theme: "light",
language: "zh-CN"
};
// 私有变量以下划线开头(约定)
let _internalValue = "内部使用";
// 构造函数使用帕斯卡命名法
function UserManager() {
// 构造函数体
}变量声明的最佳实践
1. 使用 const 优先原则
javascript
// 好的做法
const users = [];
const config = {};
// 当需要重新赋值时使用 let
let currentUser = null;
if (isLoggedIn) {
currentUser = getUserInfo();
}2. 避免全局变量污染
javascript
// 不好的做法
var globalCounter = 0;
// 好的做法
const App = {
counter: 0
};
// 或者使用模块
const counterModule = (() => {
let counter = 0;
return {
increment() {
counter++;
},
getValue() {
return counter;
}
};
})();3. 合理分组声明
javascript
// 相关的变量可以一起声明
const WIDTH = 800;
const HEIGHT = 600;
const ASPECT_RATIO = WIDTH / HEIGHT;
// 不相关的变量分开声明
const userName = "张三";
let userAge = 25;
const isLoggedIn = true;总结
JavaScript 变量声明的要点:
三种声明方式:
var:函数作用域,可重复声明,存在变量提升let:块级作用域,不可重复声明,存在暂时性死区const:块级作用域,不可重新赋值,必须初始化
现代推荐做法:
- 优先使用
const,必要时使用let - 避免使用
var
- 优先使用
作用域概念:
- 全局作用域
- 函数作用域(var)
- 块级作用域(let、const)
变量提升:
- var 会提升声明但不提升赋值
- let 和 const 会提升但存在暂时性死区
命名规范:
- 使用有意义的变量名
- 遵循驼峰命名法
- 常量使用全大写
掌握变量声明是学习 JavaScript 的重要基础。在下一章节中,我们将学习 JavaScript 的对象。