JavaScript 中事件循环(eventloop)、垃圾回收机制、闭包、递归函数的理解及示例

news2025/4/11 4:53:57

事件循环(eventloop)

概念

js 是单线程,为防止阻塞代码,把同步代码交给 js 引擎执行 异步代码交给宿主环境,
同步代码放入执行栈中 异步代码等待时机送入任务队列中,
执行栈执行完毕 会去任务队列看是否有异步任务 有就送到执行栈执行 反复循环查看执行 这个过程就是事件循环

同步任务和异步任务(宏任务和微任务)

  • 同步:立即放入js引擎(js主线程)执行,并原地等待结果

  • 异步:先放入宿主环境(浏览器/node),不必原地等待结果,并不阻塞主线程继续往下执行,异步结果在将来执行

  • 宏任务:由宿主(浏览器、node)发起 setTimeout setTimeout不管时间是 0 还是 200 都是异步任务

  • 微任务:由 js 引擎发起 promise、async/await、Object.observe、process.nextTick(node) promise本身是同步,then/catch 的回调函数是异步的

执行顺序

先执行同步任务,在执行微任务,宏任务。
先进先出原则

例子

console.log(1);

setTimeout(() => {
		console.log(2);
}, 0)

console.log(3);

new Promise((resolve, reject) => {
		console.log(4);
		resolve(5);
}).then(res => {
		console.log(res);
}).catch(err => { })


console.log(6);
// 1 3 4 6 5 2

垃圾回收

常见浏览器垃圾回收算法:引用计数法(基本不再使用)和标记清除法

垃圾回收机制

js 中内存的分配和回收都是自动完成的,内存在不适用的时候会被垃圾回收器自动回收

内存泄漏

不再用到的内存,没有及时释放,就叫做内存泄漏

内存的生命周期

内存分配、内存使用、内存回收
全局变量一般不会回收,页面关闭回收
局部变量一般不用了,会被自动回收

闭包

概念

可以从内部函数访问外部函数的作用域

闭包的作用

缓存数据,延长作用域链

优点同时也是缺点:滥用闭包会造成内存泄漏

闭包的模式

  • 对象模式的闭包
  • 函数模式的闭包

基本写法

function closure() {
    var name = 'xr' // closure 局部变量
    function fn() { // closure 内部函数
        console.log(name); // 使用了父函数中声明的变量,此时形成了闭包
    }
    fn()
}
closure()

闭包

另一种写法

function closure() {
    var name = 'xr'
    return function fn() {
        console.log(name);
    }
}
closure()()

思考题

var name = 'window name'
var obj = {
    name: 'obj name',
    fun: function () {
        return function () {
            console.log(this.name);
        }
    },
    fun2: function () {
        var that = this
        return function () {
            console.log(that.name);
        }
    }
}

obj.fun()() // window name
obj.fun2()() // obj namedw

递归

概念

函数中调用函数自己 此时就形成了递归

递归一定要有结束条件 不然报错

例子

递归求和

function total(num) {
    if (num === 1) return 1 // 结束条件
    return num += total(num - 1) // 调用自己
}
console.log(total(3)); // 6

解析

  • 第一轮 3 + total(2)
  • 第二轮 3 + 2 + total(1)
  • 第三轮 3 + 2 + 1

对象深克隆

var obj = {
    name: "zs",
    list: [1, 2],
    detail: {
        msg: "123",
    },
};
var o = {};
function deepClone(newObj, oldObj) {
    for (var k in oldObj) {
        var item = oldObj[k];
        //   数组也属于对象所以要先在前面判断
        if (item instanceof Array) {
            newObj[k] = [];
            deepClone(newObj[k], item);
        } else if (item instanceof Object) {
            newObj[k] = {};
            deepClone(newObj[k], item);
        } else {
            newObj[k] = item;
        }
    }
}
deepClone(o, obj);
console.log(o);
o.detail.msg = "修改成功";
console.log(obj);

递归生成 tree 数据

在这里插入图片描述

