博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
js中栈和堆详解
阅读量:3957 次
发布时间:2019-05-24

本文共 2560 字,大约阅读时间需要 8 分钟。

一、数据类型

为了更好的来阐述栈和堆,我们先来了解一下数据类型

在js中数据类型主要分为以下两大类:

基本类型:String,Number,Boolean,Null,Undefined,symbol,这6种基本数据类型它们是直接按值存放的,所以可以直接访问。

引用类型:Function,Array,Object,当我们需要访问这三种引用类型的值时,首先得从栈中获得该对象的地址指针,然后再从堆内存中取得所需的数据。

二、什么是栈,什么是堆

栈(stack):由操作系统自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈;

堆(heap):一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收,分配方式倒是类似于链表。

三、二者区别

1、缓存方式区别

1.栈使用的是一级缓存, 他们通常都是被调用时处于存储空间中,调用完毕立即释放;
2.堆是存放在二级缓存中,生命周期由虚拟机的垃圾回收算法来决定(并不是一旦成为孤儿对象就能被回收)。所以调用这些对象的速度要相对来得低一些。

2、堆栈数据结构区别

堆(数据结构):堆可以被看成是一棵树,如:堆排序;

栈(数据结构):一种先进后出的数据结构。

四、二者比较

在这里插入图片描述

var a = 10;var b =a;是 a 先取出 10,copy 一份放到 b 里面,改变 a 的值,b 的值是不变的,再把 a=20;时 b 的值还是 10,不发生改变

var arr = [1,2];var arr1 =arr;arr.push(3);

答案:这往[1,2]放 3,arr 和 arr1 都是[1,2,3]

引用值是在栈内存里面放堆的地址,拷贝的也是地址,所以改变 arr,arr1 也变了

var arr = [1,2]; var arr1 =arr; arr = [1,3]; document.write(arr1)

答案:arr = [1,3];是新建了一个新的房间。arr1 是 1,2,现在是插入新引入值”房间”,

会在堆里面重新申请一间房,并指向新房间

五、拷贝(后面知识点,现在可先不看)

1、浅度拷贝

var obj = {
name : "asdas", sex : klm, age : 12}var obj1 = {
}function clone(target, origin){
var target = target || {
} for(var prop in origin){
target[prop] = origin[prop]; } return target;}clone(obj1, obj);

结果为:

在这里插入图片描述
可以看出,原始值的拷贝,是直接复制栈里面的数值,所以一个改变但另一个不改变,但要是有引用值的情况下,就会发生下面的现象

var obj = {
name : "asdas", sex : [1,2,3], age : 12}var obj1 = {
}function clone(target, origin){
var target = target || {
} for(var prop in origin){
target[prop] = origin[prop]; } return target;}clone(obj1, obj);

结果为:

在这里插入图片描述
可以看出,这种浅度克隆,原始值改变不会影响,但是引用值改变的时候,克隆出来的那个也会跟着改变,所以要想改变这种现象,就要使用深度克隆

2、深度克隆

var obj = {
name : "sadafs", sex : "adwas", age : 213, card : ['sadsa', 'das'], wife : {
name : "asd", son : {
name : "sad", } }}var obj1 = {
} function deepClone(origin, target){
var target = target || {
}, toStr = Object.prototype.toString, arrStr = "[object Array]"; for(var prop in origin){
if(origin.hasOwnProperty(prop)){
if(origin[prop] !== "null" && typeof(origin[prop]) == 'object'){
if (toStr.call(origin[prop]) == arrStr){
target[prop] = []; }else{
target[prop] = {
}; } deepClone(origin[prop], target[prop]); }else{
target[prop] = origin[prop]; } } } return target;}

结果为:

在这里插入图片描述
这样就解决了克隆会继承的现象

六、栈和堆的溢出六: 堆和栈的溢出

如果想要堆溢出,比较简单,可以循环创建对象或大的对象; 如果想要栈溢出,可以递归调用方法,这样随着栈深度的增加,JVM

(虚拟机)维持着一条长长的方法调用轨迹,直到内存不够分配,产生栈溢出。

转载地址:http://lxtzi.baihongyu.com/

你可能感兴趣的文章
memcached了解使用和常用命令详解
查看>>
GDB调试各功能总结
查看>>
"undefined reference to" 多种可能出现的问题解决方法
查看>>
类结构定义
查看>>
Windows下关于多线程类 CSemaphore,CMutex,CCriticalSection,CEvent,信号量CSemaphore的使用介绍
查看>>
图像处理基本算法(汇总)以及实现
查看>>
C++编程获取本机网卡信息 本机IP 包括Windows和Linux
查看>>
23种设计模式详解及C++实现
查看>>
C++连接CTP接口实现简单量化交易
查看>>
服务端使用c++实现websocket协议解析及通信
查看>>
C# string.Format使用说明
查看>>
Linux下安装Mysql数据库开发环境
查看>>
Linux用户及用户组添加和删除操作
查看>>
通用 Makefile 的编写方法以及多目录 makefile 写法
查看>>
C++的4种智能指针剖析使用
查看>>
RPC框架实现之容灾策略
查看>>
Docker私库
查看>>
hdu——1106排序(重定向)
查看>>
hdu——1556Color the ball(树状数组)
查看>>
hdu——1541Stars(树状数组)
查看>>