JS进阶-作用域
学习目标:
- 掌握作用域
学习内容:
- 作用域
- 局部作用域
- 全局作用域
- 作用域链
- JS垃圾回收机制
- 拓展-JS垃圾回收机制-算法说明
- 闭包
- 变量提升
作用域:
作用域规定了变量能够被访问的"范围",离开了这个"范围"变量便不能被访问。
作用域分为:
- 局部作用域
- 全局作用域
局部作用域:
局部作用域分为函数作用域和块作用域。
- 函数作用域:
在函数内部声明的变量只能在函数内部被访问,外部无法直接访问。
<script>function getSum() {//函数内部是函数作用域 属于局部变量const num = 10}console.log(num) //此处报错,函数外部不能使用局部作用域变量</script>
总结:
- 函数内部声明的变量,在函数外部无法被访问。
- 函数的参数也是函数内部的局部变量。
- 不同函数内部声明的变量无法互相访问。
- 函数执行完毕后,函数内部的变量实际被清空了。
- 块级作用域:
在JavaScript中使用{ }
包裹的代码称为代码块,代码块内部声明的变量外部将【有可能
】无法被访问。
<script>// for (var i = 1; i <= 3; i++) {// console.log(i)// }// console.log(i)// for (let i = 1; i <= 3; i++) {// // 块作用域// console.log(i)// }// for (let i = 1; i <= 3; i++) {// // 块作用域// console.log(i)// }if (true) {let i = 10}console.log(i) //报错,外部无法被访问到</script>
总结:
let
声明的变量会产生块级作用域,var
不会产生块级作用域。const
声明的常量也会产生块作用域。- 不同代码之间的变量无法互相访问。
- 推荐使用
let
或const
。
- 小结:
1.局部作用域分为哪两种?
局部作用域 | 说明 |
---|---|
函数作用域 | 函数内部 |
块级作用域 | { } |
2.局部作用域声明的变量外部能使用吗?
不能
全局作用域:
<script>标签
和.js文件
的【最外层】就是所谓的全局作用域,在此声明的变量在函数内部也可以被访问。
全局作用域中声明的变量,任何其它作用域都可以被访问。
<script>//全局作用域//全局作用域下声明了num变量const num = 10function fn() {//函数内部可以使用全局作用域的变量console.log(num)}//此处全局作用域</script>
注意:
- 为window对象动态添加的属性默认也是全局的,不推荐!!!
- 函数中未使用任何关键字声明的变量为全局变量,不推荐!!!!
- 尽可能少的声明全局变量,防止全局变量被污染。
- 小结:
1.全局作用域有哪些?
<script>标签内部 | - |
---|---|
.js文件 | - |
2.全局作用域声明的变量其他作用域能使用吗?
相当能
JavaScript中的作用域是程序被执行时的底层机制,了解这一机制有助于规范代码书写习惯,避免因作用域导致的语法错误。
作用域链:
作用域本质上是底层的变量查找机制
。
在函数被执行时,会优先查找当前
函数作用域中查找变量。
如果当前作用域查找不到则会依次逐级查找父级作用域
直到全局作用域。
<script>//全局作用域let a = 1let b = 2//局部作用域function f() {let a = 1//局部作用域function g() {a = 2console.log(a)}g() //调用g}f() //调用f</script>
总结:
- 嵌套关系的作用域串联起来形成了作用域链。
- 相同作用域链中按着
从小到大
的规则查找变量。 - 子作用域能够访问父作用域,父级作用域无法访问子级作用域。
- 小结:
1.作用域链本质是什么?
作用域本质上是底层的变量查找机制。
2.作用域查找的规则是什么?
会优先查找当前函数作用域中查找变量。
查找不到则会依次逐级查找父级作用域直到全局作用域。
JS垃圾回收机制:
垃圾回收机制简称GC。
JS中内存
的分配和回收都是自动完成
的,内存在不使用的时候会被垃圾回收器
自动回收。
- 内存的生命周期:
JS环境中分配的内存,一般有如下生命周期
:
内存分配
:当我们声明变量、函数、对象的时候,系统会自动为他们分配内存。内存使用
:即读写内存,也就是使用变量、函数等。内存回收
:使用完毕,由垃圾回收器
自动回收不再使用的内存。
- 说明:
全局变量一般不会回收(关闭页面回收)。
一般情况下局部变量的值
,不用了,会被自动回收
掉。
- 内存泄漏:程序中分配的
内存
由于某种原因程序未释放
或无法释放
叫做内存泄漏
。
<script>for (let i = 1; i <= 3; i++) {}let num = 10function fn() {const str = 'andy'// str = 'lily'console.log(str)}fn()fn()fn()</script>
- 小结:
1.什么是垃圾回收机制?
简称GC。
JS中内存的分配和回收都是自动完成的,内存在不使用的时候会被垃圾回收器自动回收。
2.什么是内存泄漏?
不再用到的内存,没有及时释放,就叫做内存泄漏。
3.内存的生命周期是什么样的?
内存分配、内存使用、内存回收。
全局变量一般不会回收;一般情况下局部变量的值,不用了,会被自动回收掉。
拓展-JS垃圾回收机制-算法说明:
堆栈空间分配区别:
- 栈(操作系统):由
操作系统自动分配释放
函数的参数值、局部变量等,基本数据类型
放到栈里面。 - 堆(操作系统):一般由程序员分配释放,若程序员不释放,由
垃圾回收机制
回收。复杂数据类型
放到堆里面。
下面介绍两种常见的浏览器垃圾回收算法
:引用计数法
和标记清除法
。
- 引用计数:
IE采用的引用计数算法,定义“内存不再使用
”,就是看一个对象
是否有指向它的引用,没有引用了就回收对象。
算法:
- 跟踪记录被
引用的次数
。 - 如果被引用了一次,那么就记录次数1,多次引用会
累加 ++
。 - 如果减少一个引用就
减1 --
。 - 如果引用次数是
0
,则释放内存。
由上面可以看出,引用计数算法是个简单有效的算法。
但它却存在一个致命的问题:嵌套引用
(循环引用)。
如果两个对象相互引用
,尽管他们已不再使用,垃圾回收器不会进行回收,导致内存泄漏。
因为他们的引用次数永不会是0。这样的相互引用如果说很大量的存在就会导致大量的内存泄漏。
- 标记清除法:
现代的浏览器已经不再使用引用计数算法了。
现代浏览器通用的大多是基于标记清除算法
的某些改进算法,总体思想都是一致的。
核心:
- 标记清除算法将“不再使用的对象”定义为“
无法达到的对象
”。 - 就是从
根部
(在JS中就是全局对象)出发定时扫描内存中的对象。凡是能从根部到达
的对象,都是还需要使用
的。 - 那些
无法
由根部出发触及到的对象被标记
为不再使用,稍后进行回收
。
根部已经访问不到,所以自动清除。
- 小结:
1.标记清除法核心思路是什么?
从根部扫描对象,能查找到的就是使用的,查找不到的就要回收。
闭包:
概念:一个函数对周围状态的引用捆绑在一起,内层函数中访问到其外层函数的作用域。
简单理解:闭包 = 内层函数 + 外层函数的变量
。
- 闭包作用:封闭数据,提供操作,外部也可以访问函数内部的变量。
<script>// //简单的写法// function outer() {// let a = 10// function fn() {// console.log(a)// }// fn()// }// outer()//常见的闭包的形式 外部可以访问使用 函数内部的变量function outer() {let a = 10function fn() {console.log(a)}return fn}// outer() === fn === function fn() {}// const fun = function fn(){}// const fun = outer()//常见的写法2// function outer() {// let a = 100// return function () {// console.log(a)// }// }// const fun = outer()// fun() // 调用函数//外面要使用这个10</script>
- 闭包应用:实现数据的私有。
<script>//闭包的应用//普通形式 统计函数调用的次数// let i = 0// function fn() {// i++// console.log(`函数被调用了${i}次`)// }//因为i是全局变量,容易被修改//闭包形式 统计函数调用的次数function count() {let i = 0function fn() {i++console.log(`函数被调用了${i}次`)}return fn}const fun = count()</script>
- 小结:
1.怎么理解闭包?
闭包 = 内层函数 + 外层函数的变量。
2.闭包的作用?
封闭数据,实现数据私有,外部也可以访问函数内部的变量。
闭包很有用,因为它允许将函数与其所操作的某些数据(环境)关联起来。
3.闭包也可能引起的问题?
内存泄漏。
变量提升:
变量提升是 JavaScript 中比较“奇怪”的现象,它允许在变量声明之前即被访问(仅存在于var声明变量)。
- 注意:
- 变量在未声明即被访问时会报语法错误。
- 变量在
var声明之前
即被访问,变量的值为undefined
。 let/const
声明的变量不存在变量提升。- 变量提升出现在相同作用域当中。
实际开发中推荐先声明再访问变量
。
<script>// 1. 把所有var声明的变量提升到 当前作用域的最前面// 2. 只提升声明, 不提升赋值// var num// console.log(num + '件')// num = 10// console.log(num)function fn() {console.log(num)var num = 10}fn()</script>
- 说明:
JS初学者经常花很多时间才能习惯变量提升,还经常出现一些意想不到的bug,正因为如此,ES6 引入了块级作用域,用let 或者 const声明变量,让代码写法更加规范和人性化。
- 小结:
1.用哪个关键字声明变量会有变量提升?
var
2.变量提升是什么流程?
先把var变量提升到当前作用域于最前面。
只提升变量,不提升变量赋值。
然后依次执行代码。
我们不建议
使用var
声明变量。
相关文章:

JS进阶-作用域
学习目标: 掌握作用域 学习内容: 作用域局部作用域全局作用域作用域链JS垃圾回收机制拓展-JS垃圾回收机制-算法说明闭包变量提升 作用域: 作用域规定了变量能够被访问的"范围",离开了这个"范围"变量便不能被…...

stm32 使用GPIO模拟串口发送
在STM32微控制器上实现模拟串口输出(也称为软件串口或比特邦定(Bit-Banging)串口),主要是因为硬件上的UART资源有限或者为了特定需求而需要更多的串口通信接口。模拟串口意味着使用GPIO引脚模拟UART的TX(发…...

数据的统计探针:SKlearn中的统计分析方法
数据的统计探针:SKlearn中的统计分析方法 在数据科学领域,统计分析是理解和解释数据的关键工具。Scikit-learn(简称sklearn),作为Python中一个功能强大的机器学习库,提供了多种方法来进行数据的统计分析。…...

实例演示Kafka-Stream消息流式处理流程及原理
以下结合案例:统计消息中单词出现次数,来测试并说明kafka消息流式处理的执行流程 Maven依赖 <dependencies><dependency><groupId>org.apache.kafka</groupId><artifactId>kafka-streams</artifactId><exclusio…...

【博士每天一篇文献-综述】Threats, Attacks, and Defenses in Machine Unlearning A Survey
1 介绍 年份:2024 作者:刘子耀,陈晨,南洋理工大学 期刊: 未发表 引用量:6 Liu Z, Ye H, Chen C, et al. Threats, attacks, and defenses in machine unlearning: A survey[J]. arXiv preprint arXiv:2403…...

Python数据分析实战,运输车辆驾驶行为分析,案例教程编程实例课程详解
引言 运输车辆的安全驾驶行为分析是确保道路安全、提高运输效率的重要环节。随着数据采集技术的发展和数据分析工具的普及,利用Python进行数据分析已成为这一领域的重要工具。本文将详细介绍如何使用Python进行运输车辆驾驶行为分析,涵盖数据采集、数据预处理、数据分析及结果…...

网络安全法对等级保护中的权利和义务有何规范?
在数字时代的交响乐章中,网络安全法与等级保护共同编织了一曲关于权利与义务的和谐旋律。《中华人民共和国网络安全法》作为我国网络安全领域的基本法,对等级保护提出了明确的规范,旨在构建一个安全、有序的网络空间。本文将深入解析网络安全…...

苹果清理软件:让你的设备焕然一新
随着时间的推移,无论是Mac电脑还是iOS设备,都可能会因为积累的垃圾文件、缓存、未使用的应用和其他冗余数据而开始表现出性能下降。这不仅会占用宝贵的存储空间,还可能影响设备的响应速度和电池寿命。幸运的是,有多种苹果清理软件…...

vue前端通过sessionStorage缓存字典
正常来说,一个vue项目前端需要用到的一些翻译字典对象保存方式一般有多重, 新建js文件方式保存通过vuex方式保存通过sessionStorage保存通过localStorage保存 正常以上几点的保存方式是够用了。 但是,当有字典不能以文件方式保存并且字典量…...

React Redux使用@reduxjs/toolkit的hooks
关于redux的学习过程需要几个官网,有redux官网,React Redux官网和Redux Toolkit的官网。 其中后者的中文没有找到,不过其中的使用在React Redux官网的快速入门中有介绍。 现在一般不使用connect借接口了。 对于借助Redux Toolkit的React Redu…...

Rejetto HFS 服务器存在严重漏洞受到攻击
AhnLab 报告称 ,黑客正在针对旧版本的 Rejetto HTTP 文件服务器 (HFS) 注入恶意软件和加密货币挖矿程序。 然而,由于存在错误, Rejetto 警告用户不要使用 2.3 至 2.4 版本。 2.3m 版本在个人、小型团队、教育机构和测试网络文件共享的开发…...

Electron开发 - 如何在主进程Main中让node-fetch使用系统代理
背景 开发过程中,用户设置的系统代理是不同的,比如公司内的服务器,所以就要动态地使用系统代理来访问,但是主进程默认为控制台级别的请求,不走系统代理,除非你指定系统代理配置,这个就就有了这…...

vue2 webpack使用optimization.splitChunks分包,实现按需引入,进行首屏加载优化
optimization.splitChunks的具体功能和配置信息可以去网上自行查阅。 这边简单讲一下他的使用场景、作用、如何使用: 1、没用使用splitChunks进行分包之前,所有模块都揉在一个文件里,那么当这个文件足够大、网速又一般的时候,首…...

深入理解 Docker 容器技术
一、引言 在当今的云计算和软件开发领域,Docker 容器技术已经成为了一项不可或缺的工具。它极大地改变了应用程序的部署和运行方式,为开发者和运维人员带来了诸多便利。 二、Docker 容器是什么? Docker 容器是一种轻量级、可移植、自包含的…...

redis并发、穿透、雪崩
Redis如何实现高并发 首先是单线程模型:redis采用单线程可以避免多线程下切换和竞争的开销,提高cpu的利用率,如果是多核cpu,可以部署多个redis实例。基于内存的数据存储:redis将数据存储在内存中,相比于硬…...

【架构设计】-- ACK 机制
1、ACK 机制的定义 ACK(全称:acknowledgement) 机制是一种确认机制,起源于TCP报文到达确认(ACK)机制(参考:TCP报文到达确认(ACK)机制_tcp接收方在收到一个报文…...

这些网络安全知识,请务必牢记!
#网络安全# 随着“互联网”时代的到来,人们的生活变得更加便利,但电信诈骗、信息泄露、恶意软件等也随之而来。面对网络这把双刃剑,如何绷紧思想“安全弦”,正确安全使用网络呢?今天,让我们跟随泰顺网信IP…...

学习笔记——交通安全分析11
目录 前言 当天学习笔记整理 4信控交叉口交通安全分析 结束语 前言 #随着上一轮SPSS学习完成之后,本人又开始了新教材《交通安全分析》的学习 #整理过程不易,喜欢UP就点个免费的关注趴 #本期内容接上一期10笔记 #最近确实太懒了,接受…...

Python 3 编程第一步
Python 3 编程第一步 Python 是一种广泛使用的高级编程语言,以其简洁明了的语法和强大的功能而闻名。Python 3 是该语言的最新版本,它在许多方面对早期的 Python 2 进行了改进和更新。本篇文章将作为 Python 3 编程的入门指南,带你迈出编程的第一步。 Python 3 的安装 首…...

【eMTC】eMTC 窄带以及带宽的关系
1 概述 eMTC 传输进行通信时,一般采用1.4M带宽,在和LTE小区联合部署时,需要将LTE的带宽分割成以1.4M带宽为粒度的单位,这个单位在协议上叫做窄带。 2 窄带定义 3 参考文献 36.211...

【MySQL】mysqldumpslow工具 -- 总结慢查询日志文件
1. 作用 在平时使用MySQL数据库时,经常进行查询操作,有些查询语句执行的时间非常长,当执行时间超过设定的阈值时,我们称这个查询为慢查询,慢查询的相关信息通常需要用日志记录下来称为慢查询日志,mysqldum…...

【mindspore进阶】02-ResNet50迁移学习
Mindspore 应用(2)ResNet50迁移学习 在实际应用场景中,由于训练数据集不足,所以很少有人会从头开始训练整个网络。普遍的做法是,在一个非常大的基础数据集上训练得到一个预训练模型,然后使用该模型来初始化…...

智能决策的艺术:揭秘决策树的奇妙原理与实战应用
引言 决策树(Decision Tree)是一种常用的监督学习算法,适用于分类和回归任务。它通过学习数据中的规则生成树状模型,从而做出预测决策。决策树因其易于理解和解释、无需大量数据预处理等优点,广泛应用于各种机器学习任…...

基于AOP的数据字典实现:实现前端下拉框的可配置更新
作者:后端小肥肠 创作不易,未经允许严禁转载。 目录 1. 前言 2. 数据字典 2.1. 数据字典简介 2.2. 数据字典如何管理各模块的下拉框 3. 数据字典核心内容解读 3.1. 表结构 3.2. 核心代码 3.2.1. 根据实体类名称获取下属数据字典 3.2.2. 数据字…...

基于CentOS Stream 9平台搭建RabbitMQ3.13.4以及开机自启
1. erlang与RabbitMQ对应版本参考:https://www.rabbitmq.com/which-erlang.html 2. 安装erlang 官网:https://www.erlang.org/downloads GitHub: https://github.com/rabbitmq/erlang-rpm/releases 2.1 安装依赖: yum -y install gcc glib…...

9、Redis 高级数据结构 HyperLogLog 和事务
1. HyperLogLog 简介 HyperLogLog 是一种用于基数估计的概率数据结构。它并不是一种新的数据结构,而是 Redis 中的一种字符串类型。HyperLogLog 的主要优点是能够利用极少的内存空间完成对独立总数的统计,适用于统计大量数据的独立元素数量,…...

MyBatis(30)如何在 MyBatis 中使用 XML 和注解混合配置方式
在MyBatis中,你可以灵活地选择XML配置方式、注解方式,或者将这两种方式混合使用来配置你的映射器(Mapper)。使用混合配置方式,你可以结合两者的优势,例如,利用XML配置复杂查询和动态SQL…...

强化学习与控制模型结合例子
强化学习与模型控制结合 强化学习(Reinforcement Learning, RL)与控制模型结合,可以通过整合传统控制理论和现代RL算法,利用控制模型提供的动态信息和稳定性保障,同时利用RL的学习能力优化控制策略。这种结合的方式被称为模型辅助强化学习(Model-Assisted Reinforcement…...

RKNN3588——利用推理YOLOv8推理图片
1. yolov8_test.py import os import cv2 import numpy as np from class_type import CLASSES# 设置对象置信度阈值和非极大值抑制(NMS)阈值。 OBJ_THRESH 0.25 NMS_THRESH 0.45 IMG_SIZE (640, 640)def filter_boxes(boxes, box_confidences, box_…...

【ARMv8/v9 GIC 系列 1.7 -- GIC PPI | SPI | SGI | LPI 中断使能配置介绍】
请阅读【ARM GICv3/v4 实战学习 】 文章目录 GIC 各种中断使能配置PPIs(每个处理器私有中断)SPIs(共享外设中断)SGIs(软件生成的中断)LPIs(局部中断)GIC 各种中断使能配置 在ARM GICv3和GICv4架构中,不同类型的中断(如PPIs、SPIs、SGIs和LPIs)可以通过不同的方式进…...