javascript的栈内存 VS 堆内存(浅拷贝 VS 深拷贝)

简介: javascript的栈内存 VS 堆内存(浅拷贝 VS 深拷贝)

在js引擎中对变量的存储主要有两种位置——栈内存(stack)和堆内存(heap)。


基本数据类型(Number、String 、Boolean、Null和Undefined)存储在栈中,按值访问


引用数据类型(Object 、Array 、Function等)的具体内容存储在堆中,其在堆内存中的引用地址(指针)存储在栈中,按引用访问(访问引用类型的数据时,首先从栈中获得该对象的地址指针,然后再从堆内存中取得所需的数据)

栈内存为线性有序存储,占据固定大小的空间,自动分配内存空间,会自动释放。容量小,系统分配效率高,垃圾回收快(变量基本上用完就回收了


堆内存为动态分配,大小不定也不会自动释放,容量大,系统分配效率相对较低(堆内存首先要在堆内存新分配存储区域,之后又要把指针存储到栈内存中),垃圾回收慢(内存中的变量因为存在很多不确定的引用,只有当所有调用的变量全部销毁之后才能回收)

浅拷贝

发生在栈中的拷贝行为,只拷贝基本值和引用值的地址。 如 =

优点:对于体量巨大的数据可以节省复制的时间和空间

缺点:数据会相互影响,不安全

深拷贝

拷贝栈中基本值和引用值的地址的同时,拷贝地址指向堆中的对象。

优点:数据互不影响,更加安全

缺点:会耗费更多的时间和空间

简单对象的深拷贝

var b = JSON.parse(JSON.stringify(a));

这种方法操作的对象的属性值不能是 undefined、symbol、函数、日期和正则。

最靠谱的深拷贝(推荐)

优点:能够实现对象和数组的深拷贝

缺点:如果拷贝的对象嵌套过深的话,会对性能有一定的消耗

function deepCopy(obj) {
  var newobj = obj.constructor === Array ? [] : {};
  if (typeof obj !== 'object') {
    return obj;
  } else {
  for (var i in obj) {
    if (typeof obj[i] === 'object'){ //判断对象的这条属性是否为对象
      newobj[i] = deepCopy(obj[i]);  //若是对象进行嵌套调用
    }else{
        newobj[i] = obj[i];
        }
    }
    }
    return newobj; //返回深度克隆后的对象
}
 
var obj1 = {
    name: 'shen',
    show: function (argument) {
        console.log(1)
    }
}
var obj2 = deepCopy(obj1)

有局限性的深拷贝

适用于无嵌套的对象,如下存在嵌套的对象不能使用

var obj2 = {
    innner: {
        name: 'shen'
    }
}

es6解构赋值

var obj1 = {
    name: 'shen',
    show: function (argument) {
        console.log(1)
    }
}
var obj2 = { ...obj1 }

Object.assign()

var obj1 = {
    name: 'shen',
    show: function (argument) {
        console.log(1)
    }
}
var obj2 = Object.assign(obj1)

数组中的slice() 和 concat()

var arr1 = [1,2,3]
var arr2 = arr1.slice()  // 方法一
// var arr2 = arr1.concat()  //方法二

目录
相关文章
|
1月前
|
监控 Java
压力测试Jmeter的简单使用,性能监控-堆内存与垃圾回收 -jvisualvm的使用
这篇文章介绍了如何使用JMeter进行压力测试,包括测试前的配置、测试执行和结果查看。同时,还探讨了性能监控工具jconsole和jvisualvm的使用,特别是jvisualvm,它可以监控内存泄露、跟踪垃圾回收、执行时内存和CPU分析以及线程分析等,文章还提供了使用这些工具的详细步骤和说明。
压力测试Jmeter的简单使用,性能监控-堆内存与垃圾回收 -jvisualvm的使用
|
7天前
|
缓存 Java 测试技术
谷粒商城笔记+踩坑(11)——性能压测和调优,JMeter压力测试+jvisualvm监控性能+资源动静分离+修改堆内存
使用JMeter对项目各个接口进行压力测试,并对前端进行动静分离优化,优化三级分类查询接口的性能
谷粒商城笔记+踩坑(11)——性能压测和调优,JMeter压力测试+jvisualvm监控性能+资源动静分离+修改堆内存
|
29天前
|
存储 程序员 编译器
堆和栈内存的区别是什么
【8月更文挑战第23天】堆和栈内存的区别是什么
61 4
|
1月前
|
JavaScript Java 开发工具
Electron V8排查问题之接近堆内存限制的处理如何解决
Electron V8排查问题之接近堆内存限制的处理如何解决
90 1
|
1月前
堆内存
1.栈(Stack)存放的都是方法中的局部变量。方法的运行一定要在栈当中运行。 2.堆(Heap)凡是new出来的东西,都是在堆当中 堆内存的东西都有一个地址值:16进制 堆内存的数据,都有默认值。
40 1
|
1月前
|
JavaScript 前端开发
js中浅拷贝和深拷贝的区别
js中浅拷贝和深拷贝的区别
22 0
|
1月前
|
搜索推荐 Java API
Electron V8排查问题之分析 node-memwatch 提供的堆内存差异信息来定位内存泄漏对象如何解决
Electron V8排查问题之分析 node-memwatch 提供的堆内存差异信息来定位内存泄漏对象如何解决
38 0
|
2月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的客户关系管理系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的客户关系管理系统附带文章源码部署视频讲解等
70 2
|
2月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的宠物援助平台附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的宠物援助平台附带文章源码部署视频讲解等
63 4
|
2月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的宠物交易平台附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的宠物交易平台附带文章源码部署视频讲解等
55 4