• js内存与数据


    1.内存空间的重要性

    想要对js理解更深刻,就需要对内存空间有个清晰的认知。

    • 比如基本和引用数据类型存储方式和引用传递到底是怎么回事? 
    • 栈内存与堆内存的区别?

    2.计算机存储空间

    • 内存:容量小 访问速度快 程序运行时(临时占用)
    • 硬盘:容量大 访问速度慢 程序安装

    3.js运行和存储空间的关联

    • js运行在哪里? 运行在浏览器内存
    • 和硬盘完全没有关联吗? 有关联,比如做数据的持久化存储(localStorage)

    4.js的哪些场景会占用内存空间?

    • 函数声明 -> 函数体:页面运行期间持续存在。如全局变量会一直占用内存空间
    • 函数运行 -> 执行上下文:临时占用内存空间,函数运行结束释放内存

    5.内存的生命周期(内存管理的过程)

    1. 分配内存 (定义变量)
    2. 使用内存(变量值的读取或写入)
    3. 回收内存(对不在使用的数据进行回收)
    1. // 分配内存
    2. var obj = {
    3. b: 2
    4. }
    5. var obj1 = 1
    6. // 使用内存
    7. console.log(obj)
    8. // 回收内存?那基本数据类型怎么回收?
    9. obj = null

    6.js中内存空间类型:栈内存与堆内存

    栈内存与堆内存本身没有区别,只是存储方式的差异,有了不同。

    6.1 栈内存:

    • 栈内存:通常用于记录函数执行记录(函数调用栈),包括函数内的基础数据类型
    • 特性:先进后出 后进先出
    • 使用场景:通常用于记录函数的执行记录,它代表了函数的执行顺序(函数调用栈

    6.2 堆内存

    • 堆内存:存储引用数据类型,也就是对象。访问没有顺序限制
    • 特性:堆内存中的变量只有在所有对它的引用都结束的时候才会被回收。

    1. var testHeap = {
    2. a: 10,
    3. b: 20,
    4. c: {
    5. m: 100,
    6. n: 110
    7. }
    8. }
    9. testHeap.a

    7.数据类型——基础数据类型 => 栈内存

    • string
    • number 
    • boolean
    • null
    • undefined
    • BigInt
    • Symbol

    7.1特性:

    • 按值访问
    • 是不可变数据(值本身无法被改变

     7.2实例说明1:

    1. var a = 1;
    2. var b = a;
    3. console.log(a === b)
    4. b += 1;//栈中值的本身是无法修改的,var b = a赋值时,是先在栈中开辟内存b,然后将a的值赋值给b;当b = b+1是又会重新开辟一块空间,将b+1的值2赋值给b,原来的b占用的空间被释放
    5. console.log(a === b)
    6. console.log(a);
    7. console.log(b);
    8. var str = 'hello'
    9. str += 'world'

    解析:栈中值的本身是无法修改的,var b = a赋值时,是先在栈中开辟内存b,然后将a的值赋值给b;当b = b+1是又会重新开辟一块空间,将b+1的值2赋值给b,原来的b占用的空间被释放 

     

    说明:

    第一个打印中a b 的等价,并不表示他们是同一个地址(指向同一个内存地址)。a赋值给b的时候,其实是把1这个值赋值给了b,而不是赋值的内存地址。所以说,基础数据类型,是按值访问的。

    7.3 当两个基础类型的变量进行比较时,本质上,也是他们的值在进行比较

    1. var a = 1;
    2. var b = a;
    3. console.log(a === b)

    7.4不可变数据实例2:

    如:对字符串的操作一定是返回一个新字符串,原始字符串并没有被改变

    1. var str = 'hello world'
    2. str[0] = 'b'
    3. console.log(str) // 'hello world'基本数据类型值的本身不会被修改

     8.数据类型——引用数据类型(对象) => 堆内存

    • object
    • array
    • function
    • Date
    • RegExp
    • Set和WeakSet
    • Map和WeakMap

    8.1特性

    • 按引用访问
    • 值可以被改变

    8.2实例1

    1. var a = {
    2. m: 1
    3. };
    4. var b = a; //b=a 赋值是赋值的内存地址,所以赋值后修改b,a也会被修改
    5. console.log(a === b) //true
    6. b.m = 2
    7. console.log(a === b)
    8. console.log(b.m);
    9. console.log(a.m);

    赋值是赋值的内存地址,所以赋值后修改b,a也会被修改 

     

     8.3当引用数据类型在进行比较时,本质上,是对他们的内存地址进行比较

    1. var a = {}
    2. var b = {}
    3. console.log(a == b) //false

    此处a和b都由自己独立的内存地址,所以返回false 

    8.4对象常见雷区:引用传递

    实例1:

    想要通过一个方法修改对象,而不改变原有对象

    1. // 示例1
    2. var person = {
    3. province: 'hubei',
    4. city: 'wuhan'
    5. }
    6. function getPerson(p, name, age) {
    7. p.name = name;
    8. p.age = age;
    9. return p;
    10. }
    11. var a = getPerson(person, 'Bob', 10);
    12. console.log(a);
    13. console.log(person);
    14. console.log(a === person);

    说明:最后原有对象也被修改了,传入的是person对象的内存地址,所以修改p以后,person也会被修改 

    实例2

    想通过Object.assign()方法创建一个新的对象bar,但是发现最后foo对象也被更改了

    console.log(foo === bar);//进行了浅拷贝

    1. // 示例2
    2. var foo = {
    3. a: 1,
    4. b: 2
    5. };
    6. // Object.assign方法是浅拷贝,拷贝的是数据的内存地址
    7. var bar = Object.assign(foo, { c: 100 }); // a,b,c
    8. console.log(foo, bar);//foo被修改,{a: 1, b: 2, c: 100}
    9. var bar = Object.assign({}, foo, { c: 100 });
    10. console.log(foo, bar);//{a: 1, b: 2, c: 100}
    11. foo.b = 3;
    12. console.log(foo, bar);//{a: 1, b: 3, c: 100},{a: 1, b: 2, c: 100}
    13. console.log(foo === bar);//进行了浅拷贝

  • 相关阅读:
    练习题57:接口的语法特征
    数据结构 链表
    【药材识别】基于matlab GUI SVM色差色温判断药材炮制程度系统【含Matlab源码 2241期】
    Mysql——》Innodb存储引擎的索引
    APP网站如何防止短信验证码接口被攻击
    论文翻译:2021_LACOPE: Latency-Constrained Pitch Estimation for Speech Enhancement
    前端_Vue_1.初识Vue
    前端基础建设与架构30 实现高可用:使用 Puppeteer 生成性能最优的海报系统
    Mac 快捷键整理
    svn介绍 4.0
  • 原文地址:https://blog.csdn.net/qq_34569497/article/details/133814515