美文网首页
js中的堆、栈与深拷贝、浅拷贝

js中的堆、栈与深拷贝、浅拷贝

作者: jadefan | 来源:发表于2019-09-30 17:19 被阅读0次

程序执行过程中的变量是需要保存起来供代码调用和计算的,这就用到了内存空间,分为堆和栈

堆(heap)堆内存的简称,动态分配内存,内存大小不一,也不会自动释放。
混沌无序,方便存储和开辟内存空间
堆空间大,由用户控制释放。通过引用计数来控制生命期,回收器来释放最终的堆空间

栈(stack)栈内存的简称,自动分配相对固定大小的内存空间,并由系统自动释放。
线性结构,后进先出,便于管理

堆栈与变量的存储关系

5种基本类型:Undefined、Null、Boolean、Number和String

基本类型都是直接按值存储在栈中的,每种类型的数据占用的内存空间的大小是确定的,并由系统自动分配和自动释放。这样带来的好处就是,内存可以及时得到回收,相对于堆来说,更加容易管理内存空间。

引用类型 : 如对象(Object)、数组(Array)、函数(Function) …

引用类型的数据存储于堆中,但是数据的地址指针是存储于栈中的,当我们想要访问引用类型的值的时候,需要先从栈中获得对象的地址指针,然后,在通过地址指针找到堆中的所需要的数据。

深拷贝、浅拷贝

基本类型拷贝的时候只是在内存中又开辟了新的空间,和原始变量相互独立,不存在深浅,因此深浅拷贝是相对于引用类型来说的

浅拷贝 :引用类型在拷贝过程中,只是拷贝了存在栈内存中的指针,二者同时指向堆内存中相同数据
深拷贝 :引用类型在拷贝过程中,需要将堆内存中的数据全部拷贝,分配新的存储空间和指针,以保证二者完全独立

深拷贝的常用方法:

最简单的通过JSON转换,适用于没有函数的对象

    function deepCopy(obj) {
        return JSON.parse(JSON.stringify(obj));
    }

或者遍历对象中的所有属性和方法,一直找到最下层的基本类型为止,全部拷贝
借用大佬的代码

  //这里为了阅读方便,只深拷贝对象,关于数组的判断参照上面的例子
   function deepClone(data){
       var obj = {};
       var originQueue = [data];
       var copyQueue = [obj];
       //以下两个队列用来保存复制过程中访问过的对象,以此来避免对象环的问题(对象的某个属性值是对象本身)
       var visitQueue = [];
       var copyVisitQueue = [];
       while(originQueue.length > 0){
           var _data = originQueue.shift();
           var _obj = copyQueue.shift();
           visitQueue.push(_data);
           copyVisitQueue.push(_obj);
           for(var key in _data){
               var _value = _data[key]
               if(typeof _value !== 'object'){
                   _obj[key] = _value;
               } else {
                   //使用indexOf可以发现数组中是否存在相同的对象(实现indexOf的难点就在于对象比较)
                   var index = visitQueue.indexOf(_value);
                   if(index >= 0){
                       // 出现环的情况不需要再取出遍历
                       _obj[key] = copyVisitQueue[index];
                   } else {
                       originQueue.push(_value);
                       _obj[key] = {};
                       copyQueue.push(_obj[key]);
                   }
               }
           }
       }
       return obj;
   }
堆栈的大小问题

堆栈是在内存中的空间,大小就会有显示限制,浏览器会有自动垃圾回收机制,但代码的优化也很重要

每次执行代码时,都会分配一定尺寸的栈空间(Windows系统中为1M),每次方法调用时都会在栈里储存一定信息(如参数、局部变量、返回值等等),这些信息再少也会占用一定空间,成千上万个此类空间累积起来,自然就超过线程的栈空间了。

尤其发生在大数据量的递归处理时,后续介绍处理办法。

相关文章

  • JS中的深拷贝与浅拷贝

    知乎:js中的深拷贝和浅拷贝? 掘金: js 深拷贝 vs 浅拷贝 前言 首先深拷贝与浅拷贝只针对 Object,...

  • 对象的深拷贝与浅拷贝

    浅拷贝和深拷贝都是对于JS中的引用类型而言的,浅拷贝就只是复制对象的引用(堆和栈的关系,简单类型Undefined...

  • js 深拷贝 vs 浅拷贝(本篇博客摘抄子掘金‘sunshine

    链接本文主要讲一下 js 的基本数据类型以及一些堆和栈的知识和什么是深拷贝、什么是浅拷贝、深拷贝与浅拷贝的区别,以...

  • OC由浅入深系列 之 深浅拷贝

    一、什么是深拷贝,浅拷贝? 在堆中产生一个副本的拷贝操作称为深拷贝,在栈中声名一个指针指向对象的堆地址称为浅拷贝。...

  • 浅拷贝与深拷贝

    一、内存 我们都知道数据存放内存中,基本数据在栈内存,引用数据指针在栈内存实体在堆内存 二、深拷贝与浅拷贝 深拷贝...

  • js中的堆、栈与深拷贝、浅拷贝

    程序执行过程中的变量是需要保存起来供代码调用和计算的,这就用到了内存空间,分为堆和栈 堆(heap)堆内存的简称,...

  • js底层数据类型

    js底层数据类型 堆和栈的区别 其实深拷贝和浅拷贝的主要区别就是其在内存中的存储类型不同。 堆和栈都是内存中划分出...

  • js的深拷贝和浅拷贝

    学习之前,先了解下堆和栈知识,js 的数据类型 堆和栈的区别 其实深拷贝和浅拷贝的主要区别就是其在内存中的存储类型...

  • C++封装(二)

    第2章 对象成员与对象数组 第3章 深拷贝与浅拷贝 浅拷贝: 深拷贝: 第4章 对象指针 对象指针: 栈中: 对象...

  • Js的浅拷贝与深拷贝

    堆和栈的区别 堆和栈都是内存中划分出来的用于存储的区域。 深拷贝与浅拷贝的区别就是其在内存中存储的类型不同。 栈(...

网友评论

      本文标题:js中的堆、栈与深拷贝、浅拷贝

      本文链接:https://www.haomeiwen.com/subject/hplhpctx.html