javascript 的执行上下文与作用域

news2024/11/23 20:52:59

目录

    • 1. 初步了解 上下文(context)
    • 2. 全局上下文(global context)
    • 3. 上下文栈 (context stack)
    • 4. 作用域链( scope chain)
    • 5. 作用域(scope)
    • 6. 作用域链增强

1. 初步了解 上下文(context)

   上下文(context) 全称 执行上下文 (execution context) 。

  变量和函数的上下文 决定了它们可以访问哪些数据,以及它们的行为。所以 上下文 也可以说是 变量和函数所处的环境

  每个上下文都有一个关联的变量对象,而这个上下文中定义的所有变量和函数都存在于这个对象上。虽然无法通过代码访问变量对象,但后台处理数据总是用到它。

2. 全局上下文(global context)

  全局上下文是最外层的上下文。浏览器中,全局上下文就是 window 对象,所有通过 var 定义的全局变量和函数都会成为window对象的属性和方法
  使用 let 和const 的顶级声明不会定义在全局上下文中,但在作用链解析上效果是一样的。上下文在其所有代码都执行完毕后会被销毁,包含定义在它上面的所有变量和函数,全局上下文在应用程序退出前才会被销毁,比如关闭网页或退出浏览器。

3. 上下文栈 (context stack)

  每个函数调用都有自己的上下文,当代码执行到某个函数时,函数的上下文被推到(push)一个 上下文的栈结构 中,忘了栈结构的,可以查看 栈的基本操作。在函数执行完之后,上下文栈会弹出(pop)该函数的上下文,将控制权返还给之前的执行上下文。ECMAScript程序的执行流就是通过这个上下文栈进行控制的。

4. 作用域链( scope chain)

   学习作用域,先了解一下做应用于链。这个链,其实就是上面说的上下文栈结构。
  上下文中的代码在执行的时候,会创建变量对象的一个作用域链。这个作用域链决定了各级上下文中的代码在访问变量和函数时的顺序。代码正在执行的上下文的变量对象始终处于作用域链的最前端。如果上下文是函数,则其活动对象(activation object) 用作 变量对象。活动对象最初只有一个变量:参数(arguments)。题外话:上面提到的全局上下文是没有这个变量的。作用域链中的下一个变量对象来自包含上下文,再下一个对象来自下一个包含上下文。依次类推直至全局上下文。全局上下文的变量对象始终是作用域链的最后一个变量对象。

  代码执行的标识符解析是通过沿作用域链逐级搜索标识符名称完成的。搜索过程始终从作用域链的最前端开始,然后逐级往后,直到找到标识符。(未找到标识符,通常会报错)

5. 作用域(scope)

作用域,就是 变量可用性的范围。通俗的讲,就是哪些函数可以访问到这个变量。
先看下面的例子:


var color = "blue";
function changeColor() {
	if (color === "blue") {
		color = "red";
	} 
	else{
		color = "blue";
	}
}
changeColor();

上述函数 changeColor() 的作用域包含两个对象:一个是它自己的变量对象(即 arguments 对象的那个),另一个是全局上下文的变量对象。这个函数内部之所以能够访问变量color,就是因为可以在作用域链中找到它。
局部作用域中定义的变量可用于在局部上下文中替换全局变量。看看下面这个例子:


var color = "blue";
function changeColor() {
	let anotherColor = "red";
	
	function swapColors(){
		let tempColor = anotherColor;
		anotherColor = color;
		color = tempColor;
		//此处为swapColors内部,可以访问color、anotherColor 和tempColor
	}
	//此处为changeColor内部,可以访问 color 和anotherColor ,但访问不到tempColor
}
// 这里只能访问color 
changeColor();

   以上代码涉及到3个上下文:全局上下文、changeColor()的局部上下文和 swapColors()的局部上下文。他们的关系是全局上下文包含 changeColor()上下文,changeColor()包含 swapColors()。
他们的关系如下图:
在这里插入图片描述

