JavaScript中的作用域(链)和闭包(一)

JavaScript作用域与闭包 在JavaScript中,作用域(Scope)指的是变量和函数的可访问性范围。在JavaScript中,作用域有全局作用域和局部作用域之分。作用域在JavaScript中起着非常重要的作用,它决定了变量和函数的可访问性,帮助我们避免命名冲突和提高代码的可维护性。在理解作用域的基础上,可以更好地编写和理解JavaScript代码。 阅读详情

学JavaScript有很长一段时间了,做了一些网页,总是有一些bug或者不好的解决方案使我困扰,感觉是原生js的基础没有打好,最近开始巩固基础,首先对作用域和闭包的相关知识回顾并总结了一下

作用域

首先介绍一下编译原理:

JavaScript引擎进行编译的步骤和传统的编译语言相似,但某些环节可能更复杂。
传统语言的源代码在执行前会经历三个步骤。统称为“编译”。

分别是:分词/词法分析—— 解析/语法分析——代码生成。

N1:整个过程大概是,将代码中的字符组成的字符串分解成有意义的代码块,代码块也被称为词法单元token。另外,分词和词法分析之间的区别比较微妙。主要差异在于词法单元的识别是通过有状态还是无状态的方式进行的。简单来说,如果词法单元生成器在判断a是一个独立的词法单元还是其他词法单元的一部分时,调用的是有状态的解析规则,这个过程就被称为词法分析。接着数组类型的词法单元流转换成一个由元素逐级嵌套所组成的代表了程序语法结构的树。——抽象语法树。(AST)

N2:var a = 2;的抽象语法树中有一个VariableDeclaration的顶级节点,接下来是一个叫做Identifier(它的值是a)的子节点,以及一个叫做AssignmentExpression的子节点。AssignmentExpression节点有一个叫做NumericLiteral(它的值是2)的子节点。

N3:将AST转换为可执行代码的过程被称为代码生成。这个过程与语言、目标平台等息息相关。简单来说就是有某种方法可以将var a = 2;的AST转化为一组机器指令,用来创建一个叫做a的变量(包括分配内存等),并将一个值 储存在a中。

JavaScript引擎要复杂得多,在语法分析和代码生成阶段有特定的步骤来运行性能进行优化,包括对冗余元素进行优化等。而且,JavaScript引擎不会有大量的时间用来优化,因为js的编译过程不是发生在构建之前。大部分情况下编译发生在代码执行前的几微秒之内。编译后做好执行它的准备,并且马上就会执行它。实际上js引擎用尽了各种办法(JIT,可以延迟编译甚至实施重编译)来保证性能最佳。

理解作用域:

引擎:负责整个js程序的编译及执行过程。
编译器:负责语法分析及代码生成。
作用域:负责收集并维护由所有声明的标识符(变量)组成的一系列查询,并实施一套非常严格的规则,确定当前代码对这些标识符的访问权限。

接下来模拟引擎、编译器、作用域之间的协作(var a = 2;):
首先编译器在遇到var a,编译器会询问作用域是否已经有一个该名称的变量存在于同一个作用域的集合中。如果是,编译器会忽略该声明,继续进行编译;否则他会要求作用域在当前作用域的集合中声明一个新的变量,并命名为 a。
接下来编译器会为引擎生成运行时所需的代码,这些代码被用来处理a = 2这个赋值操作。引擎运行时会首先询问作用域,在当前的作用域集合中是否存在一个叫做a的变量。如果是,引擎就会使用这个变量;如果否,引擎会继续查找该变量。找到了就将2赋值给它,否则抛出异常。

总结:变量的赋值操作会执行两个动作,首先编译器会在当前作用域中声明一个变量(如果之前没有声明过),然后在运行时引擎会在作用域中查找该变量,如果能够找到就会对它赋值。

接下来介绍一些编译器的术语
编译器在编译过程的第二步中生成了代码,引擎执行它时,会通过查找变量a来判断它是否已声明过。查找的过程有作用域进行协助,但是引擎执行怎样的查找,会影响最终的查找结果。

引擎会为例子中的变量a进行LHS查询。另外一个查找的类型叫作RHS。
当变量出现在赋值操作的左侧时进行LHS查询,出现在右侧时进行RHS查询。
RHS查询与简单地查找某个变量的值别无二致,而LHS查询则是试图找到变量容器的本身,从而可以对其赋值。

可以将RHS理解成retrieve his source value (取到它的源值),这意味着“得到某某的值”。
“赋值操作的目标是谁(LHS)”“谁是赋值操作的源头(RHS)”

