对作用域链的理解

news2024/12/23 17:26:12

 

一、作用域

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

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

举个例子

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遵循词法作用域,相同层级的 foo 和 bar 就没有办法访问到彼此块作用域中的变量,所以输出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时找不到,向上一层作用域找,即全局作用域,还是找不到则报错

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

厉害的人都在用的思维导图-思维导图的七大图示

思维导图是一种非常实用的工具,它可以帮助我们更好地组织和表达自己的思想。 在这篇文章中,我将会介绍用ProcessOn完成思维导图的7大图示,并解释它们各自的作用和应用场景。 思维导图是一种非常实用的工具,它可以帮助我们更好地组…

H264码流插入和读取自定义数据(SEI字段)

目录 1. 前言2. H264码流结构2.1 文字说明2.2 码流格式图解 3. 自定义数据封装以及H264码流插入3.1 将自定义数据封装成SEI字段通用格式即可插入H264码流中3.2 编码逻辑 4. 代码5. 总结 1. 前言 本文主要记录,如何在已有的H264码流中插入自定义的数据,并…

商家说:我的对讲机能通话10公里、50公里,你敢信吗?

有不少渠道经销商,在日常经营中往往会遇到用户的经典四问: 您家的对讲机通话距离远吗?待机时间长吗?功能多吗?经得住摔吗? 对讲机用户常问的问题 对于后三问,通常还有电池电量、技术规格、功能…

查找ABAP代码

SE38执行:RS_ABAP_SOURCE_SCAN/RPR_ABAP_SOURCE_SCAN 批量查找字符串使用位置

互联网工程师 Java 面试题及答案整理(2023 速成版,7 天就能吃透)

现在 Java 面试都只是背答案吗? 不背就通过不了面试,但是现在面试都问原理、问场景!Java 面试题就像我们高考时的文言文,包括古诗词,不背是不可能答出来的!当然了,除了背,还得理解&…

全网最牛,性能测试超全流程总结整理,你都遗漏了什么...

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 1、性能需求分析 …

Jenkins自动化构建

自动化构建 Jenkins 是一款开源 CI&CD 软件,用于自动化各种任务,包括构建、测试和部署软件 Jenkins 支持各种运行方式,可通过系统包、Docker 或者通过一个独立的 Java 程序 安装依赖 安装参考:Windows环境下安装Jenkins **…

解锁市场潜力:海外网红营销效果最大化的7个关键步骤

在当今数字化时代,海外网红营销已经成为许多企业推广产品和品牌的重要手段。通过与海外网红合作,品牌可以有效地扩大影响力和受众群体,并提升产品或服务的认知度。然而,要实现海外网红营销效果最大化,并不是一件轻而易…

一元函数微分学中导数--定义--意义--基本公式--运算法则

目录 导数的定义 左导数和右导数 导数的几何意义和物理意义 几何意义 导数的几何意义--切线的斜率 物理意义 导数的物理意义——瞬时速度 基本初等函数导数公式 基本初等函数 常用基本初等函数导数公式 导数求解的四则运算法则 函数的求导法则 复合函数求导法则 导…

Linux驱动入门(五)——构建第一个驱动程序

文章目录 前言开发环境配置之内核升级为什么升级内核内核升级 Hello world 驱动程序驱动模块的组成Hello World模块编译Hello World模块模块的操作Hello World模块加载后文件系统的变化 模块参数和模块之间通信模块参数模块的文件格式ELF模块之间的通信模块之间的通信实例 将模…

RHEL 9 新特性及技术演示

OpenSSH:新增禁止 root 的密码登录 Cockpit:RHEL 的 Web 控制台 DNF-3:软件安装方法 NetworkManager:网络管理的主要组件 Nftables:默认的用户空间防火墙 WireGuard:快速、安全的 VPN 隧道&#xff08…

阿里架构师珍藏版“亿级高并发系统设计手册(2023 版)”

高并发 俗话说:罗马不是一天建成的,系统的设计当然也是如此。 从原来谁都不看好的淘宝到现在的电商巨头,展现的不仅仅是一家互联网巨头的兴起,也是国内互联网行业迎来井喷式发展的历程,网络信号从 2G 发展到现在的 5…

【计算机图形学】期末复习Bezier曲线与曲面篇

【计算机图形学】期末复习Bezier曲线与曲面篇 文章目录 【计算机图形学】期末复习Bezier曲线与曲面篇一、Bezier曲线的定义二、一次Bezier曲线(直线)三、二次Bezier曲线(抛物线)四、三次Bezier曲线(自由曲线&#xff0…

高效地将 TailwindCSS 与 Nuxt 结合使用

在这篇文章中,我们将了解如何在 TailwindCSS 的官方 Nuxt 模块的帮助下有效地将 TailwindCSS 与 Nuxt 应用程序结合使用。我们还将了解如何将 SVG 图标与 TailwindCSS 一起使用,而不是直接使用图像或 SVG 图标,以及如何基于给定图像为 Tailwi…

总结5种常用加密算法

前言 在平时的工作中,可能也在很多地方用到了加密、解密,比如: 用户的密码不能明文存储,要存储加密后的密文 用户的银行卡号、身份证号之类的敏感数据,需要加密传输 还有一些重要接口,比如支付&#xff0…

Linux conda 环境迁移 服务器之间迁移

网上很多方法语焉不详,本文主要介绍在Linux系统之间进行单一环境迁移,从服务器A迁移到服务器B的两种方式: conda list方式进行Linux系统在线环境迁移拷贝envs方式进行Linux系统离线环境迁移 conda list方式 迁移完毕后需要手动安装缺失的py…

ProcessOn思维导图流程图 超厉害的入门指南

如果你刚刚认识ProcessOn,不知道从哪里开始,希望这篇内容可以帮助到你。ProcessOn 是什么? ProcessOn 是一款专业的在线思维导图流程图软件。 专业强大的作图工具,支持多人实时在线协作,可用于原型图、UML、BPMN、网络拓扑图等多种…

INDEMIND双目视觉惯性模组实时生成点云并保存点云图

双目惯性相机最开始是从VINS中了解到的,2018年VINS中推荐过Loitor视觉惯性相机,但是后来看到GitHub Issue中有人反映Loitor丢帧、无技术支持等问题,加之购入渠道非官方故未入手Loitor,浏览知乎时关注到Indemind的该款产品&#xf…

AI绘画:Roop插件的特性与安装!

交叉”学科”来了! 我们之前讲过可以实现单图换脸的Roop,也讲过可以通过文字描述画画的项目Stable-Diffusion-WebUI。现在这两者要通过sd-webui-roop产生交汇。 我们先来简单的看一下这个插件可以干什么! 功能特点 根据项目作者的说法&…

JavaScript二叉树及各种遍历算法详情

目录 什么是二叉树 满二叉树完全二叉树二叉树的存储 数组存储链表存储与二叉树相关的算法 深度优先遍历广度优先遍历先序遍历中序遍历后序遍历 前言: 上一篇文章中介绍了树的概念、深度优先遍历和广度优先遍历,这篇文章我们来学习一个特殊的树——二叉树。 什么是…