JavaScript 教程

纯干货教学,从零开始学习 JavaScript

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. 块级作用域

在块(如 iffor 等)内部使用 letconst 声明的变量具有块级作用域,只能在块内部访问:

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 的变量提升

letconst 也会被提升,但在声明之前访问会导致 "暂时性死区" 错误:

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 的区别
  • 变量的作用域(全局作用域、函数作用域、块级作用域)
  • 变量提升的概念
  • 变量的命名规则
  • 变量的解构赋值
  • 变量的作用域链