JavaScript作用域指变量可访问的范围,分全局、函数、块级三种;作用域链是逐级向上查找变量的路径;闭包是内部函数记住并持续访问外部作用域变量的现象。

JavaScript中的作用域,简单说就是变量能被访问的范围。它决定了代码中某个变量在哪些地方可用、哪些地方不可用,是理解JS执行逻辑和避免常见错误(比如“undefined”或“ReferenceError”)的关键。
作用域的类型:全局、函数、块级
JS主要有三种作用域:
- 全局作用域:在任何函数或块外部声明的变量(如 var a = 1; 或 let b = 2;),在整个脚本中都可访问;
- 函数作用域:用 function 声明的函数内部,用 var 声明的变量只在该函数内有效(注意:var 有变量提升,但作用域仍是函数级);
- 块级作用域:用 let 和 const 在 { } 内声明的变量(如 if、for、switch 或任意花括号块),只在该块内有效。
作用域链:查找变量的路径
当访问一个变量时,JS引擎会从当前作用域开始查找,找不到就向上一级作用域找,直到全局作用域。这个逐级向上搜索的链条叫“作用域链”。
例如:
立即学习“Java免费学习笔记(深入)”;
let x = 'global';
function foo() {
let x = 'local';
function bar() {
console.log(x); // 输出 'local',不是 'global'
}
bar();
}
这里 bar 中的 x 先在自身作用域找(没声明),再到外层 foo 找到 let x = 'local',就不会继续往上找全局的 x。
闭包:作用域链的“持久化”表现
当一个函数返回另一个函数,并且内部函数引用了外部函数的变量,外部函数执行完后,那些变量仍保留在内存中——这就是闭包。本质是内部函数记住了它定义时所处的作用域环境。
典型例子:
function createCounter() {
let count = 0;
return function() {
count++;
return count;
};
}
const counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2
每次调用 counter() 都能访问并修改 createCounter 中的 count,说明那个局部作用域没有被销毁。
容易踩坑的地方
- var 没有块级作用域:在 if 或 for 中用 var 声明,变量会泄露到外层函数或全局;
- 函数声明提升但作用域不变:虽然 function foo(){} 会被提升到顶部,但它定义的作用域仍是它所在的位置;
- 箭头函数不创建自己的 this 和 arguments,但作用域规则和其他函数一致——它沿用外层函数的作用域链。










