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)块级作用域

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

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

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

ifforwhile{}都可以形成块级作用域。


三、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 自己内部找,找到

  • binner找不到,去outer 找,找到

  • ainner找不到,outer 找不到,去全局找,找到

这就是作用域链。


六、作用域链的本质

作用域链的本质是:

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

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

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


七、总结

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

重点记住:

  • 全局作用域
  • 函数作用域
  • 块级作用域
  • 变量查找是逐级向上找
  • 找不到最终会报错
相关推荐
im_AMBER2 小时前
AJAX vs Fetch API:Promise 与异步 JavaScript 怎么用?
前端·javascript·面试
用户9714171814272 小时前
JavaScript call、apply、bind 详解
javascript
用户9714171814272 小时前
JavaScript 深拷贝与浅拷贝详解
javascript
Highcharts.js2 小时前
Highcharts React v4 迁移指南(上):核心变更解析与升级收益
前端·javascript·react.js·react·数据可视化·highcharts·v4迁移
菌菌的快乐生活2 小时前
在 WPS 中设置 “第一章”“第二章” 这类一级编号标题自动跳转至新页面
前端·javascript·wps
hh随便起个名2 小时前
useRef和useState对比
前端·javascript·react
吴声子夜歌3 小时前
JavaScript——对象
开发语言·javascript·ecmascript
不会写DN3 小时前
Js常用的字符串处理
开发语言·前端·javascript
晓13133 小时前
第三章 TypeScript 高级类型
前端·javascript·typescript