【JS】栈内存、堆内存、事件机制区别

js中,内存主要分为两种类型:栈内存(stack)、堆内存(heap),两种内存区域在存储和管理数据时有各自的特点和用途。

栈内存

访问顺序

栈是先进后出、后进先出的数据结构,栈内存是内存用于存放临时变量的一片内存块,是一种特殊的列表,栈内元素只能通过列表的一端访问,这一端成为栈顶,另一端称为栈底。

存储数据

栈内存主要用于存储各种基本类型的变量,包括Boolean、Number、String、Undefined、Null、Symbol、BigInt以及对象变量的指针。

比如乒乓球盒子,盒子顶层的乒乓球,是最后放进去的,但可以最先被使用,如果想要取最底层的乒乓球,必须将上面的乒乓球都取出才行,这就是栈先进后出、后进先出的特点。

注意:闭包中的基本数据类型变量是在堆中,而不是在栈中;

          通过new String类似这种new出来的实例对象,也是在堆中,而不是在栈中;

堆内存

访问顺序

堆内存不同于栈,虽然都是存储的一片空间,但堆中存储变量没什么规律,只会用一块足够大的空间存储变量。js不允许直接访问堆内存中的位置。

存储数据

堆内存主要用于存储像对象Object变量类型的的存储,堆内存存储的对象类型数据对于大小这方面,一般都是未知的。

注意:闭包中的基本数据类型变量是在堆中,而不是在栈中;

          通过new String类似这种new出来的实例对象,也是在堆中,而不是在栈中;

// 基本数据类型-栈内存
let a1 = 0;
// 基本数据类型-栈内存
let a2 = 'this is string';
// 基本数据类型-栈内存
let a3 = null;
// 对象的指针存放在栈内存中,指针指向的对象存放在堆内存中
let b = { m: 20 };
// 数组的指针存放在栈内存中,指针指向的数组存放在堆内存中
let c = [1, 2, 3];

变量复制

基本类型复制

let a = 20;
let b = a;
b = 30;
console.log(a); // 此时 a 的值是多少,是 30?还是 20?
// 答案是20

 a、b都是基本类型,值是存在栈中的,a、b有各自独立的栈空间,所以修改了b的值后,a不会变化。

引用类型复制

let m = { a: 10, b: 20 };
let n = m;
n.a = 15;
console.log(m.a) // 此时 m.a 的值是多少,是10?还是15?
// 答案是15

 m、n都是引用类型,栈内存中存放的地址指向堆内存中的对象,引用类型的复制会为新的变量自动分配一个新的值保存在变量中,但只是引用类型的一个地址指针而已,实际指向的是同一个对象。

常常问到的面试题:const定义的值是否可以改

答案:部分能改,部分不能改。

  • 定义基本数据类型后,是不可修改的;
  • 定义对象时,不可修改的是指向堆内存中的地址,对象内部的属性和方法是可以修改的;

栈内存、堆内存优缺点 

栈:

  • 存储基本数据类型:Boolean、Number、String、Undefined、Null、Symbol、BigInt以及对象变量的指针。
  • 固定大小:栈内存的大小是固定的,由操作系统在程序运行时分配,数据进栈,栈顶指针移动,分配空间,数据出栈,栈顶指针反向移动,释放空间。
  • 快速访问:栈内存采用线性结构,访问数据速度非常快。
  • 自动管理:js引擎会自动管理栈内存,分配和回收空间,不需要手动介入。
  • 函数执行的时候是放在栈里执行的。

堆:

  • 存储引用数据类型:Object(包括普通对象、数组、函数)、String(通过拼接方式创建)
  • 动态大小:堆内存大小是动态的,可以根据程序的运行需求进行扩展和收缩。
  • 较慢访问:堆内存的数据是通过栈中的引用地址访问的,所以相对较慢。
  • 垃圾回收:堆内容中的变量只有在所有的引用都结束后,才会被回收。
  • 闭包中的局部变量存在堆中。

浏览器的事件机制

