JS作用域按“出生地”划分:全局作用域指在script最外层声明或函数内漏var直接赋值的变量;函数作用域指在函数体内声明的变量;块级作用域(ES6)指用let/const在{}内声明的变量。

JS 中作用域的划分主要看变量或函数是在哪里声明的,不是看它在哪被用,而是看它“出生地”在哪。
全局作用域的判定标准
满足以下任一条件,就属于全局作用域:
- 直接写在 <script></script> 标签最外层(不在任何函数或块内)的 var、function 声明;
- ES6 之前,在函数内部漏掉 var/let/const 直接赋值的变量(如
a = 10),会自动挂到 window 上,成为全局属性; - 顶层 let/const/class 在传统 <script></script> 中也属于全局作用域(但不会成为 window 属性);
- 模块(import/export)环境下,顶层声明不属于全局作用域,而是模块作用域——这点容易被忽略。
局部作用域(函数作用域)怎么识别
只要在函数体内声明的变量,默认就进入该函数的局部作用域:
- function 声明、var 声明的变量,整个函数体都可访问(包括嵌套的 if/for 内部);
- 函数参数也属于这个局部作用域;
- 每次调用函数,都会新建一个独立的局部作用域,互不影响;
- 函数内部可以读取外部(包括全局)的变量,但外部无法读取函数内的变量。
注意:块级作用域不是“局部作用域”的同义词
ES6 引入了 let/const,它们在 {} 块内形成块级作用域,但这和传统说的“局部作用域”(即函数作用域)不同:
-
if (true) { let x = 1; }→ x 只在大括号内有效,函数外、甚至同一函数的其他块里都不可见; -
if (true) { var y = 1; }→ y 仍属于外层函数或全局作用域,不是块级隔离; - 所以不能把 if 或 for 的大括号默认当成“局部作用域”,得看用的是 var 还是 let/const。
快速自查口诀
看到一个变量,三步判断它的作用域:
- 它是不是在某个 function 大括号里声明的?→ 是,大概率是函数局部作用域;
- 它是不是在 if/for/{} 里,且用 let/const 声明?→ 是,属于块级作用域;
- 它既不在函数里,也不在任何块里(或用了 var 且在最外层)?→ 就是全局作用域。











