作用域链的理解(超级详细)

文章目录

    • 一、作用域
      • 全局作用域
      • 函数作用域
      • 块级作用域
    • 二、词法作用域
    • 三、作用域链

一、作用域

作用域,即变量(变量作用域又称上下文)和函数生效(能被访问)的区域或集合

换句话说,作用域决定了代码区块中变量和其他资源的可见性

举个例子

function myFunction() {
    let inVariable = "函数内部变量";
}
myFunction();//要先执行这个函数,否则根本不知道里面是啥
console.log(inVariable); // Uncaught ReferenceError: inVariable is not defined

上述例子中,函数myFunction内部创建一个inVariable变量,当我们在全局访问这个变量的时候,系统会报错

这就说明我们在全局是无法获取到(闭包除外)函数内部的变量

我们一般将作用域分成:

  • 全局作用域

  • 函数作用域

  • 块级作用域

全局作用域

任何不在函数中或是大括号中声明的变量,都是在全局作用域下,全局作用域下声明的变量可以在程序的任意位置访问

// 全局变量
var greeting = 'Hello World!';
function greet() {
  console.log(greeting);
}
// 打印 'Hello World!'
greet();

函数作用域

函数作用域也叫局部作用域,如果一个变量是在函数内部声明的它就在一个函数作用域下面。这些变量只能在函数内部访问,不能在函数以外去访问

function greet() {
  var greeting = 'Hello World!';
  console.log(greeting);
}
// 打印 'Hello World!'
greet();
// 报错: Uncaught ReferenceError: greeting is not defined
console.log(greeting);

可见上述代码中在函数内部声明的变量或函数,在函数外部是无法访问的,这说明在函数内部定义的变量或者方法只是函数作用域

块级作用域

ES6引入了letconst关键字,和var关键字不同,在大括号中使用letconst声明的变量存在于块级作用域中。在大括号之外不能访问这些变量

{
  // 块级作用域中的变量
  let greeting = 'Hello World!';
  var lang = 'English';
  console.log(greeting); // Prints 'Hello World!'
}
// 变量 'English'
console.log(lang);
// 报错:Uncaught ReferenceError: greeting is not defined
console.log(greeting);

二、词法作用域

词法作用域,又叫静态作用域,变量被创建时就确定好了,而非执行阶段确定的。也就是说我们写好代码时它的作用域就确定了,JavaScript 遵循的就是词法作用域

var a = 2;
function foo(){
    console.log(a)
}
function bar(){
    var a = 3;
    foo();
}
bar()

上述代码改变成一张图

由于JavaScript遵循词法作用域,相同层级的 foobar 就没有办法访问到彼此块作用域中的变量,所以输出2

三、作用域链

当在Javascript中使用一个变量的时候,首先Javascript引擎会尝试在当前作用域下去寻找该变量,如果没找到,再到它的上层作用域寻找,以此类推直到找到该变量或是已经到了全局作用域

如果在全局作用域里仍然找不到该变量,它就会在全局范围内隐式声明该变量(非严格模式下)或是直接报错

这里拿《你不知道的Javascript(上)》中的一张图解释:

把作用域比喻成一个建筑,这份建筑代表程序中的嵌套作用域链,第一层代表当前的执行作用域,顶层代表全局作用域

变量的引用会顺着当前楼层进行查找,如果找不到,则会往上一层找,一旦到达顶层,查找的过程都会停止

下面代码演示下:

var sex = '男';
function person() {
    var name = '张三';
    function student() {
        var age = 18;
        console.log(name); // 张三
        console.log(sex); // 男 
    }
    student();
    console.log(age); // Uncaught ReferenceError: age is not defined
}
person();

上述代码主要主要做了以下工作:

  • student函数内部属于最内层作用域,找不到name,向上一层作用域person函数内部找,找到了输出“张三”
  • student内部输出sex时找不到,向上一层作用域person函数找,还找不到继续向上一层找,即全局作用域,找到了输出“男”
  • person函数内部输出age时找不到,向上一层作用域找,即全局作用域,还是找不到则报错

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/449815.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++初学

