JavaScript相关(一)——作用域

本篇将从JS的执行上下文开始,去理解:变量提升、 栈式调用、作用域和闭包。

参考:
浏览器工作原理与实践

JS执行上下文

执行上下文是 JavaScript 执行一段代码时的运行环境,比如调用一个函数,就会生成这个函数的执行上下文,确定该函数在执行期间用到的诸如 this、变量环境、词法环境、外部环境引用等。

JS引擎执行JS代码分为两部分,第一部分是编译、第二部分才是执行,在编译阶段,会做变量提升等操作,生成JS执行上下文。
JS执行上下文中包含变量环境,变量提升的变量都存储在这里面,包括用户声明的变量以及函数声明变量,里面还包括指向外部变量环境的引用(作用域链查找)、词法环境,存储块级变量声明,即const\let声明的量,在生成了执行上下文后,才会继续执行JS可执行的代码。

执行时,需要从作用域中查询某个变量,具体查询办法是:沿着词法环境的栈顶向下查询,如果在词法环境中的某个块中查找到了,就直接返回给 JavaScript 引擎,如果没有查找到,那么继续在变量环境中查找。

showName()
console.log(myname)
showName1()var myname = '!!!'
function showName() {console.log('函数showName被执行');
}
var showName1 = function () {console.log('函数showName1被执行');
}// 输出
函数showName被执行
undefined
Error:showName1 is not a function如果showName1声明 var改成const Error:showName1 is not defined

说明:
变量的生成涉及到 声明、赋值两个阶段。在声明阶段JS引擎会把变量和函数的声明提升到代码开头执行,因此showName可以被执行,myname被默认赋值为undefined,但是showName1是一个变量赋值,它一开始只是提升了声明,因此showName1是undefined,会报错not a function。

var的创建和初始化被提升,赋值不会提升。
let的创建被提升,初始化和赋值不会提升。
function的创建、初始化和赋值都被提升。

变量提升,是指在 JavaScript 代码执行过程中,JavaScript 引擎把变量的声明部分和函数的声明部分提升到代码开头的“行为”。变量被提升后,会给变量设置默认值,这个默认值就是我们熟悉的 undefined。变量提升操作并不会直接在代码里显现出来,它是在JS代码的编译阶段完成的。

为什么要引入块级作用域
因为会存在着变量覆盖、无法自动回收全局变量导致占用内存 等设计缺陷,所以 ES6 引入了块级作用域关键字来解决这些问题。

作用域

作用域是指在程序中定义变量的区域,该位置决定了变量的生命周期。通俗地理解,作用域就是变量与函数的可访问范围,即作用域控制着变量和函数的可见性和生命周期
作用域在编码时就确定了, 不会再变化,可以用于隔离变量, 在不同作用域定义同名的变量不冲突。

作用域链:多个嵌套的作用域形成的由内向外的结构, 用于查找变量

分类:
  1. 全局作用域:全局作用域中的对象在代码中的任何地方都能访问,其生命周期伴随着页面的生命周期。
  2. 函数作用域:函数作用域就是在函数内部定义的变量或者函数,并且定义的变量或者函数只能在函数内部被访问。函数执行结束之后,函数内部定义的变量会被销毁。
  3. 块级作用域。
区别作用域与执行上下文

作用域: 静态的, 编码时就确定了(不是在运行时), 一旦确定就不会变化了
执行上下文: 执行代码时在编译阶段动态创建, 当执行结束消失
联系: 执行上下文环境是在对应的作用域中的

作用域链

function bar() {console.log(myName)
}
function foo() {var myName = "极客邦"bar()
}
var myName = "极客时间"
foo()

分析:

答案是会输出:极客时间。

为什么bar查询的作用域链不会指向foo的作用域链,而是指向全局?
因为作用域链的生成由函数声明的位置决定,和调用位置、调用栈无关。

要回答这个问题,你还需要知道什么是词法作用域
这是因为在 JavaScript 执行过程中,其作用域链是由词法作用域决定的。
词法作用域词法作用域就是指作用域是由代码中函数声明的位置来决定的,所以词法作用域是静态的作用域,通过它就能够预测代码在执行过程中如何查找标识符。

块级作用域
function bar() {var myName = "极客世界"let test1 = 100if (1) {let myName = "Chrome浏览器"console.log(test)}
}
function foo() {var myName = "极客邦"let test = 2{let test = 3bar()}
}
var myName = "极客时间"
let myAge = 10
let test = 1
foo()

