常量与作用域
常量和字面量是写数据的两种方式,作用域决定了变量在哪里能被访问。
常量
const 声明
const 声明的变量必须在定义时初始化,且不能重新赋值:
JavaScript
const PI = 3.14159;
const MAX_USERS = 100;
// const EMPTY; // SyntaxError: 必须初始化
// PI = 3.14; // TypeError: 不可重新赋值
引用类型常量
const 保证的是引用不变,对象内部属性可修改:
JavaScript
const user = { name: 'Tom', age: 25 };
user.age = 26; // 允许
user.email = 't@t.com'; // 允许
// user = {}; // TypeError
const arr = [1, 2, 3];
arr.push(4); // 允许
arr[0] = 10; // 允许
// arr = []; // TypeError
需要完全冻结对象时使用
Object.freeze()。
常量命名约定
JavaScript
// 全局常量:全大写下划线
const API_BASE_URL = 'https://api.example.com';
const DEFAULT_TIMEOUT = 5000;
// 局部常量:驼峰式
function calculate(radius) {
const pi = 3.14;
const area = pi * radius * radius;
return area;
}
字面量
字面量是直接写在代码中的数据值表示。
| 类型 | 字面量示例 | 说明 |
|---|---|---|
| 数字 | 42, 3.14, 0xFF | 十进制/十六进制 |
| 字符串 | 'hello', "hi", `temp` | 单/双引号/模板 |
| 布尔 | true, false | |
| 数组 | [1, 2, 3] | |
| 对象 | { name: 'Tom' } | |
| null | null | 空值 |
| 正则 | /pattern/ |
JavaScript
// 数字字面量
let decimal = 255;
let hex = 0xFF; // 255
let binary = 0b11111111; // 255
// 字符串字面量
let single = 'hello';
let double = "world";
let template = `1 + 2 = ${1 + 2}`;
// 对象字面量
let user = {
name: 'Tom',
age: 25,
greet() { console.log('Hi'); }
};
作用域
全局作用域
在任何函数或块外声明的变量属于全局作用域:
JavaScript
var globalVar = 'global';
let globalLet = 'also global';
function fn() {
console.log(globalVar); // 可访问
}
函数作用域
var 声明的变量只在函数内有效:
JavaScript
function test() {
var local = 'inside';
console.log(local); // 'inside'
}
// console.log(local); // ReferenceError
if (true) {
var x = 10;
}
console.log(x); // 10(var 不受块限制)
块级作用域
let 和 const 只在 {} 内有效:
JavaScript
if (true) {
let y = 20;
const z = 30;
console.log(y, z); // 20 30
}
// console.log(y); // ReferenceError
// console.log(z); // ReferenceError
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 0); // 0 1 2
}
变量提升
var 的提升
JavaScript
console.log(a); // undefined(不是报错)
var a = 10;
// 等价于:
var a;
console.log(a);
a = 10;
let/const 的 TDZ
JavaScript
// console.log(b); // ReferenceError: TDZ
let b = 20;
// 即使外部有同名变量,块内 TDZ 也优先
let c = 'outer';
{
// console.log(c); // ReferenceError: TDZ
let c = 'inner';
}
函数声明提升
JavaScript
greet(); // 'Hello'(函数声明整体提升)
function greet() {
console.log('Hello');
}
// 函数表达式不提升
// sayHi(); // TypeError
var sayHi = function() {
console.log('Hi');
};
要点总结
const保证引用不变,对象内部属性仍可修改- 字面量是数据的直接写法,对象/数组字面量最常用
var是函数作用域,let/const是块级作用域var存在提升初始化为undefined,let/const有 TDZ- 优先用块级作用域,避免变量污染和意外覆盖