1>思维导图 2>试编程 提示并输入一个字符串&#xff0c;统计该字符中大写、小写字母个数、数字个数、空格个数以及其他字符个数要求使用C风格字符串完成 #include <iostream> #include<string.h> using namespace std;int main() {string str;cout <<…

C++14之std::index_sequence和std::make_index_sequence

相关文章系列 std::apply源码分析 C之std::tuple(一) : 使用精讲(全) 目录 1.std::integer_sequence 2.std::index_sequence 3.std::make_index_sequence 4.运用 4.1.打印序列的值 4.2.编译时求值 4.3.std::tuple访问值 5.总结 1.std::integer_sequence 运行时定义一个…

Linux:进程

进程 知识铺垫冯诺依曼体系结构操作系统&#xff08;OS&#xff09; 进程概念进程的查看ps 命令获取进程 pid文件内查看进程终止进程的方式kill命令快捷键 进程的创建 forkfork 返回值问题 进程状态运行状态 &#xff1a;R休眠状态&#xff1a;S &#xff08;可中断&#xff09…

【3GPP】【核心网】【5G】5G核心网组网方案(超详细)

5G NR RRC协议总体介绍 UE入网过程包括几个子过程&#xff1a; UE分为三种状态&#xff1a;空闲态&#xff0c;连接态和非活动态。 开机入网流程 小区搜索与选择 UE开机选网&#xff0c;小区搜索并完成下行同步。 系统消息广播 UE读取广播信息&#x…

VMD + CEEMDAN 二次分解,CNN-LSTM预测模型

目录 往期精彩内容&#xff1a; 前言 1 二次分解与数据集制作 1.1 导入数据 1.2 VMD分解 1.3 样本熵 1.4 CEEMDAN分解 1.5 数据集制作 2 基于Pytorch的 CNN-LSTM 预测模型 2.1 定义CNN-LSTM预测模型 2.2 设置参数&#xff0c;训练模型 3 模型评估与可视化 3.1 结果…

学习JavaEE的日子 Day26 手撕所有集合类底层源码

Day26 1.手撕ArrayList底层源码 思路&#xff1a; 1.研究继承关系 2.研究属性 3.理解创建集合的过程 – 构造方法的底层原理 4.研究添加元素的过程 public class Test01 { public static void main(String[] args) {//ArrayList<String> list new ArrayList<>();…

【Java从发入门到精通】Java StringBuffer 和 StringBuilder 类

Java StringBuffer 和 StringBuilder 类 当对字符串进行修改的时候&#xff0c;需要使用 StringBuffer 和 StringBuilder 类。 和 String 类不同的是&#xff0c;StringBuffer 和 StringBuilder 类的对象能够被多次的修改&#xff0c;并且不产生新的未使用对象。 在使用 Stri…

在线安装MySQL5.7

在线安装MySQL 安装MySQL5.7 yum -y install mysql57-community-release-el7-10.noarch.rpm 若无可用安装包&#xff0c;执行下面这句 wget http://dev.mysql.com/get/mysql57-community-release-el7-7.noarch.rpm 本地安装 yum localinstall -y mysql57-community-releas…

Head First Design Patterns - 命令模式

什么是命令模式 命令模式&#xff0c;把请求封装成对象&#xff0c;以便使用不同的请求、队列或者日志请求来参数化其他对象&#xff0c;并支持可撤回的操作。 为什么会有命令模式 假设要设置一个遥控器&#xff0c;遥控器需要控制多个设备&#xff0c;每个设备除了开关&#…

MS30517SA单通道、高速、低侧栅极驱动器

