前端内存空间(堆、栈、队列、拷贝、垃圾回收)

在了解前端内存空间前,我们先学习三种基本数据结构:堆、栈、队列。

栈是一种线性的数据结构,它遵循后进先出(LIFO)的原则。栈的特点是只能在栈顶进行插入和删除操作,因此栈的底部是栈中的最小值。
栈是自动分配相对固定大小的内存空间、并由系统自动释放

常见算法题应用

有效的括号、删除字符串中的所有相邻重复项…

堆是一种树状的数据结构,每个节点都可以有零个或多个子节点。堆的特点是每个节点的值都大于或等于其子节点的值,因此堆的根节点是堆中的最大值。
堆是动态分配内存、内存大小不固定,也不自动释放,是一种无序的树状结构,满足key-value 键值对的存储方式

队列

队列是一种线性的数据结构,它遵循先进先出(FIFO)的原则。队列的特点是只能在队列的一端进行插入操作,在另一端进行删除操作,因此队列的头部是队列中的最小值。

队列可以在js的事件循环机制中,再深入理解TODO

js数据类型

基本类型

undefined 、null、number、string、boolean、symbol、bigint
值传递,栈内存中存储的是值的拷贝,所以对基本类型的操作不会影响到原变量。

const a = 10;
const b = a;
b = 20;
console.log(a); // 10

引用类型

Object、Array、Function、Date、等等
址传递,堆内存中存储的是地址的拷贝,对引用类型的操作会影响到原变量。

const a = { name: 'Kevin' };
const b = a;
b.name = 'Daisy';
console.log(a.name); // Daisy

深拷贝、浅拷贝

深拷贝

深拷贝是指完全复制一个对象,包括对象的所有属性和方法,以及对象的所有嵌套对象和嵌套数组。
深拷贝会创建一个新的对象,将原对象的所有属性和方法复制到新对象中,并且新对象的所有属性和方法都是新的对象,不会与原对象共享内存。

1、序列化和反序列

问题:undefined、function、symbol这三种类型的值是非安全的(包括该对象的属性循环赋值该对象),所以格式化后,就被过滤掉了,而set、map这种数据格式的对象,也并没有被正确处理,而是处理成了一个空对象。
另外,对于循环引用的对象,会直接报错

const a = { name: 'Kevin', age: 18 };
const b = JSON.parse(JSON.stringify(a));
b.name = 'Daisy';
console.log(a.name); // Kevin
// 循环引用
var data = {name: 'foo',child: null,
}
data.child = data

在这里插入图片描述

2、Object.assign
const a = { name: 'Kevin', age: 18 };
const b = Object.assign({}, a);
b.name = 'Daisy';
console.log(a.name); // Kevin
3、手写深拷贝

需要考虑对象、数组、处理循环引用

