在大多数语言都对变量访问进行限制,例如Java、C。JavaScript也有这样的设计。这样的规则称为作用域
。按照指定规则查找变量的路径称为作用域链
。
作用域
作用域本质是一套规则,它定义了在什么地方以及查找变量。可以比作盒子,盒子里面有什么东西(变量和函数),哪些人可以看到使用这东西(变量和函数的访问权限)。
作用域主要分为以下几种:
全局作用域:
脚本运行时顶级作用域,它始终在调用栈的栈底函数作用域:
在函数创建的作用域块级作用域:
通过let
、const
声明的变量,被限制在{}
之内可以访问。ES6引入特性模块作用域:
模块模式下运行代码的作用域。通过<script type="module">
或者.mjs
文件定义的脚本内部具有模块作用域
js
// 全局作用域
var globalValue = 'global value';
funciton executeFunction() {
// 函数作用域
var executeValue = 'execute value';
if (true) {
// 块级作用域
let blockValue = 'bloack value';
}
// 此处访问blockValue 报错
}
// 此处访问executeValue 报错
作用域链
作用域链是当前执行上下文和所有外层执行上下文以链表数据结果关联起来的一条链条。这是当前执行上下查找变量的核心。
js
var globalValue = "global value";
function executeFunction() {
var executeValue = "execute value";
function innerFunction() {
var innerValue = "inner value";
console.log(innerValue);
console.log(executeValue);
console.log(globalValue);
}
return innerFunction;
}
var execute = executeFunction();
execute();
在上述代码中的作用域链就像下面图的结构

作用域和作用域链与执行上下文之间关系
作用域定义了一套变量访问权限规则;执行上下文时按照这个规则下的具体实现。而作用域链是这套规则在代码运行时具体实现,列出了所有需要查找的变量对象。
特性 | 作用域 | 执行上下文 |
---|---|---|
定义 | 词法、静态、在编写代码已经决定 | 运行时、动态 |
确定时机 | 函数定义时确定 | 函数调用时创建 |
数量关系 | 这是一套规则 | 一个环境,包含了代码运行时所有需要的信息 |
比喻 | 房子的蓝图 | 正在使用房间 |
小结
本章主要讲解作用域和作用域链,以及作用域和作用域链与执行上下文的关系。下章将会讲讲this确定指向的时机,this在不同情况下到底指向谁? 下章见👋🏻👋🏻┏(^0^)┛。