javascript中的作用域链

在 JavaScript 中,作用域链 是一种用于解析变量的机制,它决定了在不同的上下文(或作用域)中如何查找和访问变量。作用域链与 JavaScript 的函数作用域、块级作用域紧密相关,是理解变量可见性和访问权限的关键。

1. 作用域链的基本概念

作用域
  • 作用域(Scope) 指的是代码中变量、函数和对象的可访问范围。
  • JavaScript 主要有三种作用域:
    • 全局作用域:在全局上下文中声明的变量或函数,可以在任何地方访问。
    • 函数作用域:在函数内声明的变量和函数,只能在该函数内访问。
    • 块级作用域:用 letconst 声明的变量具有块级作用域,只在 {} 代码块内有效。
作用域链的定义
  • 作用域链(Scope Chain) 是指当 JavaScript 引擎在函数中查找变量时,如果在当前作用域找不到,它会沿着作用域链向上一级作用域查找,直到找到这个变量或者到达全局作用域为止。
  • 作用域链的查找顺序是从内到外的,即由当前作用域逐层向上查找,直到全局作用域。如果在作用域链中找不到对应的变量,最终会返回 undefined 或抛出错误(如果是严格模式)。

2. 作用域链的形成

  • 当函数被创建时,其作用域链就会确定。作用域链的形成是因为函数在定义时记录了所在上下文的作用域。
  • 每个函数都会有自己的作用域,但函数可以访问父级作用域中的变量,这就是作用域链的关键。

3. 作用域链的查找机制

当 JavaScript 引擎需要查找一个变量时,它会遵循以下步骤:

  1. 当前作用域:首先,JavaScript 会从当前作用域查找变量。
  2. 父级作用域:如果当前作用域没有找到变量,它会沿着作用域链向父级作用域查找。
  3. 全局作用域:如果在所有父级作用域中都找不到变量,它会最终在全局作用域中查找。
  4. 未找到:如果在作用域链中都未找到该变量,则根据是否启用严格模式,返回 undefined 或抛出 ReferenceError

4. 作用域链的案例