/**  class类写法 */
class DeepClone {constructor(){cloneVal: null;}clone(val, map = new WeakMap()) {let type = this.getType(val); //当是引用类型的时候先拿到其确定的类型if (this.isObj(val)) {switch (type) {case 'date':             //日期类型重新new一次传入之前的值,date实例化本身结果不变return new Date(val);break;case 'regexp':           //正则类型直接new一个新的正则传入source和flags即可return new RegExp(val.source, val.flags);break;case 'function':        //如果是函数类型就直接通过function包裹返回一个新的函数,并且改变this指向return new RegExp(val.source, val.flags);break;default:this.cloneVal = Array.isArray(val) ? [] : {};if (map.has(val)) return map.get(val)map.set(val, this.cloneVal)for (let key in val) {if (val.hasOwnProperty(key)) { //判断是不是自身的keythis.cloneVal[key] = new DeepClone().clone(val[key], map);}}return this.cloneVal;}} else {return val;     //当是基本数据类型的时候直接返回}}/** 判断是否是引用类型 */isObj(val) {   return (typeof val == 'object' || typeof val == 'function') && val != null}/** 获取类型 */getType(data) { var s = Object.prototype.toString.call(data);return s.match(/\[object (.*?)\]/)[1].toLowerCase();};
}/** 测试 */
var a ={a:1,b:true,c:undefined,d:null,e:function(a,b){return a + b},f: /\W+/gi,time: new Date(),}
const deepClone = new DeepClone()
let b = deepClone.clone(a)
console.log(b)
4、lodash库

_.cloneDeep()

浅拷贝

浅拷贝是指只复制对象的一层属性,而不复制对象的嵌套属性。

const a = { name: 'Kevin', age: 18 };
const b = {...a };
b.name = 'Daisy';
console.log(a.name); // Kevin

垃圾回收机制

JavaScript中有自动垃圾回收机制,会通过标记清除的算法识别哪些变量对象不再使用,对其进行销毁。开发者也可在代码中手动设置变量值为null(a = null)进行标记清除,让其失去引用,以便下一次垃圾回收时进行有效回收。

堆内存中的对象不会随方法的结束而销毁,就算方法结束了,这个对象也可能会被其他引用变量所引用(参数传递)。创建对象是为了反复利用(因为对象的创建成本通常较大),这个对象将被保存到运行时数据区(也就是堆内存)。只有当一个对象没有任何引用变量引用它时,系统的垃圾回收机制才会在核实的时候回收它。

为什么会有栈内存和堆内存之分?

通常与垃圾回收机制有关。为了使程序运行时占用的内存最小。

当一个方法执行时,每个方法都会建立自己的内存栈,在这个方法内定义的变量将会逐个放入这块栈内存里,随着方法的执行结束,这个方法的内存栈也将自然销毁了。因此,所有在方法中定义的变量都是放在栈内存中的;

当我们在程序中创建一个对象时,这个对象将被保存到运行时数据区中,以便反复利用(因为对象的创建成本通常较大),这个运行时数据区就是堆内存。堆内存中的对象不会随方法的结束而销毁,即使方法结束后,这个对象还可能被另一个引用变量所引用(方法的参数传递时很常见),则这个对象依然不会被销毁,只有当一个对象没有任何引用变量引用它时,系统的垃圾回收机制才会在核实的时候回收它。

引用计数垃圾收集

如果没有引用指向该对象(零引用),对象将被垃圾回收机制回收。
但是当循环引用时,就会出现内存泄漏。

标记清除

垃圾收集器在运行时会给内存中的所有变量都加上一个标记,假设内存中所有对象都是垃圾,全标记为0
然后从各个根对象开始遍历,把不是垃圾的节点改成1
清理所有标记为0的垃圾,销毁并回收它们所占用的内存空间
最后,把所有内存中对象标记修改为0,等待下一轮垃圾回收

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

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

相关文章

浮动+flex布局

一.浮动 1.介绍 2.效果 <style> .one{ width: 100px; height: 100px; background-color: red; float: left; } .two{ width: 200px; height: 200px; background-color: blue; float: right; } </style> </head> <body> <div class"one&quo…

安全日志记录的重要性

1024程序员节不仅是对技术的庆祝&#xff0c;也是我们审视自己工作中责任的重要时刻。在现代信息安全体系中&#xff0c;安全日志记录是最关键的环节之一。它不仅能帮助企业或开发者及时发现安全威胁&#xff0c;还能在事后追踪攻击源、分析事件并采取补救措施。因此&#xff0…

架构师备考-系统分析与设计(结构化方法)

定义 1978年&#xff0c;E.Yourdon 和 L.L.Constantine 提出了结构化方法&#xff0c;即 SASD 方法&#xff0c;也可称为面向功能的软件开发方法或面向数据流的软件开发方法。Yourdon 方法是20世纪80年代使用最广泛的软件开发方法。 结构化方法提出了一组提高软件结构合…

正点原子阿尔法ARM开发板-IMX6ULL(十二)——驱动开发的简单介绍

文章目录 一、前言二、Linux驱动开发思维三、驱动开发分类四、应用程序和驱动的交互原理五、字符设备驱动开发流程 一、前言 也终于是到了这个最是激动人心的时刻了&#xff0c;那个也是从本科&#xff0c;就听说过的词汇&#xff0c;非常的让人神往&#xff0c;这个词对我而言…

人工智能原理实验二:搜索方法

一、实验目的 本实验课程是计算机、智能、物联网等专业学生的一门专业课程&#xff0c;通过实验&#xff0c;帮助学生更好地掌握人工智能相关概念、技术、原理、应用等&#xff1b;通过实验提高学生编写实验报告、总结实验结果的能力&#xff1b;使学生对智能程序、智能算法等…

Chromium 中chrome.fontSettings扩展接口定义c++

一、chrome.fontSettings 使用 chrome.fontSettings API 管理 Chrome 的字体设置。 权限 fontSettings 要使用 Font Settings API&#xff0c;您必须在扩展程序中声明 "fontSettings" 权限 清单。例如&#xff1a; {"name": "My Font Settings E…

npm install | npm ERR! Incorrect or missing password.

前端项目更新&#xff0c;执行npm install 安装依赖的时候&#xff0c;经常会出现一些莫名奇妙的问题&#xff0c;其中由于开发在本地编写的时候&#xff0c;可能会引用一些私有包&#xff0c;部署到服务器时就会出现问题&#xff0c;下面是排查过程。 npm ERR! code E401 npm …

C++——写一函数,将一个3x3的整型矩阵转置。用指针或引用方法处理。

没注释的源代码 #include <iostream> using namespace std; void move(int *p); int main() { int a[3][3],*p; cout<<"please input matrix:"<<endl; for(int i0;i<3;i) { for(int j0;j<3;j) { …

React + SpreadJS 开发时常见问题

在使用React与SpreadJS进行开发时&#xff0c;可能会遇到各种各样的问题。以下是一些常见的问题及其解决建议&#xff1a; 1. SpreadJS初始化失败 问题描述&#xff1a; 有时候SpreadJS的初始化可能会失败&#xff0c;特别是在React组件的生命周期内不当的初始化时机。 解决…

【AI应用】大模型工具如何助力文字创意工作(提示词Prompt+谷歌NotebookLM)

出发点&#xff1a;身处信息碎片和过载的时代&#xff0c;如何在日常工作学习中汇总并高效梳理知识&#xff1f;普通用户又如何激发AI大模型产出高质量的结果呢&#xff1f;本文将给出这两个问题的一些解决思路。 0、提纲&#xff1a; 提示词工程应知应会NotebookLM惊艳登场总…

springboot 使用 weixin-java-pay 支付demo

springboot引入依赖 <dependency><groupId>com.github.binarywang</groupId><artifactId>weixin-java-pay</artifactId><version>4.6.0</version></dependency>配置 wx:pay:appId: *********mchId: ********apiV3Key: ******…

数据安全-接口数据混合加密笔记

接口数据传输安全设计方案 采用非对称加密对称加密混合方式&#xff0c;接口混合加、解密过程梳理&#xff1a; 后端准备sm2公钥和私钥后端将SM2公钥传输到前端前端生成SM4密钥前端使用SM2公钥加密SM4秘钥&#xff0c;获得密文使用SM4秘钥加密数据将密文和加密数据传输至后端…

深入 Prometheus 监控生态 - 第六篇:与 Grafana 实现系统全面监控(健康状态和任务状态看板)

文章目录 前言部署 Grafana 和连接 Prometheus 数据源简单部署 Grafana 构建系统监控看板1. 监控信息查看2. 看板制作&#xff08;表格图&#xff09;配置表格图&#xff08;Line Chart&#xff09; 配置告警规则与通知1. Prometheus 中的告警规则2. Grafana 告警配置&#xff…

剧本杀门店预约小程序,在线一键预约体验

剧本杀作为集社交、角色扮演、休闲娱乐为一体的游戏&#xff0c;吸引了年轻人的目光。当下&#xff0c;随着市场的发展&#xff0c;剧本杀行业正面临挑战&#xff0c;对于门店来说&#xff0c;如何找到新的发展方向&#xff0c;在市场中脱颖而出是重中之重&#xff01; 线上线…

Python自动化数据备份与同步

在日常运维工作中&#xff0c;定期备份重要数据是确保业务连续性和数据安全的关键步骤。本文将介绍如何使用Python的shutil库来复制文件和目录&#xff0c;并结合schedule库实现定时执行备份任务的功能。 1. 环境准备 首先&#xff0c;我们需要安装schedule库&#xff0c;这个…

使用Html5基本标签实现“时空电影网”案例步骤及详细代码

根据您的需求&#xff0c;我为您实现了对“时空电影网”电影节页面的美化。以下是详细的步骤&#xff1a; 设置一级标题“电影节”文字的颜色&#xff1a;将一级标题的颜色设置为深蓝色&#xff08;#0000FF&#xff09;。 <h1><font color"darkblue">电…

SpringBoot技术:闲一品交易的新机遇

摘 要 随着科学技术的飞速发展&#xff0c;社会的方方面面、各行各业都在努力与现代的先进技术接轨&#xff0c;通过科技手段来提高自身的优势&#xff0c;闲一品交易平台当然也不能排除在外。闲一品交易平台是以实际运用为开发背景&#xff0c;运用软件工程原理和开发方法&…

柔性数组的使用

1.只有一个malloc的情况 //柔性数组的使用 #include<stdio.h> #include<stdlib.h> #include<errno.h> struct s {int i;int a[]; }; int main() {struct s* ps (struct s*)malloc(sizeof(struct s) 20 * sizeof(int));if (ps NULL){perror("malloc&…

gradio RuntimeError: async generator raised StopAsyncIteration

主要是return和yield混用导致的&#xff0c;yield是可以流式回复&#xff0c;return一次性回答&#xff1b;需要通义&#xff0c;都改成yield&#xff0c;但不是流式的内容需要最后再加个return 移除了所有的 return 语句&#xff0c;改为 yield 加 return。在生成器函数中&…

SpringAI你知道吗???

目前AI的浪潮已经居高不下了&#xff0c;因此我最近也开始了有关AI的项目&#xff0c;再开始AI的项目之前&#xff0c;我们也要先熟知AI的开发文档和知识&#xff0c;才能更好的开发项目&#xff0c;因此特地从官网查看了有关SpringAI的使用。 Spring AI 官方说明文档&#xf…