Skip to content

JavaScript 变量声明

变量是编程语言中最基本的概念之一,用于存储和操作数据。在 JavaScript 中,变量声明是一个重要的主题,因为它涉及到作用域、生命周期和内存管理等多个方面。在本章节中,我们将深入学习 JavaScript 中的变量声明方式及其特点。

变量声明的历史演变

JavaScript 的变量声明方式随着语言的发展而演变:

  1. ES5 及之前:只有一种声明方式 var
  2. ES6 (ES2015):引入了 letconst
  3. 现代 JavaScript:推荐使用 letconst,避免使用 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 defined

2. 变量提升(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); // 2

let 声明

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 declared

4. 循环中的作用域

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 declaration

const 的特点

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 defined

4. 对象和数组的特殊情况

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 推荐做法

  1. 优先使用 const:当变量不需要重新赋值时
  2. 必要时使用 let:当变量需要重新赋值时
  3. 避免使用 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); // 5

let 和 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 变量声明的要点:

  1. 三种声明方式

    • var:函数作用域,可重复声明,存在变量提升
    • let:块级作用域,不可重复声明,存在暂时性死区
    • const:块级作用域,不可重新赋值,必须初始化
  2. 现代推荐做法

    • 优先使用 const,必要时使用 let
    • 避免使用 var
  3. 作用域概念

    • 全局作用域
    • 函数作用域(var)
    • 块级作用域(let、const)
  4. 变量提升

    • var 会提升声明但不提升赋值
    • let 和 const 会提升但存在暂时性死区
  5. 命名规范

    • 使用有意义的变量名
    • 遵循驼峰命名法
    • 常量使用全大写

掌握变量声明是学习 JavaScript 的重要基础。在下一章节中,我们将学习 JavaScript 的对象。

本站内容仅供学习和研究使用。