4.1 简单函数作用域链
let globalVar = 'I am global';function outerFunction() {let outerVar = 'I am in outerFunction';function innerFunction() {let innerVar = 'I am in innerFunction';// 依次查找变量,作用域链的顺序是:innerFunction -> outerFunction -> global scopeconsole.log(innerVar);  // I am in innerFunctionconsole.log(outerVar);  // I am in outerFunctionconsole.log(globalVar); // I am global}innerFunction();
}outerFunction();

解释

  • innerFunction 执行时,它的作用域链是从 innerFunction 本身开始的。
  • 如果 innerVarinnerFunction 内找到,则使用该变量。
  • 如果 outerVar 不在 innerFunction 内定义,JavaScript 会向上查找 outerFunction 的作用域,直到找到。
  • 如果没有找到 outerVar,再继续查找全局作用域中的变量 globalVar
4.2 函数嵌套与作用域链
let a = 10;function first() {let b = 20;function second() {let c = 30;console.log(a); // 查找顺序:second -> first -> global,输出 10console.log(b); // 查找顺序:second -> first,输出 20console.log(c); // 查找顺序:second,输出 30}second();
}first();

解释

  • second 函数内部定义了变量 c,但当它访问 ab 时,需要沿着作用域链向上查找。
  • second 函数的作用域链包含了它自己的作用域和 first 函数的作用域,以及全局作用域。
4.3 块级作用域与作用域链
let globalVar = 'global';function checkScope() {let functionScopeVar = 'function scope';if (true) {let blockScopeVar = 'block scope';console.log(blockScopeVar); // block scopeconsole.log(functionScopeVar); // function scopeconsole.log(globalVar); // global}// 块级作用域外访问 blockScopeVar 会报错// console.log(blockScopeVar); // ReferenceError: blockScopeVar is not defined
}checkScope();

解释

  • blockScopeVar 是通过 let 定义的块级作用域变量,因此只能在 if 块内访问。
  • blockScopeVar 被查找时,它首先会在块内找到。
  • functionScopeVar 在整个 checkScope 函数内都是可访问的,因为它是在函数作用域中定义的。
  • globalVar 是全局变量,因此可以在任何地方访问。

5. 作用域链的特点

  1. 词法作用域(静态作用域)

    • JavaScript 使用词法作用域,即函数的作用域在函数定义时就已经决定,而不是在函数调用时。
    • 因此,作用域链是基于函数的定义位置,而不是调用位置。
  2. 作用域链的层次结构

    • 每个函数调用时,都会有一个自己的作用域。
    • 如果作用域中没有找到某个变量,就会通过作用域链逐级向上查找,直到找到变量或到达全局作用域。
  3. 嵌套作用域

    • 函数可以在其内部定义其他函数,形成嵌套作用域。内层函数可以访问外层函数的变量,但外层函数不能访问内层函数的变量。
  4. 闭包与作用域链

    • 闭包是依赖于作用域链的。闭包是指一个函数能够记住并访问它的词法作用域,即使这个函数在词法作用域之外被调用。

    闭包案例

    function outer() {let outerVar = 'I am outer';return function inner() {console.log(outerVar); // 闭包机制:inner 函数访问 outer 的变量};
    }const innerFunc = outer();
    innerFunc(); // 输出: I am outer
    

    解释inner 函数可以记住并访问 outer 函数的 outerVar,即使 outer 函数已经执行结束。这是因为 inner 函数在定义时创建了一个闭包,保留了对其词法作用域的引用。

6. 作用域链的使用场景

  • 变量的可见性控制:通过不同的作用域,开发者可以限制某些变量的可见性,从而避免全局变量污染,保证代码的模块化。

  • 闭包应用:利用作用域链可以实现闭包,闭包在很多场景中(如回调函数、事件处理、数据封装等)都有广泛应用。

  • 模块化开发:在模块化开发中,通过作用域链可以实现变量的封装和私有化,避免全局变量的冲突。

7. 总结

  • 作用域链 是一种变量解析机制,决定了 JavaScript 如何在多层嵌套的函数和块中查找变量。
  • 作用域链的查找顺序是由内到外的,最终会查找到全局作用域。
  • 通过作用域链,可以在内层函数中访问外层函数的变量,而闭包是作用域链的一个重要应用场景。
  • 使用作用域链,可以更好地控制变量的可见性和生命周期,从而编写出更模块化、更健壮的代码。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[已更新前两问代码+全部建模]2024华为杯C题详细思路代码文章建模分享研究生数学建模竞赛数学建模研赛

截止9.21 12点 已更新问题一二的代码和全部内容的建模 下面我们会先进行代码讲解,之后给出全部内容的建模公式 ## https://docs.qq.com/doc/DVWhyZ1NFY01XcmNw基于磁通密度数据的特征提取与分类分析。 问题一代码详解 1. 导入必要的库 import pandas as pd import numpy as…

Elastic 的 OpenTelemetry PHP 发行版简介

作者:Pawel Filipczak 宣布 OpenTelemetry PHP 的 Elastic 发行版的第一个 alpha 版本。在本篇博文中了解使用 OpenTelemetry 来检测 PHP 应用程序是多么简单。 我们很高兴推出 OpenTelemetry PHP 的 Elastic Distribution 的第一个 alpha 版本。在这篇文章中&…

十九、石英晶体振荡电路

石英晶体振荡电路 1、石英晶体的特点、等效电路、特性曲线; 2、石英晶体振动器的特点, 3、石英晶体振动器的振荡频率

【爱给网-注册安全分析报告-无验证方式导致安全隐患】

前言 由于网站注册入口容易被黑客攻击,存在如下安全问题: 1. 暴力破解密码,造成用户信息泄露 2. 短信盗刷的安全问题,影响业务及导致用户投诉 3. 带来经济损失,尤其是后付费客户,风险巨大,造…

滑动窗口算法专题(1)

找往期文章包括但不限于本期文章中不懂的知识点: 个人主页:我要学编程(ಥ_ಥ)-CSDN博客 所属专栏: 优选算法专题 目录 滑动窗口算法的简介 209. 长度最小的子数组 3.无重复字符的最长子串 1004. 最大连续1的个数III 1658. 将减到0的最小…

Java调用数据库 笔记06 (修改篇)

1.创建Java的普通class类 2.加载驱动 Class.forName("com.mysql.jdbc.Driver"); 3.驱动管理类调用方法进行连接,得到连接对象 DriverManager.getConnection(url, user, password); 其中设置参数: static final String url "jdbc:my…

python中ocr图片文字识别样例(二)

一、说明 本次解决图片相关出现中文乱码问题,属于上篇文章的优化,前提条件依赖上篇文章的包,当然ocr的具体应用场景很多,根据自身需求进行调整 二、具体实现 2.1 代码实现: # -*- coding: utf-8 -*- import easyoc…

电气设备施工现场风险状态判断ai模型训练数据集

电气设备施工现场风险状态判断ai模型训练数据集 id:18 电气设备施工现场工人人工智能学习数据和工作环境安全数据,建立系统化管理体系,改变全球EHS范式,预防工业事故。数据集记录了387709例子电力设施建设以及施工现场相关的灾害安全环境数据…

电力行业螺钉螺帽螺丝缺失检测数据集 voc yol

电力行业螺钉螺帽螺丝缺失检测数据集 数据集描述 该数据集旨在用于电力行业中的螺钉、螺帽、螺丝等紧固件的缺失检测任务。数据集包含了大量的图像及其对应的标注信息,可用于训练计算机视觉模型,以识别和定位电力设施中的螺钉、螺帽、螺丝等部件是否存在…

【零成本】七日杀 服务器搭建 异地联机 无需公网IP、服务器

主要内容 什么是七日杀 搭建前需要准备什么 详细步骤 1.Steam中下载七日杀服务器工具 2.修改七日杀服务配置文件 3.启动七日杀服务器应用 4.运行 MoleSDN 进行异地联机 5.小伙伴打开游戏加入 鼠鼠的服务器 什么是七日杀 《七日杀》是一款沙盒生存恐怖游戏,…

【2025】儿童疫苗接种预约小程序(源码+文档+解答)

博主介绍: ✌我是阿龙,一名专注于Java技术领域的程序员,全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师,我在计算机毕业设计开发方面积累了丰富的经验。同时,我也是掘金、华为云、阿里云、InfoQ等平台…

LeetCode[中等] 54.螺旋矩阵

给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。 思路:定义方向数组,按照顺时针顺序:右(0,1),下(1,0),左(0,-1),上(0,-1) 从矩阵的左上角开始遍历…

5. 数字证书与公钥基础设施

5. 数字证书与公钥基础设施 (1) PKI 的定义、组成及应用 PKI(Public Key Infrastructure,公钥基础设施) 是一个使用公钥技术来提供安全服务的框架。它定义了如何管理和维护公钥,以及如何通过证书来验证公钥的真实性。PKI的核心组成部分包括: 证书颁发机构(CA, Certifica…

Maven 安装

Maven 安装 Maven 下载安装 下载MAVEN 选择版本注意: IDEA 2022 兼容maven 3.8.1及之前的所用版本 IDEA 2021 兼容maven 3.8.1及之前的所用版本 IDEA 2020 兼容Maven 3.6.3及之前所有版本 IDEA 2018 兼容Maven3.6.1及之前所有版本 打开MAVEN官网 下载需要的版本 Wi…

软件设计师——操作系统

📔个人主页📚:秋邱-CSDN博客☀️专属专栏✨:软考——软件设计师🏅往期回顾🏆:C: 类和对象(上)🌟其他专栏🌟:C语言_秋邱 一、操作系统…

Qt_窗口界面QMainWindow的介绍

目录 1、菜单栏QMenuBar 1.1 使用QMainWindow的准备工作 1.2 在ui文件中设计窗口 1.3 在代码中设计窗口 1.4 实现点击菜单项的反馈 1.5 菜单中设置快捷键 1.6 菜单中添加子菜单 1.7 菜单项中添加分割线和图标 1.8 关于菜单栏创建方式的讨论 2、工具栏QToolBar …

谷歌-BERT-“bert-base-chinese ”

1 需求 需求:自动下载模型和分词器 需求:手动导入模型和分词器 需求:pipeline使用预训练模型 需求:训练和评估 需求:测试 关键词:训练数据集、评估数据集、测试数据集 需求:上线 2 接口 3 自…

[UTCTF2020]sstv

用goldwave和010editor打开均未发现线索, 网上搜索sstv,豆包回答如下: 慢扫描电视(Slow Scan Television,简称 SSTV)是一种通过无线电传输和接收静态图像的技术。 一、工作原理 SSTV 通过将图像逐行扫描并…

鸿蒙OpenHarmony【轻量系统内核通信机制(互斥锁)】子系统开发

互斥锁 基本概念 互斥锁又称互斥型信号量,是一种特殊的二值性信号量,用于实现对共享资源的独占式处理。 任意时刻互斥锁的状态只有两种,开锁或闭锁。当任务持有互斥锁时,该互斥锁处于闭锁状态,这个任务获得该互斥锁…

利用Metasploit进行信息收集与扫描

Metasploit之信息收集和扫描 在本文中,我们将学习以下内容 使用Metasploit被动收集信息 使用Metasploit主动收集信息 使用Nmap进行端口扫描 使用db_nmap方式进行端口扫描 使用ARP进行主机发现 UDP服务探测 SMB扫描和枚举 SSH版本扫描 FTP扫描 SMTP枚举 …