对象是放在堆里的,常见的基础类型和函数放在栈里,函数执行的时候,在栈里执行,栈里函数执行的时候,可能会调一些Dom操作,ajax,settimeout,这时候,要等栈里所有程序先走,走完再执行ajax,ajax执行完后,结果放在回调队列里(队列中代码,先进先执行),也就是当栈里程序走完,再从任务队列中读取事件,将队列中的事件放到执行栈中依次执行。

  • 所有同步任务都在主线程上执行,形成一个执行栈;
  • 主线程之外,还存在一个任务队列,只要异步任务有了运行结果,就在任务队列中放置一个事件;
  • 一旦执行栈里所有的同步任务执行完毕,胸痛会读取任务队列中的事件,放到执行栈中,依次执行;
  • 主线程从任务队列中读取事件,这个过程是循环不断的;
  • 宏任务、微任务属于队列,并不是放在栈中,具体看【JS】Promise与setTimeout执行顺序_js settimeout 同步执行-CSDN博客

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

glog在vs2022 hello world中使用

准备工作 设置dns为阿里云dns 223.5.5.5,下载cmake,vs2022,git git clone https://github.com/google/glog.git cd glog mkdir build cd build cmake .. 拷贝文件 新建hello world并设置 设置预处理器增加GLOG_USE_GLOG_EXPORT;GLOG_NO_AB…

20241127 给typecho文章编辑附件 添加视频 图片预览

Typecho在写文章时,如果一次性上传太多张图片可能分不清哪张,因为附件没有略缩图,无法实时阅览图片,给文章插入图片时很不方便。 编辑admin/file-upload.php 大约十八行的位置 一个while 循环里面,这是在进行html元素更新操作,在合…

重生之我在异世界学编程之C语言:二维数组篇

大家好,这里是小编的博客频道 小编的博客:就爱学编程 很高兴在CSDN这个大家庭与大家相识,希望能在这里与大家共同进步,共同收获更好的自己!!! 本文目录 引言正文一 二维数组的创建1. 二维数组的…

Tree搜索二叉树、map和set_数据结构

数据结构专栏 如烟花般绚烂却又稍纵即逝的个人主页 本章讲述数据结构中搜索二叉树与HashMap的学习,感谢大家的支持!欢迎大家踊跃评论,感谢大佬们的支持! 目录 搜索二叉树的概念二叉树搜索模拟实现搜索二叉树查找搜索二叉树插入搜索二叉树删除…

分离整数的各个数

分离整数的各个数 C语言代码C 语言代码Java语言代码Python语言代码 💐The Begin💐点点关注,收藏不迷路💐 给定一个整数,要求从个位开始分离出它的每一位数字。 输入 输入一个整数,整数在1到100000000之间…

OpenAI Whisper 语音识别 模型部署及接口封装

环境配置: 一、安装依赖: pip install -U openai-whisper 或者,以下命令会从这个存储库拉取并安装最新的提交,以及其Python依赖项: pip install githttps://github.com/openai/whisper.git 二、安装ffmpeg: cd …

PotPlayer 最新版本支持使用 Whisper 自动识别语音生成字幕

PotPlayer 最新版本支持使用 Whisper 自动识别语音生成字幕 设置使用下载地址 设置 使用 下载地址 https://www.videohelp.com/software/PotPlayer

第33周:运动鞋识别(Tensorflow实战第五周)

目录 前言 一、前期工作 1.1 设置GPU 1.2 导入数据 1.3 查看数据 二、数据预处理 2.1 加载数据 2.2 可视化数据 2.3 再次检查数据 2.4 配置数据集 2.4.1 基本概念介绍 2.4.2 代码完成 三、构建CNN网络 四、训练模型 4.1 设置动态学习率 4.2 早停与保存最佳模型…

云轴科技ZStack助力 “上科大智慧校园信创云平台”入选上海市2024年优秀信创解决方案

