JavaScript作用域详解:全局、函数与块级作用域及作用域链
本文深入解析JavaScript中的三种核心作用域:全局作用域、函数作用域以及ES6引入的块级作用域。详细阐述变量在不同作用域下的可见性与生命周期,解释var、let、const关键字对作用域的影响,并剖析作用域链的查找机制,帮助开发者避免变量污染并优化代码结构。
在深入探讨AO(Activation Object)和BO(Binding Object)之前,有必要先厘清作用域的基本概念。理解这一机制对于后续掌握this指向、变量提升等复杂特性至关重要。
作用域
作用域(Scope)是指变量、函数或对象定义后,其可被访问的有效范围。
console.log(a)
{
var a=1;
}
function test(){
var b=2;
}

从代码执行结果可以看出,外部无法直接访问变量b。这表明作用域具有数据保护机制,防止外部随意访问或修改内部数据。同时,作用域实现了变量隔离,确保不同作用域下的同名变量互不冲突。
在实际开发中,最常用的是全局作用域和函数作用域。随着ES6标准的引入,let和const关键字的出现,又新增了一种块级作用域。
全局作用域
全局作用域指的是所有代码区域均可访问该作用域下的变量、方法及对象。
var a="全局1";
function test(){
b="没有带var,隐式转变为全局变量";
window.c="直接将变量c作为window下也会变全局";
var d="非全局作用域";
}
#第一步 执行test()
test() #这样才会将方法内的变量进行定义以及赋值
#第二步
console.log(a)
console.log(b)
console.log(c)
console.log(d)

通常情况下,window对象的属性即为全局变量。例如,window.c 实际上是将变量c作为window对象的一个属性来处理。需要注意的是,在声明变量时务必使用var关键字,否则该变量可能会意外提升为全局变量,导致数据相互污染。
此外,test方法本身也属于全局作用域下的方法。
function test(){
var a= function(){
console.log("字面量的方法")
}
b=function(){
console.log("不带var字面量的方法")
}
function test1(){
console.log("普通声明方法")
}
}

上述代码展示了字面量声明的方法,类似于将函数赋值给一个变量,并将其作为变量对待。这一点在前面的预编译环节中已有演示。
函数作用域
与全局作用域相对,函数作用域并非对所有地方可用,而是限定在特定范围内。通常,在函数内部声明的变量仅在函数内部有效。
function test(){
var a="非全局作用域";
console.log(a)
}
这里引出一个问题:全局方法能否访问函数作用域内部的变量?反之,函数内部是否可以包含由子函数生成的函数作用域?这些内部变量之间又能否相互访问?
function test(){
var a="test方法作用域";
function test1(){
var b="test1方法作用域";
console.log("a的值=",a);
}
# 调用函数内部函数
test1();
console.log("b的值=",b);
}

从代码执行结果可以看出,作用域是分层的。内层作用域可以访问外层作用域的变量,但外部无法访问内部作用域的变量。
if,switch,for ,while
条件语句和逻辑循环(如if、switch、for、while)并非函数,也不会创建新的作用域。在这些代码块中定义的变量将保留在其存在的作用域中。
function test(a){
if(a>1){
var b=13;
}else{
var b=1;
}
console.log(b);
}

因此,在使用条件语句和逻辑循环时,应尽量避免在全局作用域下使用。因为代码块中的变量可能会影响其他数据。
块作用域
块作用域的出现通常依赖于let或const关键字之一,否则不会形成块级作用域。

function test(a){
const b="23";
if (a>2){
const c=3
console.log("第一个人if---c-----",c)
}
if (a>1){
console.log("第二个人if----b----",b)
console.log("第二个人if----c----",c)
}
}

从代码可以看出,如果使用了let和const关键字,变量的作用范围仅限于声明所在的花括号内。因此,第一个if中的c变量在第二个if内部无法获取。当然,这依然遵循内层作用域可以访问外层作用域变量的原则。
如需了解let和const的更多细节,请参考前一篇:地址
作用域链
这一看似神奇的概念,简单来说就是:在作用域内直接查找变量,若未找到则向上一层查找;若仍未找到,则继续向上直到全局作用域,查找结束。
var a=1
var b=3
function test(){
var a=2
console.log("a的值",a);
console.log("b的值",b);
}

补充说明,作用域链的查找逻辑与原型链类似,后续文章将继续探讨。
总结
本文到此结束,希望能对您有所帮助。也欢迎您关注本站以获取更多相关内容!
JS split切割后出现空字符串怎么过滤
2026-11-05 16:00:30
在 React 或 Vue 项目中封装使用 JS 节流防抖
2026-11-05 15:27:29
JavaScript中怎么将带小数的字符串转为整数?
2026-11-05 14:32:38
怎么用JavaScript策略模式重构电商促销计算逻辑?
2026-11-05 14:01:09
JS使用constructor判断数据类型可靠吗
2026-11-05 13:49:41
