文章目录
- 一、JavaScript 作用域链
- 1、作用域
- 2、作用域链
- 3、作用域链变量查找机制
- 二、代码示例 - 作用域链
一、JavaScript 作用域链
1、作用域
在 JavaScript 中 , 任何代码都有 作用域 ,
- 全局作用域 : 在
<script>
标签中 或者 js 脚本中 定义的变量 属于 全局作用域 ; - 局部作用域 : 在 函数中 定义的 变量 属于 局部作用域 ;
- 块作用域 :
- ES6 中 在
{}
代码块 中 使用 let / const 定义的 常量 / 变量 属于 块作用域 ; - ES6 之前使用 var 关键字在
{}
代码块 中定义的变量 , 取决于 代码块位置 , 代码块在全局作用域 则 该变量属于全局作用域 , 代码块在 局部作用域 则该变量属于 局部作用域 ;
- ES6 中 在
2、作用域链
如果在 函数 的 局部作用域 中 , 又定义了一个 函数 , 则诞生了一个新的 局部作用域 ;
作用域链 概念 : 在 内部函数 访问 外部函数的变量 或 全局变量 , 此时 需要 使用 链式查找 的方法 , 确定取哪个值 , 这种作用域结构 称为 " 作用域链 " ;
- 内部函数 , 外部函数 , 全局变量 中 , 定义的变量名称 可能是相同的 , 给定一个变量名 , 需要从作用域链中具体查找
作用域链 是 JavaScript 的重要的概念 , 用于 查找 变量名 对应的 不同作用域的 变量 ;
当 JavaScript 代码 执行时 , 会创建变量对象的 作用域链 , 其用途是保证对执行环境有权访问的所有变量和函数的有序访问 ;
3、作用域链变量查找机制
在 JavaScript 代码中 的 嵌套作用域 中 , 查找 变量 或 函数 的 机制就是 作用域链 的 链式查找机制 ;
内部函数 在 访问 指定名称的 变量时 , 采取的是 链式查找方式 ;
- 如果 内部函数 的 局部作用域 有该变量 , 则采用该变量 ;
- 如果 内部函数 的 局部作用域 没有该变量 , 则向上一层 外部函数 局部作用域查找 ;
- 如果 外部函数 的 局部作用域 有该变量 , 则采用该变量 ;
- 如果 外部函数 的 局部作用域 没有该变量 , 则向上一层 全局作用域 查找 ;
- 如果 全局作用域 有该变量 , 则采用该变量 ;
- 如果 全局作用域 没有该变量 , 则报 " 变量未定义 " 错误 ;
二、代码示例 - 作用域链
在下面的代码中 :
首先 , 在 全局作用域 中定义 num 变量 , 该变量的 作用域 属于 全局作用域 ;
然后 , 定义外部函数 , 在 全局作用域 中 定义 out_fun 函数 , 在 该函数的 范围内 是 局部作用域 ;
最后 , 定义内部函数 , 在 out 函数中 , 定义了 in_fun 函数 , 在 局部作用域 中 又 诞生了一个新的 局部作用域 ;
在 全局作用域 , 内部函数 , 外部函数 , 都定义一个 num 变量 ,
- 在 in_fun 内部函数 中 , 可以访问 内部函数 / 外部函数 / 全局作用域 中的变量 ;
- 在 out_fun 外部函数 中 , 可以访问 外部函数 / 全局作用域 中的变量 ;
- 在 全局作用域 中 , 只能访问 全局作用域 中的变量 ;
完整代码示例 :
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><!-- 设置 meta 视口标签 --><meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no,maximum-scale=1.0,minimum-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>JavaScript</title><style></style><script>// 作用域链// 全局作用域 变量var num = 333;function out_fun() {// 外部函数 局部作用域 变量var num = 666;function in_fun() {// 内部函数 局部作用域 变量var num = 999;// 打印查找的 num 变量console.log("in_fun : num = " + num)}// 调用内部函数in_fun();// 打印查找的 num 变量console.log("out_fun : num = " + num)}// 打印查找的 num 变量console.log("global : num = " + num)// 调用外部函数out_fun()</script>
</head><body>
</body></html>
执行结果 :