近日,为激发创新活⼒,促进信创⾏业⾼质量发展,由上海市经济信息化委会同上海市委网信办、上海市密码管理局、上海市国资委等主办的“2024年上海市优秀信创解决方案”征集遴选活动圆满落幕。云轴科技ZStack支持的“上科大智慧校园信创云平台”…

Linux 服务器使用指南:诞生与演进以及版本(一)

一、引言 在当今信息技术的浪潮中,Linux 操作系统无疑是一个关键的支柱😎。无论是在服务器管理、软件开发还是大数据处理领域,Linux 都以其卓越的适应性和优势脱颖而出👍。然而,对于许多新手而言,Linux 系统…

基于树莓派3B+的简易智能家居小项目(WiringPi库 + C语言开发)

github主页:https://github.com/snqx-lqh 本项目github地址:https://github.com/snqx-lqh/RaspberryPiSmartHome 硬件开源地址:https://oshwhub.com/from_zero/shu-mei-pai-kuo-zhan-ban 欢迎交流 树莓派智能家居项目,学习树莓派的…

YOLOv8-Pose NCNN安卓部署

YOLOv8-Pose NCNN安卓部署 前言 YOLOv8-Pose NCNN安卓部署 目前的帧率可以稳定在30帧左右,下面是这个项目的github地址:https://github.com/gaoxumustwin/ncnn-android-yolov8-pose 介绍 在做YOLOv8-Pose NCNN安卓部署的时候,在github上…

【热门主题】000077 物联网智能项目:开启智能未来的钥匙

前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏关注哦 💕 目录 【热…

【STM32学习】TB6612FNG驱动芯片的学习,驱动电路的学习

目录 1、TB6612电机驱动芯片 1.1如下是芯片的引脚图: 1.2如下图是电机的控制逻辑: 1.3MOS管运转逻辑 1.3典型应用电路 2、H桥驱动电路 2.1、单极模式 2.2、双极模式 2.3、高低端MOS管导通条件 2.4、H桥电路设计 2.5、自举电路 3、电气特性 3…

day01(Linux底层)基础知识

目录 导学 基础知识 1、Bootloader是什么 2、Bootloader的基本作用 3、入式中常见的Bootloader有哪些 4、Linux系统移植为什么要使用bootloader 5、uboot和Bootloader之间的关系 6.Uboot的获取 7、uboot版本命名 8、uboot版本选择 9、uboot的特点 10.Uboot使用 导学…

OpenFeign 服务调用

1.简介 微服务架构中使用 OpenFeign 进行服务调用, OpenFeign 提供了一种简洁的方式来定义和处理服 务间的调用。 OpenFeign 作为一个声明式的、模块化的 HTTP 客户端,通过 「接口」 的定义和 「注解」 的使用,简化了微服务之间的通信调用。…

superset load_examples加载失败解决方法

如果在执行load_examples命令后,出现上方图片情况,或是相似报错(url error\connection error),大概率原因是python程序请求github数据,无法访问. 因此我们可以将数据下载在本地来解决. 1.下载zip压缩文件,存放到本地 官方示例地址:GitHub - apache-superset/examples-data …

k8s集成skywalking

如果能科学上网的话,安装应该不难,如果有问题可以给我留言 本篇文章我将给大家介绍“分布式链路追踪”的内容,对于目前大部分采用微服务架构的公司来说,分布式链路追踪都是必备的,无论它是传统微服务体系亦或是新一代…

深度学习Python基础(2)

二 数据处理 一般来说PyTorch中深度学习训练的流程是这样的: 1. 创建Dateset 2. Dataset传递给DataLoader 3. DataLoader迭代产生训练数据提供给模型 对应的一般都会有这三部分代码 # 创建Dateset(可以自定义) dataset face_dataset # Dataset部分自定义过的…

【Git教程 之 安装】

Git教程 之 安装 Git教程 之 安装Windows系统安装gitLinux安装gitmacOS安装Git Git教程 之 安装 Windows系统安装git 首先从官网上直接下载安装 选择对应的操作系统,我电脑是Windows,所以我演示以Windows为主 点进去 点击Click here to download 下…