对于swapColos来说,发现变量color, 先在自己的局部上下文 swapColors() 中搜索,发现自己并没有color的定义。往父级上下文changeColor () 中搜索,还是没有搜索到,则到全局作用域 window中搜索,本次搜索到了。

6. 作用域链增强

上下文包含全局上下文和函数上下文两种方式,按照栈的结构形成作用域链,按照顺序向上级搜索,但是有两种情况增强作用域链:
try/catch 语句的catch块
with 语句
这两种情况 直接在作用域链前端临时添加一个上下文,在代码执行后被删除。
对于with语句来说,会想作用域链前端添加一个指定的对象;
对于catch语句而言,则会创建一个新的变量对象,这个变量对象会包含要抛出的错误对象的声明。

function buildUrl(){
	let qs = "?debug=true";
	with (location) {
		let url = href + qs;
	}
	return url;  // 这里的url为 undefined
}

上面代码中,with 语句将 location 对象作为上下文,因此 location会被添加到作用域链前端。buildUrl函数中定义了一个变量 qs。 当 with 语句中的代码应用变量 href 时, 实际上引用的是 location.href,也就是自己变量对象的属性。在引用 qs 时,引用的则是定义在 buildUrl() 中的那个变量,它定义在函数上下文的变量对象上。而在with 语句中使用 var声明的变量 url 会成为函数上下文的一部分,可以作为函数的值返回;但这里使用 let 声明的变量url ,因为被限制在块级作用域,所以在with 块之外没有定义。

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

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

相关文章

linux中RocketMQ安装(单机版)及springboot中的使用

文章目录 一、安装1.1、下载RocketMQ1.2、将下载包上传到linux中,然后解压1.3、修改runserver.sh的jvm参数大小(根据自己服务器配置来修改)1.4、启动mqnamesrv (类似于注册中心)1.5、修改runbroker.sh的jvm参数大小&am…

【Linux】进程信号 --- 信号处理

👦个人主页:Weraphael ✍🏻作者简介:目前正在学习c和算法 ✈️专栏:Linux 🐋 希望大家多多支持,咱一起进步!😁 如果文章有啥瑕疵,希望大佬指点一二 如果文章对…

el-table列的显示与隐藏

需求:实现 表字段的显示与隐藏。效果图 代码实现 写在前面 首先 我部分字段有自定义的排序逻辑,和默认值或者 数据的计算 所以是不能简单的使用 v-for 循环column 。然后 我需要默认展示一部分字段,并且 当表无数据时 提示不能 显示隐藏 …

HTTP 缓存

缓存 web缓存是可以自动保存常见的文档副本的HTTP设备,当web请求抵达缓存时,如果本地有已经缓存的副本,就可以从本地存储设备而不是从原始服务器中提取这个文档。使用缓存有如下的优先。 缓存减少了冗余的数据传输缓存环节了网络瓶颈的问题…

学习大数据DAY21 Linux基本指令2

目录 思维导图 搜索查看查找类 find 从指定目录查找文件 head 与 tail 查看行 cat 查看内容 more 查看大内容 grep 过滤查找 history 查看已经执行过的历史命令 wc 统计文件 du 查看空间 管道符号 | 配合命令使用 上机练习 4 解压安装类 zip unzip 压缩解压 tar …

google 浏览器插件开发简单学习案例:TodoList

参考: google插件支持: https://blog.csdn.net/weixin_42357472/article/details/140412993 这里是把前面做的TodoList做成google插件,具体网页可以参考下面链接 TodoList网页: https://blog.csdn.net/weixin_42357472/article/de…

Web前端:HTML篇(一)

HTML简介: 超文本标记语言(英语:HyperText Markup Language,简称:HTML)是一种用于创建网页的标准标记语言。 您可以使用 HTML 来建立自己的 WEB 站点,HTML 运行在浏览器上,由浏览器…

android studio中svn的使用

第一步,建立一个项目。 第二步,share project。 第三步,选择存放的位置,然后添加提交信息,最后点击share。这样就可以在svn上面看到一个空的项目名称。 第四步,看到文件变成了绿色,点击commit图…