let data = [
     { id: 1, name: "办公管理", pid: 0 },
     { id: 2, name: "请假申请", pid: 1 },
     { id: 3, name: "系统设置", pid: 0 },
     { id: 4, name: "权限管理", pid: 3 },
 ];
 function parentDeal(data, pid) {
     //声明返回数组
     let returnArr = [];
     data.forEach((item) => {
         if (item.pid === pid) {
             //除去最高层级的数据(id === 0)
             returnArr.push(item)
             //进入递归中处理 
             childrenDeal(data, item, item.id)
         }
     })
     return returnArr;
 }

 function childrenDeal(arr, itemData, itemId) {
     //首先判断是否有子类  没有默认为空
     itemData.children = itemData.children ? itemData.children : [];
     arr.forEach((item) => {
         //递归条件
         if (item.pid === itemId) {
             //找到则追加至上层数据children中
             itemData.children.push(item)
             //不断递归查找子类直到找不到子类本次递归结束才进入parentDeal函数进行下一最高层级操作
             childrenDeal(arr, item, item.id)
         }
     })
 }
 let resArr = parentDeal(data, 0)
 console.log(resArr)

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

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

相关文章

Postman核心功能解析-参数化和测试报告

参数化处理 参数化:针对于某一个接口,有大量的的测试数据需要批量验证,一个一个的更改请求参数太耗时耗力,使用参数化批量处理数据会比较高效,常规通过文档参数化实现。 创建文件 格式CSV 文件内第一行信息 需要和参数…

谈谈转行数据分析以及工作的心得

由于两个月前写了一篇文章叫《自己找数据分析师时犯的错误》,然后这期间就一直有人问我找到工作了吗?面试的时候,面试官都是问你的什么呢?你从事数据分析工作之后主要干什么呢?所以想在这里为大家分别解答下。 首先回…

【Linux】编译器gcc / g++的使用

​🌠 作者:阿亮joy. 🎆专栏:《学会Linux》 🎇 座右铭:每个优秀的人都有一段沉默的时光,那段时光是付出了很多努力却得不到结果的日子,我们把它叫做扎根 目录👉gcc / g的…

快速玩转ChatGPT全攻略

本文内容: 准备工作。 注册接嘛平台。 注册OpenAI账号。 开始畅聊。 一.准备工作: Proxy,美国,日本,韩国,新加坡,印度,不能用香港。 Chrome浏览器。 二、注册接嘛平台&#x…

在ARM微控制器上部署MATLAB/Simulink仿真模型

在ARM微控制器上部署MATLAB/Simulink仿真模型 苏勇,suyong_yq126.com,2022年12月 文章目录在ARM微控制器上部署MATLAB/Simulink仿真模型IntroductionOverviewMATLAB、Simulink、StateFlow、Real-Time Workshop之间的关系MATLAB Coder、Simulink Coder、…

最新版Android原生集成RN

前言 现在不少应用都是采用了混合开发模式,不论是原生加RN,或是原生加Flutter,或是原生加H5。原生实现主业务线,其他部分可以借助跨平台方案开发,提高开发效率,或者实现热更新,调高业务迭代效率。 下面简单介绍一下A…

如何调整参数来更好地使用频谱分析仪

前言 使用频谱分析仪,最简单最直观的目的就是寻找并观测范围内的频谱信号,乃至将其保存下来做更进一步的数字处理或分析。因此在除了最基本的中心频率与扫宽设置外,合理使用VBW,RBW等参数设置才能获取更为真实准确的信号。 图一 合理调整参数…

Diffusion Model合集 part3