产品简述 MS30517SA 是单通道、高速、低侧栅极驱 动器器件&#xff0c;能够有效地驱动 MOSFET 和 IGBT 开 关 。 芯片的 设 计 能 够 大 大 减 少 击 穿 电 流 &#xff0c; MS30517SA 能够提供高峰值拉、灌电流脉冲&#xff0c; 同时提供了轨到轨驱动能力以及低传播…

C break 语句

C 语言中 break 语句有以下两种用法&#xff1a; 当 break 语句出现在一个循环内时&#xff0c;循环会立即终止&#xff0c;且程序流将继续执行紧接着循环的下一条语句。它可用于终止 switch 语句中的一个 case。 如果您使用的是嵌套循环&#xff08;即一个循环内嵌套另一个循…

自动驾驶---Motion Planning之构建SLT Driving Corridor

1 背景 在上篇博客《自动驾驶---Motion Planning之Speed Boundary》中,主要介绍了Apollo中Speed Boundary的一些内容,可以构造ST图得到边界信息,最后结合粗糙的速度曲线和路径曲线,即可使用优化的方法求解得到最终的轨迹信息(s,s,s,l,l,l)。 本篇博客笔者主要介绍近…

Matlab 字符串相关命令

参考 字符串命令汇总1

代码随想录算法训练营第四十一天|卡码网46. 携带研究材料(第六期模拟笔试)、416. 分割等和子集

卡码网46. 携带研究材料&#xff08;第六期模拟笔试&#xff09; 刷题https://kamacoder.com/problempage.php?pid1046 题解&#xff1a; 一维背包 文章讲解https://programmercarl.com/%E8%83%8C%E5%8C%85%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%8001%E8%83%8C%E5%8C%85-2.html…

js导出的excel文件无法打开/打开乱码,excel无法打开xxx.xlsx因为文件格式或文件扩展无效

excel无法打开xxx.xlsx因为文件格式或文件扩展无效 使用 a 标签导出这里就不细说了&#xff0c;直接说上述问题解决方案 在调用导出接口的时候加上两个参数 responseType: “blob” responseEncoding: “utf8” export function test(data) {return util({url: /test,method: …

制冷系统管道焊接气焊安全操作

气焊操作安全教育&#xff1a; 1、检查气焊用具完好牢固无损&#xff0c;不得贴粘有&#xff08;机油&#xff09;&#xff1b; 2、气瓶余压&#xff08;2KG&#xff09;停止使用&#xff1b;清除动火 10 米范围内易燃易爆物料&#xff1b; 3、库房内动火要 做好通风排气&…

数据结构——二叉树的遍历【前序、中序、后序】

&#x1f49e;&#x1f49e; 前言 hello hello~ &#xff0c;这里是大耳朵土土垚~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f4a5;个人主页&#x…

【精选】30+Redis面试题整理(2024)附答案

目录 前言Redis基础项目有用到redis吗&#xff1f;你们项目为什么用redis?redis为什么这么快&#xff1f;了解Redis的线程模型吗&#xff1f;Redis优缺点?redis如何实现持久化&#xff1f;RDB持久化过程&#xff1f;AOF持久化过程&#xff1f;AOF持久化会出现阻塞吗&#xff…

svn安装与汉化(svn1.14.5版本)带汉化包

安装 下载 TortoiseSVN 去官网下载 TortoiseSVN&#xff0c;找到页面底部 TortoiseSVN 下载&#xff0c;选择适用自己电脑位数的 TortoiseSVN 客户端下载&#xff1a; 或者 链接&#xff1a;https://pan.baidu.com/s/1YSw9LalULsQecOQgFrXGSQ?pwd4ds7 提取码&#xff1a;4ds…

套接字编程 --- 三

目录 1. 前置性知识 1.1. listen 系统调用 1.2. accept 系统调用 1.3. 如何通信 1.3.1. read 系统调用 && write系统调用 1.3.2. recv 系统调用 && send 系统调用 2. TCP --- demo 2.1. Tcp_Server.hpp (version 1) 2.2. Tcp_Server.hpp (version 2…