如果RHS查询在所有嵌套的作用域中遍寻不到所需的变量,引擎就会抛出ReferenceError异常。当引擎执行LHS查询时,如果在顶层(全局作用域)中也无法找到目标变量,全局作用域中就会创建一个具有该名称的变量,并将其返还给引擎,前提是程序运行在非严格模式下。如果RHS查询到一个变量,但是你尝试对这个变量的值进行不合理的操作,引擎会抛出另外一种类型的异常,TypeError。

举例:
function foo(a){
var b = a;
return a+b;
}
var c = foo(2);
1、找出所有的LHS查询
c=..;、a = 2(隐式变量分配)、b = ..
2、找出所有的RHS查询
foo(2..、=a);、a..、..b

JavaScript所采用的词法作用域:词法化的过程会对源代码中的字符进行检查,如果是有状态的解析过程,还会赋予单词语义。词法作用域就是定义在词法阶段的作用域。是由你在写代码时将变量和块作用域写在哪里来决定的,因此当词法分析器处理代码时会保持作用域不变。(无论函数在哪里被调用,也无论如何被调用,它的词法作用域都只由函数被声明时所处的位置决定)

深入理解 JavaScript 作用域、作用域链和闭包 作用域是 JavaScript 中一个非常重要的概念,它定义了变量和函数的可访问范围,控制着变量和函数的可见性与生命周期。全局作用域:在代码的任何地方都能访问到的变量和函数所处的作用域。全局作用域中的变量和函数可以被代码中的任何部分访问和修改。函数作用域:在函数内部定义的变量和函数只能在该函数内部访问,外部无法直接访问。函数作用域是 JavaScript 中最常见的作用域类型。块级作用域。 阅读详情

相关推荐

lumerical-环形谐振器

利用mode求解器优化得到所需的环的总长度,即环形器的半径,然后通过varFDTD得到光场分布和透过率.

m0_61776728的博客 2189

JavaScript原型、原型链、作用域、作用域链、闭包

JavaScript面向对象的基础——原型链 JavaScript闭包的形成 JavaScript中this JavaScript中的毒瘤和缺陷 一些JavaScript简单语法 . 操作符:访问对象的属性 var 操作符:用来声明变量(也叫标识符) function: 用来创建函数 new 操作符:执行构造函数 全局环境和全局对象 对象字面量 原型对象 原型对象:构造函数都...

MichelleZhai的博客 1513

【网络】PFC背景和原理 、文档(DCB=PFC + ETS,DCBX=DCB扩展)

目录 零、背景 一、PFC 1.概述 2.报文格式 3.工作机制 二、ETS 产生原因 基本原理 优先级组的调度 优先级的调度 三、DCBX 产生原因 基本原理 DCBX TLV介绍 五、PFC 拥塞研究(文档收集) 六、DC-QCN算法 (网络工程师必会) 7.1 α更新 7.2 降速 7.3 提速 8.总结 ...

小鱼菜鸟的博客 2165

【金三银四】 一文弄懂 js 数据类型、堆栈内存、作用域(链)、闭包知识拓展 (一)

大家好,这里是lionLoveVue,基础知识决定了编程思维,学如逆水行舟,不进则退。金三银四,为了面试也还在慢慢积累知识,Github上面可以直接查看所有面试题整理,github传送门,觉得不错,点个Star★,持续更新中。另外,也可以关注微信公众号:小狮子前端Vue,源码以及资料今后都会放在里面。

超逸の学习技术博客 4868

美团外卖mtgsig 1.2逆向工程:从补环境到签名生成全解析

本文深入解析了美团外卖mtgsig 1.2签名算法的逆向工程全流程。从环境检测原理与补环境实战入手,详细拆解了签名JSON中每个关键字段的生成逻辑,并重点剖析了核心签名a2的生成步骤,涉及设备指纹、MD5、AES加密等关键技术。最后提供了构建签名生成器的实践思路与常见坑点,为理解复杂风控体系提供了完整的技术视角。

weixin_29324401的博客 1756

数据结构实验1.2—高精度计算PI值(西工大)

这是数据结构第二题的题目,是让我们根据用户的需求来计算派的值 这是题目的详细描述,刚看到这道题的时候,我是真的头大,完全没有思路,于是查找了一些大佬的笔记后才开始编写 这是我在写这些代码是所运用到的数学反三角函数幂次展开式的知识。 下面是正确的代码以及我的一些见解,和需要注意的一些地方。希望能对你有所帮助。如有更加精简的算法,请在评论区留下你的算法!!!谢谢!!! #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdl

