Skip to content

JavaScript 变量

JavaScript 变量是用于存储数据值的命名容器。可以把它们想象成程序需要记住和处理的信息的标签。

在这个例子中,x、y 和 sum 都是变量:

const x = 5;
const y = 6;
const sum = x + y; // sum 将存储值 11

从上面的例子中可以看出:

  • x 存储值 5。
  • y 存储值 6。
  • sum 存储 x + y 的结果,即 11。

在现代 JavaScript(ES6 及更高版本)中,变量通常使用 let 和 const 声明。旧的关键字 var 也存在,但它的作用域规则不同,在新代码中通常应避免使用。

  • let: 声明一个块级作用域变量。let 变量的值可以重新赋值。
  • const: 声明一个块级作用域常量。初始化后,其值不能重新赋值。对于对象和数组,const 意味着对对象/数组的引用不能改变,但对象/数组的内容仍然可以修改。
  • var: 声明一个函数级作用域或全局作用域变量(旧语法)。它可以重新赋值和重新声明。

在 JavaScript 中创建(声明)变量:

let carName; // 声明一个名为 carName 的变量(初始值为 undefined)
carName = "Volvo"; // 将字符串 "Volvo" 赋值给 carName
const year = 2024; // 声明一个常量并初始化
// year = 2025; // 这将导致错误,因为 'year' 是一个常量

在使用变量之前声明它们,并在声明时初始化 const 变量,这是一个好的编程习惯。

作用域决定了变量的可访问性(可见性)。

  • 块级作用域(let 和 const): 使用 let 和 const 声明的变量只在其声明的代码块(由 {...} 定义)内部可访问。这包括循环、if 语句和函数块。
  • 函数级作用域(var): 使用 var 声明的变量在其声明的整个函数内部都可访问,无论块结构如何。
  • 全局作用域: 在任何函数或块外部声明的变量是全局变量,可在脚本的任何地方访问。

块级作用域示例:

function testScope() {
if (true) {
let blockScopedVar = "I am block-scoped";
const blockScopedConst = "Me too!";
var functionScopedVar = "I am function-scoped";
console.log(blockScopedVar); // 可访问
}
// console.log(blockScopedVar); // 错误:blockScopedVar 在此处未定义
// console.log(blockScopedConst); // 错误:blockScopedConst 在此处未定义
console.log(functionScopedVar); // 可访问
}
testScope();

使用 let 和 const 有助于防止与变量提升(hoisting)和意外的全局变量相关的 bug,这些问题在使用 var 时很常见。

所有 JavaScript 变量都必须由唯一的名称来标识,这些名称称为标识符(identifiers)。

构造变量名的规则:

  • 名称可以包含字母、数字、下划线 (_) 和美元符号 ($)。
  • 名称必须以字母、美元符号 ($) 或下划线 (_) 开头。(通常,以字母开头)。
  • 名称区分大小写(myVariable 和 myvariable 是不同的)。
  • 保留关键字(如 let、const、function、if)不能用作变量名。

使用描述性且有意义的名称(例如 userName、totalAmount)可以使你的代码更具可读性。驼峰命名法(CamelCase,userName)是标准的命名约定。

在 JavaScript 中,等号 (=) 是赋值运算符,而不是“等于”运算符(表示相等性判断,使用 == 或 ===)。

它将右侧的值赋给左侧的变量。

let x = 10; // 将 10 赋值给 x
x = x + 5; // 将 (x + 5) 的值重新赋值给 x。现在 x 是 15。

JavaScript 变量可以容纳不同类型的数据:

  • String(字符串): 文本数据,例如 "Hello"、'JavaScript'。(用引号或反引号括起来)。
  • Number(数字): 数值数据,例如 100、3.14、2.5e5(科学计数法)。JavaScript 只有一个 Number 类型,用于表示整数和浮点数。
  • Boolean(布尔值): 逻辑值,true 或 false。
  • Object(对象): 键值对的集合,例如 { name: "John", age: 30 }。数组(Arrays)和函数(Functions)也是对象类型。
  • Array(数组): 有序的值列表,例如 [1, 2, "apple"]。
  • null: 表示有意缺少的任何对象值。
  • undefined: 表示一个变量已经声明但尚未赋值。
  • Symbol (ES6): 一种独一无二且不可变的原始值,常用于对象属性键。
  • BigInt (ES2020): 用于表示任意长度的整数。

JavaScript 是一种动态类型语言,这意味着你无需声明变量的类型。类型是在运行时自动确定的。

let pi = 3.14; // pi 是一个数字 (Number)
let person = "John Doe"; // person 是一个字符串 (String)
let isHappy = true; // isHappy 是一个布尔值 (Boolean)

可以在一个语句中声明多个变量,用逗号分隔。然而,通常在单独的行上声明每个变量会更清晰。

// 常用方式:
let name = "John Doe";
let age = 30;
let city = "New York";
// 也可以这样(对于 `let` 和 `const` 不太常用,因为单独一行有助于利用块级作用域):
let user = "Jane", role = "Admin", experience = 5;

声明但未赋值的变量将具有值 undefined。

let country;
console.log(country); // 输出:undefined

let 和 const: 使用 let 或 const 声明的变量不能在同一作用域内重新声明。这样做会导致 SyntaxError(语法错误)。

let myVar = "initial";
// let myVar = "new"; // 错误:标识符 'myVar' 已经声明过
const myConst = 10;
// const myConst = 20; // 错误:标识符 'myConst' 已经声明过

var(旧语法): 使用 var 声明的变量可以在同一作用域内重新声明而不会出错。如果重新声明不赋值新值,则它实际上会被忽略;如果重新声明并赋值新值,变量将采用新值。

var oldVar = "Volvo";
var oldVar; // 不会出错,oldVar 仍然是 "Volvo"
console.log(oldVar); // 输出:"Volvo"
var oldVar = "Saab"; // 重新声明并赋值
console.log(oldVar); // 输出:"Saab"

var 的这种重新声明行为可能导致 bug,这也是首选 let 和 const 的原因之一。

JavaScript 算术运算和类型强制转换

Section titled “JavaScript 算术运算和类型强制转换”

可以使用 +、-、*、/ 等运算符对 JavaScript 变量进行算术运算。

const x = 5 + 2 + 3; // x 将为 10

当运算符与混合类型一起使用时,JavaScript 会执行类型强制转换(type coercion)。+ 运算符很特殊:它对数字执行加法,对字符串执行连接。

const strNum = "5" + 2 + 3; // 结果: "523" (字符串连接)
const numStr = 2 + 3 + "5"; // 结果: "55" (先加法后连接)
console.log("The year is " + 2024); // 结果: "The year is 2024"
如果你使用 + 运算符,并且其中一个操作数是字符串,JavaScript 会将其他操作数转换为字符串并执行连接。请注意这种行为。