驾驭云原生日志洪流:高效分析与管理的策略集

🐇明明跟你说过:个人主页 🏅个人专栏:《未来已来:云原生之旅》🏅 🔖行路有良友,便是天堂🔖 目录 一、引言 1、日志管理在云原生架构中的重要性 2、云原生环境的特…

Open-TeleVision复现及机器人迁移

相关信息 标题 Open-TeleVision: Teleoperation with Immersive Active Visual Feedback作者 Xuxin Cheng1 Jialong Li1 Shiqi Yang1 Ge Yang2 Xiaolong Wang1 UC San Diego1 MIT2主页 https://robot-tv.github.io/链接 https://robot-tv.github.io/resources/television.pdf代…

Java | Leetcode Java题解之第273题整数转换英文表示

题目: 题解: class Solution {String[] singles {"", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine"};String[] t…

Linux下安装Redis(超简单)

1.下载 选着自己需要下载的版本后,右击选择复制链接,然后利用命令进行下载,进入Xshell控制台,输入wget将复制的链接粘帖上,这里我选择的是6.0.6版本。 命令如下: wget https://download.redis.io…

QML学习——Qt Quick Controls 1 Examples Calendar/FileSystemBrowser(九)

02 File System Browser Show: Notes: 使用了自定义的继承自QFileSystemModel的类,在原有的基础上新加了角色(role),并且重写了QFileSystemModel中的data函数、及角色和字符串描述对应的哈希表; 使用系统的文件资源管理器打开该文件的链接&…

资产拆分、资产分割的操作,事务代码ABUMN

在公司常见的业务运行中可能会有这样的场景:资产A 需要拆分成资产B 和 C。这个时候就需要使用到资产分割或者资产转移的操作 ,事务代码ABUMN。 我司的实际业务场景是这样的,当初想分别入账给A和B的资产。一年之后发现,当时操作错误…

高清录屏无压力,这四款软件助你轻松搞定

现在不论是教育、娱乐还是工作电脑怎么录屏都成为这些领域里不可或缺的一部分。掌握录屏软件,也能成为个人的软实力之一哦,下面我介绍几款可以快速上手的录屏软件来为你增加实力。 1、福晰REC大师 这款软件我是觉得他是我最快上手的一个工具&#xff0…

Unity UGUI 之 Dropdown

本文仅作学习笔记与交流,不作任何商业用途 本文包括但不限于unity官方手册,唐老狮,麦扣教程知识,引用会标记,如有不足还请斧正 1.Dropdown是什么 下拉列表 2.重要参数 首先这些参数和Button差不多,不过多…

昇思MindSpore学习入门-格式转换

MindSpore中可以把用于训练网络模型的数据集,转换为MindSpore特定的格式数据(MindSpore Record格式),从而更加方便地保存和加载数据。其目标是归一化用户的数据集,并进一步通过MindDataset接口实现数据的读取&#xff…

基于微信小程序+SpringBoot+Vue的校园自助打印系统(带1w+文档)

基于微信小程序SpringBootVue的校园自助打印系统(带1w文档) 基于微信小程序SpringBootVue的校园自助打印系统(带1w文档) 管理信息可以处理复杂的信息从而提高用户的工作效率,减少失误。所以本基于Vue和微信小程序的校园自助打印系统的开发非常有意义,本系…

科研绘图系列:R语言TCGA分组饼图(multiple pie charts)

介绍 在诸如癌症基因组图谱(TCGA)等群体研究项目中,为了有效地表征和比较不同群体的属性分布,科研人员广泛采用饼图作为数据可视化的工具。饼图通过将一个完整的圆形划分为若干个扇形区域,每个扇形区域的面积大小直接对应其代表的属性在整体中的占比。这种图形化的展示方…

react入门到实战-day2-7.21

昨天晚上刚学完已经一点了,来不及写笔记,主要是想睡觉哈,所以今天补上,我发现效率还挺高的,今天重新做笔记,加固了昨天的知识点,要不以后都这样子哈,学完第二天再写哈,要…