abcdef0623的博客 5831

JavaScript中的作用域链和闭包

作用域 全局作用域局部作用域 作用域链执行上下文活动对象闭包闭包优化         JavaScript中出现了一个以前没学过的概念——闭包。何为闭包?从表面理解即封闭的包,与作用域有关。所以,说闭包以前先说说作用域。 作用域(scope)         通常来说一段程序代码中使用的变量和函数并不总是可用的,限定其可用性的范围即作用域,作用域的使用提高了程序逻辑的局部性,增强

李达 8427

3.嵌入式控制器EC学习,源码框架(60/64端口)(一)

服务函数剖析 上一篇讲到while循环会一直查询十六个标志位是否满足要求,一旦其中某个标志位为1时,程序将会执行相应的服务函数,而执行服务函数是通过函数指针(service_table[ _R1 ])();来实现的。接下来我们分别来看看这十六个服务函数分别包含了哪些内容。 16个函数的函数名如下: const FUNCT_PTR_V_V code service_table[16] = { // Hi-Level Service Service_PCI, // Host 6

qq_30135687的博客 4160

详解JS的作用域和闭包

作用域和闭包 尽管通常将JavaScript归类为“动态”或“解释执行”语言,但实际上它是一门编程语言。但与传统的编译语言不同,它不是提前编译的,编译结果也不能在分布式系统中进行移植。尽管如此,JavaScript引擎进行编译的步骤和传统的编译语言非常相似,在某些环节可能比预想的复杂。 传统的编译语言通常会在一段源代码执行之前经历三个步骤,统称为“编译”。这三个步骤分别是分词/词法分析(Tokenizing/Lexing)、解析/语法分析(Parsing)、代码生成。但对于JavaScript来说,大部分情

黄黄黄一边敲代码一边写出来的博客 3875

YOLOv8【第一章:基础入门篇·第2节】一文搞定,数据集制作与标注完全指南!

🏆 本文收录于 《YOLOv8实战:从入门到深度优化》 专栏,该专栏专注于分享我在YOLOv8目标检测模型中的实战经验,涵盖从入门基础到深度优化的全方位解决方案。无论你是计算机视觉的新手,还是具有多年深度学习经验的专家,本专栏都将为你提供高效、可复现的技术方案,助你掌握YOLOv8的核心技术,提升目标检测性能,突破瓶颈,优化模型,并加速项目开发🚀!

**My Coding Family** 1506

Spring Boot集成ShardingSphere实现数据加密及数据脱敏 | Spring Cloud 48

利用ShardingSphere实现: - 数据加密 - 数据脱敏

gmHappy 1万+

聊一聊 JavaScript 中的作用域和闭包

我们知道,作用域(Scope)就是**代码中变量和函数的可访问的区域,这个区域中决定了变量和函数的生命周期**。在当前的高级程序语言中,主要有词法作用域(静态作用域)和动态作用域两种。其实这两种作用域的区别主要是作用域中的变量和函数,是在编译期还是运行期确定的

hello_1566的博客 1169

基于imx6ull平台opencv的图像采集、ffmpeg推流和Windows端拉流(多线程)

本文档是针对imx6ull平台`opencv`的图像采集、ffmpeg推流和Windows端拉流。首先创建一个线程`opencv`通过摄像头采集视频图像,接着再创建两个线程,其中一个线程获取采集的视频图像送给ffmpeg服务,另一个线程用于获取采集的视频图像并处理,处理完并在显示屏上显示,详细的流程请参看如下。

程小二的博客 1607

一次搞懂作用域和闭包

对于那些有一点 JavaScript 使用经验但从未真正理解闭包概念的人来说,理解闭包可以看作是某种意义上的重生,但需要付出非常多的努力和牺牲才能理解这个概念。

fehub 2109

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

JavaScript中的预编译、作用域链和闭包

文章目录1.预编译1.1概念1.1.1什么是预编译1.1.2全局对象(Global Object)1.1.3活动对象(Activation Object) 1.预编译 首先是对预编译 1.1概念 1.1.1什么是预编译 首先,我们知道,JavaScript是解释性语言,即逐行解析,逐行执行。那么,什么是预编译呢? 咋JavaScript真正被解析前,js解析引擎会首先把整个文件进行预处理,从而来消除一些歧义,这个预处理的过程就被称为预编译 console.log(a) var a = 123 console

Mr_changxin的博客 1648

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

js执行机制,三、作用域链和闭包(clousre)

对作用域链和词法作用域的解释,和形成的闭包(closure)及闭包的使用

李三岁的博客 1188

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

JavaScript中的作用域和闭包

JavaScript是一门高级编程语言,用于Web开发、服务器端编程等领域。在JavaScript中,作用域和闭包是非常重要的概念,因为它们能够帮助开发者在代码中更好地控制变量的可见性,从而减少错误和提高代码的可维护性。在本文中,我们将深入讨论JavaScript中的作用域和闭包,并提供实例帮助你更好地理解这两个概念。

tyxjolin的专栏 967

深入解析JavaScript中的变量作用域和闭包

JavaScript作为一门解释执行的脚本语言,其变量作用域与传统编译型语言有着明显的区别。理解JavaScript的作用域与闭包对编写优雅可靠的JavaScript代码非常重要。本文将详细介绍JavaScript中变量的作用域规则,以及利用闭包实现的常见作用域应用场景,帮助读者进一步掌握JavaScript编程。​闭包(closure)指一个函数及其相关的引用环境组合。简单来说,在一个函数内部创建的函数可以访问到该函数的变量。// 访问外部函数的变量。

爱蹦跶的全栈大A阿 1066

Javascript 中 作用域、闭包与 this 指针

js 中的作用域,闭包的理解和运用,this 的理解和运用

博客From宋俊波 7836

javaScript的作用域、闭包

前言 JavaScript 中的闭包是相当重要的概念,并且与作用域相关知识的指向密切相关。 那么, JavaScript 中的作用域是什么? 闭包会在哪些场景中使用? 作用域 JavaScript 的作用域通俗来讲,就是指变量能够被访问到的范围,在 JavaScript 中作用域也分为好几种,ES5 之前只有全局作用域和函数作用域两种。ES6 出现之后,又新增了块级作用域。 全局作用域 在编程语言中,变量一般都会分为全局变量和局部变量两种。那么变量定义在函数外部,代码最前面的一般情况下都是全局变量。 在 J

小卡酷谋的博客 2083

JavaScript之作用域和闭包

JavaScript之作用域和闭包1. 作用域和作用域链1.1 作用域1.2 作用域链2. 闭包2.1 闭包怎么设计?2.2 eval2.3 给闭包下个定义2.4 闭包的缺点2.4.1 详细分析2.5 总结 1. 作用域和作用域链 1.1 作用域 变量保存和访问的范围。在JavaScript中,函数,块,模块都可以形成作用域。 作用域全称是词法作用域,是在代码编写时就确定了作用域的。 1.2 作用域链 函数之间的嵌套会形成作用域链。 比如说在全局作用域中定义了一个函数f1,又在f1中定义了一个内部函数f2,

小栗子的博客 938

js进阶——作用域闭包

闭包是 JavaScript 中非常强大且常用的特性,它结合了作用域链的机制,可以保存函数执行时的上下文环境,用于实现私有变量、回调函数、状态保持等多种功能。理解闭包及其工作原理,有助于更好地编写高效、结构清晰的 JavaScript 代码。

2301_79858914的博客 1445

JS中的闭包详解

闭包是指有权访问另一个函数作用域的变量的函数。在JavaScript中,闭包可以通过函数嵌套和变量引用实现。闭包是JavaScript中一个强大的特性,它允许函数访问其创建时的词法作用域。通过闭包,可以实现数据封装、事件处理、延迟执行等多种高级功能。理解闭包的概念和工作原理对于深入掌握JavaScript至关重要。版权声明:本博客内容为原创,转载请保留原文链接及作者信息。参考文章什么是闭包?以及闭包的作用—JavaScript基础篇 - 优快云博客。

ning的博客 1821

你不得不知道的js之作用域链与闭包

写在前面的话 作用域链和闭包 变量 变量的作用域 作用域链 闭包 闭包的一些应用写在前面的话 关于js中,作用域链和闭包是避不开的两个知识点,今天本文就简单介绍了一下关于作用域链和闭包的相关知识,本文适合有一定的js基础的朋友们阅读,本文只是个人愚见,尚有诸多不足之处,请朋友们留言交流,谢谢! 作用域链和闭包 谈到作用域链和闭包,首先介绍一下作用域链吧,而谈到作用域链,我们还是先了解一下变量的作用域

策码扬鞭的专栏 4206
上一篇: 网页导航栏中常用li标签嵌套超链接用法
下一篇: 关于AJAX请求JSON数据(解决responseText空的问题)
DoubleSRZee
博客等级 码龄10年 7粉丝 41原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值