javascript有三种作用域:全局作用域(最外层声明)、函数作用域(函数内var声明)、块级作用域({}内let/const声明);作用域链是引擎从当前作用域逐级向上查找变量的静态路径。

变量作用域决定了一个变量在代码中哪些地方能被访问,而作用域链是引擎查找变量时实际走的路径。理解它们的关键不是背定义,而是看清“在哪定义”和“往哪找”这两件事。
作用域类型:看变量在哪声明
JavaScript 有三种主要作用域,区别在于声明位置和关键字:
-
全局作用域:脚本最外层(不在任何函数或块内)用
var、let或const声明的变量。浏览器里会挂到window上,整个脚本都可读,但容易命名冲突。 -
函数作用域:在
function内部声明的变量(包括参数),只在该函数及内部嵌套函数中有效。var声明的变量会被提升,但不会跨函数访问。 -
块级作用域:由
{}包裹的结构(如if、for、独立代码块)中,用let或const声明的变量。它比函数作用域更细粒度,var在块内声明仍属于外层函数或全局作用域。
词法作用域:作用域在写代码时就定死了
JS 不看函数怎么被调用,只看它在源码里写在哪。比如:
function outer() {const x = 'outer';
return function inner() { console.log(x); };
}
const fn = outer();
fn(); // 输出 'outer'
虽然 inner 是在全局调用的,但它定义在 outer 里面,所以天然能访问 outer 的变量——这就是词法作用域。它让闭包成为可能。
作用域链:变量查找的真实路线图
每次函数执行时,JS 引擎会为它生成一条“查找路径”,从内到外依次是:
- 当前函数自己的作用域(含参数、
let/const/var声明) - 外层函数的作用域(如果有的话)
- 再外层……直到全局作用域
查找过程是单向向上、逐级进行的。一旦找到就停止;找不到就报 ReferenceError。例如:
function f1() {
const a = 'f1';
function f2() {
const a = 'f2';
console.log(a); // 'f2' —— 当前作用域就有,不往上找
}
f2();
}
这里 f2 打印的是自己作用域的 a,哪怕删掉 f2 里的声明,它也会继续向上找到 f1 的 a,而不是跳过直接去全局。
常见误区提醒
-
var没有块级作用域,if{ let x=1 }中的x外面访问不到,但if{ var x=1 }的x依然能从外面访问(在函数内的话)。 - 作用域链和
this无关。this是运行时动态绑定的,而作用域链是定义时静态确定的。 - 闭包不是特殊语法,只是函数“记住了”自己定义时所处的作用域链。只要内部函数被返回或传出去,这条链就一直存在。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











