js堆栈及深浅拷贝

js堆和栈

在js引擎中对变量的存储主要有两种位置,堆内存和栈内存
在这里插入图片描述

  • 栈内存

    • 主要用于存储各种基本类型的变量(boolean, null, undefined, string, number, symbol)
    • const, let对象,当我们定义const对象的时候,我们说的常量就是指针,就是const对象对应的堆内存指向是不变的。但是值的大小是可以改变的。所以const,let不能二次定义的原因: 就是用来初始化的时候,会首先遍历当前的内存栈,有的话就返回错误。
  • 堆内存

    • 主要存储引用类型,如Object
    • 堆内存中的对象不会随方法的结束而销毁,就算方法结束了,这个对象也可能被其他引用变量所引用(参数传递)。
  • 内存分配和垃圾回收

    • 内存分配: 栈内存线性有序存储,容量小,系统分配效率高。而堆内存首先要在堆内存新分配存储区域,之后又要将指针存储到栈内存中,效率相对较低。
    • 垃圾回收: 栈内存变量基本上用完就回收了,而堆内存中的变量因为存在很多不确定的引用,只有当所有调用的变量全部销毁之后才能回收。

传值与传址

基本类型与引用类型最大的区别实际就是传值与传址的区别。

var a = [1,2,3,4,5];
var b = a;
var c = a[0];

console.log(b); // [1,2,3,4,5]
console.log(c); // [1]

// 改变数值
b[4] = 6; // 能改变a,因为b的地址已经指向了a
c = 8; // 不能改变a,因为只是简单的获取一个数据值,地址没有指向a
console.log(a[4]); // 6
console.log(a[1]); // 1

深浅拷贝

浅拷贝只是将第一层的引用指向了新地址,但是更低层的地址还是指向原来的地址。

var obj = {
    a: 1
}

function copy (obj) {
    var result = {}
    for (var key in obj) {
        result[key] = obj[key]
    }
    return result
}
obj.c = [1];

var newObj = copy(obj)
// 传普通值的时候,不会改变原来的
newObj.b = [1]
console.log(newObj); // {a:1,c:[1], b: [1]}
console.log(obj); // {a: 1, c: [1]}

// 传引用值的时候, 因为他里面的属性还是指向同一个地址,所以原来的对象里面的该引用值也会改变。
newObj.c.push(2);
console.log(newObj); // {a:1, c:[1, 2], b: [1]}
console.log(obj);// {a: 1, c: [1, 2] }

深拷贝

var obj = { a: 1 }
function simpleDeepCopy (obj, newObj) {
    for (var key in obj) {
        if (obj[key] instanceof Object) {
            newObj[key] = obj[key].constructor === Array ? [] : {}
            simpleDeepCopy(obj[key], newObj[key])
        } else {
            newObj[key] = obj[key]
        }
    }
    return newObj
}
obj.c = [1]
obj.d = [{ a: 1 }]
obj.e = { e: 5 }
var newObj = {}
// newObj = deepCopy(obj, newObj)
newObj = simpleDeepCopy(obj, newObj)
newObj.c.push(2)
newObj.d.push({ b: 2 })
newObj.d[0].c = 0
// obj.e.c = 6
console.log(obj) // { a: 1, c: [ 1 ], d: [ { a: 1 } ], e: { e: 5 } }
console.log(newObj) //{ a: 1, c: [ 1, 2 ], d: [ { a: 1, c: 0 }, { b: 2 } ], e: { e: 5 } }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值