2020-10-26 初识堆栈空间与深浅拷贝

什么是栈空间?

栈空间是用来存储基本数据类型的数据(number,string,boolean,undefined,null)
注意:null 的类型是 object ,原型链的尽头就是 null
栈空间就好像一个个固定大小,依次排列的格子,里面装着变量

var a = 10;
var a = b;

上面的代码中,我们给 a 赋值为 10 , 然后将 a 的值赋值给 b,那么 b 的值也等于 10 ,在栈空间中存储情况如下

a10
b10

接着我们修改 a 的值,那么 b 的值是否会发生变化?

a = 20;
console.log(b);//10
a20
b10

我们修改的是 a 的值,和 b 没有任何关系,所以 b 的值是不会改变的。

堆空间

除了五大基本数据类型,还有一种复杂数据类型(Object),堆空间就是存储对象的
每当我们新建一个对象的时候,计算机都会在堆空间中开辟一个新的空间,将这个空间的地址赋值给变量

var obj = {
	name:'我是obj'
};
var obj1 = obj;

我们将 obj 对象赋值给一个新的变量,这个变量也会变成对象,且含有相同的属性。
没有画图软件,谅解
变量 obj1 其实接收的是存储在 obj 中的地址,因为有了相同的地址,就指向了相同的堆空间。
这样的值传递会造成一个问题,当我们改变 obj 中的变量的时候,obj1 中的变量也会随之改变,这里就引申出了浅拷贝,这样的值传递就被称为浅拷贝。

浅拷贝

  • 浅拷贝只存在于复杂数据类型中
  • 浅拷贝只是拷贝了别人的地址,并不是拷贝别人的内容

深拷贝

  • 深拷贝也只存在于复杂数据类型中
  • 深拷贝就是将别人的东西完整的复制一遍

1、如何进行深拷贝?
可以取出对象中的每一个值进行传递

var obj = {
	name:'tom',
	age:18
};
var newObj = {};
newObj.name = obj.name;
newObj.age = obj.age;
console.log(newObj);

2、使用Object.assign(新对象,原对象)

当对象中只有一级属性,没有二级属性的时候,此方法为深拷贝,但是对象中有对象的时候,此方法,在二级属性以后就是浅拷贝。(来自程序员小哥哥)

var source = {"id":1,name:"lin"};
var target = Object.assign({},source);

通过以上的方式我们发现,当我们再去改变 obj 里面的值的时候,newObj 里面的值并不是发生改变,如果你以为深拷贝就这?那你就错了

var obj = {
	subject:['语文','数学'],
	score:[50,45]
};
var newObj = {};
newObj.subject = obj.object;
newObj.score = obj.score;
console.log(newObj);//这里得到的结果确实完全于 obj 的相等

obj.score[0] = 100;
console.log(obj);// obj = {
				//subject:['语文','数学'],
				//score:[100,45]//注意,obj中的数据已经被我们改变
console.log(newObj);// obj = {
				//subject:['语文','数学'],
				//score:[100,45]//注意这里的结果也发生了改变

在上面的代码中,我们发现 newObj 的值也发生了改变,为什么了?
因为在我们的对象中,obj.score 任然是一个复杂数据类型,那就相当于 obj.score 中装的任然是这个数组对象的地址,(有点像套娃,对象中的对象)我们需要一层一层的解开进行拷贝,去拿他的值,而不是地址
以上的深拷贝又被称为假深拷贝,那么到底有没有真的深拷贝呢?

真深拷贝

初级自写,深入学习后再修改
我们对传入的对象进行判断,他里面的值如果是基本数据类型,就直接拷贝,如果不是,就深入进去,取里面的值,任然对里面的值进行判断,如果还有复杂数据类型,那不妨回调自身,用递归思路解决(写的不好,望大佬指导)

var obj = {
        id:'h2003',
        student:['1','2',[3,4]],
        teacher:{
            name:'xiaoyue',
            age:20
        },
        ooo:null
    };
    function copy(obj,newObj) {//这里传递的newObj必须是一个空对象
        var arr = Object.getOwnPropertyNames(obj);
        for(i in arr){
            if(typeof obj[arr[i]] == 'object' && obj[arr[i]] != null){
                if(obj[arr[i]] instanceof Array){
                    newObj[arr[i]] = [];
                    copy(obj[arr[i]],newObj[arr[i]]);
                }else{
                    newObj[arr[i]] = {};
                    copy(obj[arr[i]],newObj[arr[i]]);
                }
            }else{
                newObj[arr[i]] = obj[arr[i]];
            }
        }
        return newObj;
    }
    var newObj = {};
    copy(obj,newObj);

(初学,认识尚浅,后期深入学习后修改)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值