扩散模型原理介绍3八,Diffusion Probabilistic Model的算法代码而我们可以有多种建模目标:Lt−1Eq[12σt2∣∣μt∼(xt,x0)−μθ(xt,t)∣∣2]CL_{t-1}\mathbb{E}_{q}\left[\frac{1}{2\sigma_{t}^{2}}||\overset{\sim}{\mu_{t}}(\mathbf{x}_{t},\mathbf{…

系统调用(Linux)

目录 1.内核态和用户态: 1.1CPU的两种状态: 1.2CPU 指令集权限: 1.3用户态与内核态的空间: 1.4用户态与内核态的切换: 2.系统调用: 2.1linux框架图: 2.2系统调用和API: 2.3系…

The release Method

The release Method The role of the release method is the reverse of open. Sometimes youll find that the method implementation is called device_close instead of device_release. Either way, the device method should perform the following tasks: 释放方法的作用…

跟我学 UML 系统建模

UML 系统建模 1 概述 1.1 课程概述 汇集 UML 及其相关的一些话题回顾 UML 相关的符号与概念以电商订单相关业务为例,借助 UML 完成系统建模将 UML 变成提升建模效率,表达架构思想的工具 1.2 什么是 UML ​ Unified Modeling Language 统一建模语言&a…

Leetcode-1753-移除石子的最大得分

1、堆 我们可以维护一个大顶堆,其中储存了三个石子堆中石子的个数。为了确保我们的分数尽可能大,我们每次都需要从最大的两个堆中取出石子。因此我们不断循环,每次都从当前最大的堆中取出石子。值得注意的是,为了确保能够发现游戏…

数据管理篇之存储和成本管理

第14章 存储和成本管理 目标:有效的降低存储资源的消耗,节省存储成本。 1.数据压缩 问题 在分布式文件系统中,为了提高数据的可用性与性能 ,通常会将数据存储3份,这就意味着存储 1TB 的逻辑数据, 实际上…

iOS自动化真机测试验证环境过程中常见问题解析

本文节选自霍格沃兹测试学院内部教材 本章节主要讲解 iOS 自动化真机配置以及在 iOS 真机执行自动化时常见问题与解决方法。 真机使用的Capability 与模拟器不同,真机测试需要如下的 Capability 方式一:设置 App 路径,启动 App(自…

SpringBoot项目开启远程调试

1、服务端设置 cat start.sh #!/bin/bash echo "i will start the program!" java -jar -Xdebug -Xrunjdwp:transportdt_socket,servery,address9999 xxxxx-SNAPSHOT.jar --server.port10991 echo "start success" 2、开发工具设置 3、然后&#…

计算机网络~计算机网络体系结构

一、计算机网络的概念和功能 1. 计算机网络 是一个将分散的、具有独立功能的计算机系统,通过通信设备与线路连接起来,由功能完善的软件实现资源共享和信息传递的系统计算机网络是互联的、自治的计算机集合 互联:通过通信链路互联互通自治&a…

π120M30 双通道数字隔离器兼容ADuM3210TRZ 广泛应用于工业自动化系统方案

π120M30 双通道数字隔离器兼容ADuM3210TRZ 广泛应用于工业自动化系统方案 。具有出色的性能特征和可靠性,整体性能优于光耦和基于其他原理的数字隔离器产品。传输通道间彼此独立,可实现多种传输方向的配置,可实现 3.0kV rms 隔离耐压等级和 …

【Java语言】— 类型转换

1.类型转换 (1)自动类型转换 类型范围小的变量,可以直接赋值给类型范围大的变量。 ①自动类型转换的底层原理 ②自动类型转换的其他形式 (2)表达式的自动类型转换 在表达式中,小范围类型的变量会自动转…

python之序列反转

python之序列反转 方式1:.reverse() a [1, 2, 3, 4, 5] print(a.reverse()) # None,函数原地反转,不具备排序功能,而且没有返回值 print(a) # [5, 4, 3, 2, 1]方式2:reversed a [1, 2, 3, 4, 5] print(reversed…

2021年全国职业院校技能大赛网络搭建与应用赛项——国赛组播题

2021年全国职业院校技能大赛网络搭建与应用赛项——国赛组播题 sw1:# ip pim multicast-routing (开启组播模式,在全局模式) int vlan 10 ip pim dense-mode (在接口模式下开启组播-密集模式协议) ip igmp version 2 i…