什么是栈空间?
栈空间是用来存储基本数据类型的数据(number,string,boolean,undefined,null)
注意:null 的类型是 object ,原型链的尽头就是 null
栈空间就好像一个个固定大小,依次排列的格子,里面装着变量
var a = 10;
var a = b;
上面的代码中,我们给 a 赋值为 10 , 然后将 a 的值赋值给 b,那么 b 的值也等于 10 ,在栈空间中存储情况如下
a | 10 |
---|---|
b | 10 |
接着我们修改 a 的值,那么 b 的值是否会发生变化?
a = 20;
console.log(b);//10
a | 20 |
---|---|
b | 10 |
我们修改的是 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);
(初学,认识尚浅,后期深入学习后修改)