js进阶——词法作用域

词法作用域详解

在 JavaScript 中,作用域(scope) 决定了代码中变量的可见性和可访问性。JavaScript 使用的是 词法作用域(Lexical Scope),这意味着作用域是由代码的结构决定的,而不是执行时的上下文。了解词法作用域对于编写高效、可维护的代码至关重要。

1. 词法阶段(Lexical Phase)

词法作用域的关键在于 词法分析(lexical analysis),这是编译器在解析代码时执行的第一个步骤。编译器会扫描源代码,将代码拆解为一系列的词法单元(tokens),并根据代码的书写方式确定作用域的层次结构。在这个阶段,代码的作用域规则就已经确定了,这也是词法作用域与动态作用域(如部分语言中的函数调用时决定作用域)不同的地方。

举例:

function outer() {var a = 10;function inner() {console.log(a); // 输出 10}inner();
}
outer();

在这个例子中,inner 函数可以访问 outer 函数中的变量 a,这是因为它在词法上嵌套在 outer 内部。词法作用域在代码编译时已经确定,inner 函数总是能够“看到”外部作用域中的变量,即使 outer 函数不再执行。

2. 作用域链(Scope Chain)

当 JavaScript 代码执行时,函数内引用的变量将首先在当前函数作用域内查找。如果没找到,会沿着作用域链向外查找,直到找到变量或者到达全局作用域为止。这种查找方式是由词法作用域决定的,而不是运行时的调用栈。

例子:

var globalVar = 'global';function outer() {var outerVar = 'outer';function inner() {var innerVar = 'inner';console.log(globalVar);  // 输出 'global'console.log(outerVar);   // 输出 'outer'console.log(innerVar);   // 输出 'inner'}inner();
}
outer();

作用域链保证了 inner 函数可以访问外层作用域中的变量(outerVarglobalVar),因为这些作用域是基于代码的结构来确定的。

3. 欺骗词法(Cheating Lexical Scope)

虽然 JavaScript 使用词法作用域,但某些特殊结构允许你 欺骗(cheat)词法作用域,动态修改变量的可见性,这包括 eval()with 关键字。它们会让代码在运行时创建新的作用域,改变了 JavaScript 引擎原本的词法作用域规则。

3.1 eval()

eval() 函数可以动态地执行一段 JavaScript 代码,并在当前作用域中创建或修改变量。这会影响到词法作用域的正常行为。

例子:

function foo(str) {eval(str); // 动态执行代码console.log(a); // 输出 42
}foo("var a = 42;");

在这个例子中,evalfoo 函数的作用域中执行了一段字符串代码,使得变量 a 出现在 foo 的作用域内。虽然这种方法灵活,但它会导致代码的可读性、可维护性降低,并且对性能产生负面影响,因为 JavaScript 引擎不能在编译阶段优化 eval 的代码。

3.2 with 语句

with 语句允许你将对象的属性添加到作用域链的顶端,这使得在该作用域内可以直接引用对象的属性。

例子:

var obj = { a: 42 };with (obj) {console.log(a); // 输出 42
}

with 语句中,obj 的属性 a 被直接添加到作用域链中,因此可以像引用局部变量一样访问它。然而,with 语句也打破了词法作用域的规则,使得代码的可预测性降低。

性能影响:

  • eval()with 的使用会导致 JavaScript 引擎在优化时遇到障碍。通常 JavaScript 引擎可以在编译阶段确定作用域链,从而进行优化。但使用 evalwith 会让引擎无法预先知道代码执行时的作用域结构,进而无法进行有效的优化。
  • 使用这些特性会降低代码性能,尤其是在热路径(经常执行的代码)中。
4. 小结
  1. 词法作用域 是由代码的书写结构决定的,不受运行时的影响。变量的可见性在编译时已经确定。
  2. 作用域链 确保了嵌套函数可以访问其外部作用域的变量,作用域链是基于词法结构构建的。
  3. 使用 eval()with 会打破词法作用域的规则,动态地修改作用域链,尽量避免使用。
  4. 性能方面evalwith 的使用会阻碍引擎的优化,导致代码运行速度变慢,建议尽量避免这些特性。

词法作用域是理解 JavaScript 的核心之一,掌握了这一概念后,你可以编写出更具可读性和高效的代码。

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

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

相关文章

uniapp 整合 OpenLayer3

安装openLayer插件 命令行&#xff1a;npm install ol 安装sass插件 命令行&#xff1a;npm install -D sass 使用方法&#xff1a; *** *** <style scoped lang"scss"> </style> 安装ElementPlus 命令行&#xff1a;npm install element-plus -…

【宝藏案例篇!】不在同一局域网怎么远程桌面?实现远程桌面访问的3种方法推荐

不在同一局域网怎么远程桌面&#xff1f;当两台电脑不在同一局域网时&#xff0c;实现远程桌面访问可以通过多种方法。 以下是三种推荐的方法&#xff0c;以及每种方法的详细步骤和注意事项&#xff1a; 方法一&#xff1a;使用第三方远程控制软件 选择一款可靠的第三方远程控…

18938 汉诺塔问题

### 思路 1. **递归解决问题**&#xff1a;使用递归方法解决汉诺塔问题。 2. **递归基准**&#xff1a;当只有一个盘子时&#xff0c;直接从源杆移动到目标杆。 3. **递归步骤**&#xff1a; - 将n-1个盘子从源杆移动到辅助杆。 - 将第n个盘子从源杆移动到目标杆。 - …

JavaScript二进制浮点数和四舍五入错误

二进制浮点数和四舍五入错误 实数有无数个&#xff0c;但JS通过浮点数的形式&#xff0c;只能表示有限个数&#xff0c;JS表现的常常是真实值的近似表示。 二进制无法表示类似于0.1这样的十进制数字&#xff0c;只能机器近似于0.1&#xff0c;看如下代码&#xff1a; <!D…

Python 中的方法解析顺序(MRO)

在 Python 中&#xff0c;MRO&#xff08;Method Resolution Order&#xff0c;方法解析顺序&#xff09;是指类继承体系中&#xff0c;Python 如何确定在调用方法时的解析顺序。MRO 决定了在多继承环境下&#xff0c;Python 如何寻找方法或属性&#xff0c;即它会根据一定规则…

二,MyBatis -Plus 关于映射 Java Bean 对象的注意事项和细节(详细说明)

二&#xff0c;MyBatis -Plus 关于映射 Java Bean 对象的注意事项和细节(详细说明) 文章目录 二&#xff0c;MyBatis -Plus 关于映射 Java Bean 对象的注意事项和细节(详细说明)1. 映射2. 表的映射3. 字段映射4. 字段失效5. 视图属性6. 总结&#xff1a;7. 最后&#xff1a; 1.…

【数据优化】基于GEE填补遥感缺失数据

GEE填补遥感数据缺失 1.写在前面2.填充代码2.1 年内中值数据填充MODIS NPP空值2.2 年内中值数据填充Landsat8 NDVI空值 1.写在前面 在遥感影像分析中&#xff0c;我们经常会遇到由于云层遮挡、传感器故障等多重因素导致的图像数据缺失问题。为了解决这一挑战&#xff0c;常用的…

Selenium with Python学习笔记整理(网课+网站持续更新)

本篇是根据学习网站和网课结合自己做的学习笔记&#xff0c;后续会一边学习一边补齐和整理笔记 官方学习网站在这获取&#xff1a; https://selenium-python.readthedocs.io/getting-started.html#simple-usage WEB UI自动化环境配置 (推荐靠谱的博客文章来进行环境配置,具…

MySQL高阶之存储过程

什么是存储过程? 存储过程可称为过程化SQL语言&#xff0c;是在普通SQL语句的基础上增加了编程语言的特点&#xff0c;把数据操作语句(DML)和查询语句(DQL)组织在过程化代码中&#xff0c;通过逻辑判断、循环等操作实现复杂计算的程序语言。 换句话说&#xff0c;存储过程其实…

Acwing BFS

一般通过队列实现&#xff0c;当边的权值相同时具有最短性&#xff0c;可以求最少操作步数。相比DFS无需回溯&#xff0c;而是逐层搜索。 Acwing 844 走迷宫 输入样例&#xff1a; 5 5 0 1 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 1 1 0 0 0 0 1 0 输出样例&#xff1a; 8 思路分析&am…

Spring Boot蜗牛兼职网:全栈开发

第4章 系统设计 4.1 系统体系结构 蜗牛兼职网的结构图4-1所示&#xff1a; 图4-1 系统结构 登录系统结构图&#xff0c;如图4-2所示&#xff1a; 图4-2 登录结构图 蜗牛兼职网结构图&#xff0c;如图4-3所示。 图4-3 蜗牛兼职网结构图 4.2开发流程设计 系统流程的分析是通…

[今日Arxiv] 思维迭代:利用内心对话进行自主大型语言模型推理

思维迭代&#xff1a;利用内心对话进行自主大型语言模型推理 Iteration of Thought: Leveraging Inner Dialogue for Autonomous Large Language Model Reasoning URL&#xff1a;https://arxiv.org/abs/2409.12618 注&#xff1a;翻译可能存在误差&#xff0c;详细内容建议…

Java -2

常用API System 可以获取当前时间&#xff0c;以此计算运行代码的时间也可以控制代码的结束 //获取当前时间点-毫秒 1970 1-1 8:00 long num System.currentTimeMillis(); System.out.println(num);//系统退出运行 System.exit(0); Runtime 获取操作系统的线程大小 能从操…

YOLOv8改进 | 主干网络 | 将backbone替换为Swin-Transformer结构【论文必备】

秋招面试专栏推荐 &#xff1a;深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 &#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 专栏目录 &#xff1a;《YOLOv8改进有效…

Tansformer代码实现

目录 1.Tansformer架构图 2.代码实现 2.1创建类&#xff1a;实现基于位置的前馈网络 2.2创建 残差&LN层标准归一化的类 2.3编码器block 2.4创建编码器 2.5创建解码器 2.6transformer解码器部分 3.知识点个人理解 1.Tansformer架构图 2.代码实现 2.1创建类&…

连续数组问题

目录 一题目&#xff1a; 二思路&#xff1a; 三代码&#xff1a; 一题目&#xff1a; leetcode链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 二思路&#xff1a; 思路&#xff1a;前缀和&#xff08;第二种&#xff09;化0为-1hash&#xff1a; 这样可以把…

【大模型实战篇】一种关于大模型高质量数据的处理方法-无标注数据类别快速识别及重复数据检测(加权向量-卷积神经网络-聚类算法结合)

1. 背景介绍 大模型的能力很大程度上依赖于高质量的数据&#xff0c;在之前的一篇文章《高质量数据过滤及一种BoostedBaggingFilter处理方法的介绍》中&#xff0c;我们介绍了大模型的数据处理链路&#xff0c;本文继续关注在高质量数据的模块。 本文所要介绍的处理方法&…

vscode 配置django

创建运行环境 使用pip安装Django&#xff1a;pip install django。 创建一个新的Django项目&#xff1a;django-admin startproject myproject。 打开VSCode&#xff0c;并在项目文件夹中打开终端。 在VSCode中安装Python扩展&#xff08;如果尚未安装&#xff09;。 在项…

滑动窗口经典题目

目录 滑动窗口 什么是滑动窗口&#xff1f; 什么时候用滑动窗口&#xff1f; 怎么用滑动窗口&#xff1f; 209. 长度最小的子数组&#xff08;滑动窗口的引入&#xff09; 3. 无重复字符的最长子串 1004. 最大连续1的个数 III 1658. 将 x 减到 0 的最小操作数 904. 水…

Fyne ( go跨平台GUI )中文文档-容器和布局 (四)

本文档注意参考官网(developer.fyne.io/) 编写, 只保留基本用法 go代码展示为Go 1.16 及更高版本, ide为goland2021.2 这是一个系列文章&#xff1a; Fyne ( go跨平台GUI )中文文档-入门(一)-CSDN博客 Fyne ( go跨平台GUI )中文文档-Fyne总览(二)-CSDN博客 Fyne ( go跨平台GUI…