分析:
顺序由图中所示

可以由图里知道,一个变量 作用域链会先查词法环境、再查变量环境,接下来顺着外部引用,依次查询词法环境、变量环境。
因此会输出:1

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

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

相关文章

【集合系列】TreeMap 集合

TreeMap 集合 1. 概述2. 方法3. 遍历方式4. 排序方式5. 代码示例16. 代码示例27. 代码示例38. 注意事项 其他集合类 父类 Map 集合类的遍历方式 TreeSet 集合 具体信息请查看 API 帮助文档 1. 概述 TreeMap 是 Java 中的一个集合类,它实现了 SortedMap 接口。它是…

抽象springBoot报错

Failed to configure a DataSource: url attribute is not specified and no embedded datasource could be configured. 中文翻译:无法配置DataSource:未指定“url”属性,并且无法配置嵌入数据源。 DataSource 翻译:数据源 得…

MMOARPG网络战斗系统二期

哈喽,大家好,我叫人宅,很高兴介绍一下本期的MMOARPG课程。 我们的mmoarpg是一套商业级别的分布式服务器框架 SNCDS这套方案。我们公司也采用的是这套框架,代码量已经近二十万行,目前还在研发。 这么多代码如果都详细演…

前端ajax技术

ajax可以实现局部刷新,也叫做无刷新,无刷新指的是整个页面不刷新,只是局部刷新,ajax可以自己发送http请求,不用通过浏览器的地址栏,所以页面整体不会刷新,ajax获取到后台数据,更新页…

kettle控件-复制记录到结果/ 从结果获取记录的使用

在数据采集过程中,遇到对方数据传送不及时的情况,导致数据漏采集,需要手工反复补采。为了解决这一问题,可以利用kettle的复制记录到结果/从结果获取记录控件。 job的整个流程如下: 设置变量: 创建目录: ge…

TCP的连接和断开详解

目录 1.TCP基础知识 1.1.TCP 头格式 1.2.TCP协议介绍 1.3.UDP协议介绍 1.4.TCP 和 UDP 区别 1.5.TCP 和 UDP 应用场景 1.6.计算机网络相关术语(缩写) 2.TCP 连接建立:三次握手 2.1.TCP 三次握手过程 2.2.三次握手原理 2.3.异常分析…

猫头虎分享:什么是IDE?新手入门用哪个IDE比较好?

博主猫头虎的技术世界 🌟 欢迎来到猫头虎的博客 — 探索技术的无限可能! 专栏链接: 🔗 精选专栏: 《面试题大全》 — 面试准备的宝典!《IDEA开发秘籍》 — 提升你的IDEA技能!《100天精通鸿蒙》 …

【模板初阶】

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 1. 泛型编程 2. 函数模板 2.1 函数模板概念 2.2 函数模板格式 2.3 函数模板的原理 2.4 函数模板的实例化 2.5 模板参数的匹配原则 3. 类模板 3.1 类模板的定义…

【VTKExamples::PolyData】第二十三期 InterpolateMeshOnGrid

很高兴在雪易的CSDN遇见你 VTK技术爱好者 QQ:870202403 前言 本文分享VTK样例InterpolateMeshOnGrid,并解析接口vtkProbeFilter 、vtkWarpScalar & vtkDealuany2D等多个接口,希望对各位小伙伴有所帮助! 感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步!…

c语言--一维数组传参的本质(详解)

目录 一、前言二、代码三、形式3.1形式13.2形式2 四、总结 一、前言 首先从⼀个问题开始,我们之前都是在函数外部计算数组的元素个数,那我们可以把函数传给⼀个函数后,函数内部求数组的元素个数吗? 二、代码 直接上代码&#x…

笔记---dp---数字三角形模型

所谓数字三角形模型,即是从数字三角形这一题衍生出来的 题目为经典题目,不再赘述,此笔记根据AcWing算法提高课来进行对数字三角形模型衍生例题的记录 题目关系如下(见AcWing里的AcSaber): AcWing.1015.摘…

使用深度学习对视频进行分类

目录 加载预训练卷积网络 加载数据 将帧转换为特征向量 准备训练数据 创建 LSTM 网络 指定训练选项 训练 LSTM 网络 组合视频分类网络 使用新数据进行分类 辅助函数 此示例说明如何通过将预训练图像分类模型和 LSTM 网络相结合来创建视频分类网络。 要为视频…