JavaScript 作用域与作用域链详解

前言

在 JavaScript 中,作用域是非常基础但又非常重要的知识点。

闭包、变量查找、函数执行、模块化等内容,都和作用域密切相关。

本文主要讲清楚:

  • 什么是作用域
  • JavaScript 有哪些作用域
  • 什么是作用域链
  • 变量查找规则是什么

一、什么是作用域?

作用域可以理解为:

变量和函数可以被访问的范围。

也就是说,一个变量不是在任何地方都能访问,它的可访问范围由作用域决定。

例如:

ini 复制代码
let a = 10;

function test() {
  let b = 20;
  console.log(a); // 可以访问
}

test();
// console.log(b); // 报错

这里:

  • a 在全局作用域中

  • b 在函数作用域中

  • 函数内部可以访问全局变量

  • 全局不能访问函数内部变量


二、JavaScript 中的几种作用域

1)全局作用域

定义在函数外部的变量,通常属于全局作用域。

ini 复制代码
let name = 'Tom';

function say() {
  console.log(name);
}

全局作用域中的变量,在当前脚本中通常都可以访问。


2)函数作用域

在函数内部声明的变量,只能在函数内部访问。

ini 复制代码
function test() {
  let age = 18;
  console.log(age);
}

test();
// console.log(age); // 报错

3)块级作用域

使用let和const声明的变量,会形成块级作用域。

ini 复制代码
{
  let a = 1;
  const b = 2;
}

// console.log(a); // 报错
// console.log(b); // 报错

if、for、while、{}都可以形成块级作用域。


三、var、let、const 的作用域区别

var

  • 没有块级作用域
  • 只有全局作用域和函数作用域
ini 复制代码
if (true) {
  var a = 10;
}

console.log(a); // 10

let / const

  • 有块级作用域
ini 复制代码
if (true) {
  let b = 20;
}

// console.log(b); // 报错

四、什么是作用域链?

当在当前作用域中查找某个变量时,如果找不到,就会去上一级作用域查找,直到全局作用域。

这个逐级向上查找的过程,就叫做 作用域链。


五、作用域链示例

ini 复制代码
let a = 1;

function outer() {
  let b = 2;

  function inner() {
    let c = 3;
    console.log("结果",a, b, c);
  }

  inner();
}

outer();

输出:

复制代码
结果,1 2 3

查找过程:

  • 找 c:先在inner 自己内部找,找到

  • 找 b : inner找不到,去outer 找,找到

  • 找 a :inner找不到,outer 找不到,去全局找,找到

这就是作用域链。


六、作用域链的本质

作用域链的本质是:

函数在定义时,就已经确定了它能访问哪些外部变量。

注意,是定义时,不是调用时。

这也是闭包能成立的基础。


七、总结

作用域决定了变量的可访问范围,作用域链决定了变量的查找路径。

重点记住:

  • 全局作用域
  • 函数作用域
  • 块级作用域
  • 变量查找是逐级向上找
  • 找不到最终会报错
相关推荐
King禅6 分钟前
JavaScript 调试实战指南:从 console.log 到 DevTools 深度运用
javascript
全栈项目管理程序猿11 分钟前
ArcGIS JS 基础教程(28):图层渲染顺序管理
前端·javascript
扶风ff32 分钟前
练题簿在线免费刷题:创建个人任务,把刷题、听题和模考目标放到每天的学习中
开发语言·javascript·学习·小程序
asong43 分钟前
没有源代码,AI 也能拆解软件:这个开源项目已有 3.7 万 Star
javascript·后端·github
用户17335980753744 分钟前
纯前端 PDF 压平避坑指南:压平后表单字段变了?
前端·javascript·vue.js
用户298698530141 小时前
React 中实现 Word 与 Markdown 双向转换的实践记录
javascript·react.js·markdown
OpsEye2 小时前
大模型会话里的手机号、身份证,怎么自动脱敏?
javascript·ai编程
爱喝水的小周2 小时前
实验十 Vue‑Router 王者荣耀战绩查询 APP 开发实践
前端·javascript·vue.js
yexianglunbai2 小时前
Vue 3 全面详解:从核心特性到工程化实践
前端·javascript·vue.js
孟陬2 小时前
JavaScript 反引号(` backtick)和双引号的不完全等价 ≠ 场景
javascript·node.js·bun