1. 引用类型那么它是如何在内存中保存它的值呢?(对象是引用类型下面以对象举例子)
var obj1 = new Object();
var obj2 = obj1;
obj1.name = "Nicholas";
alert(obj2.name); //"Nicholas"
关于直接用等号复制内存解析
obj1 创建实例时在栈内存中开辟新空间以键值对形式保存,而这个值就是指针,指向堆内存的一个对象
obj2 = obj1 栈内存中开辟新空间储存 obj2,它的值跟obj1一样也是指针,均指向堆内存中的同一个对象
为obj1添加属性name, obj2也就拥有了这个属性
2. 那么什么是深拷贝什么是浅拷贝呢?
- 第一次看到这个这个概念是在《ES6标准入门》中的 9.5.2 注意点
- Object.assign() 这个方法实行的是浅拷贝
var obj1 = {
'a': {
'b': 1,
'c': 2
},
'd': 3
};
var obj2 = Object.assign({}, obj1);
obj1.d =4; // 通过 obj1改变 d
obj2.d; // 输出 obj2.d 发现值为3并没有改变
obj1.a.b = 3; // 通过 obj1改变 a 对象中 b 属性的值
obj2.a.b; // 输出 obj2.a.b 发现值是3 不再 2
解释: 上面有两种情况,改变对象第一层属性彼此不相互影响,而内嵌的对象b c 两个对象之间共享(把obj1 a 对象拷贝给obj2只是拷贝了a 的引用),这就是浅拷贝
浅拷贝:将 B 对象拷贝到 A 对象中,但不包括 B 里面的子对象
深拷贝:将 B 对象拷贝到 A 对象中,但包括 B 里面的子对象
3. 无子对象的深拷贝(比如数组里装的都是基本类型)
var arr1 = [1,2,3,4];
var arr2 = arr1.slice(0); // 实现深拷贝
arr2.pop();
arr1 // [1,2,3,4]
arr2 // [1,2,3]
4. 有子对象的深拷贝
- Using JSON.parse(JSON.stringify(object));
let obj = {
a: 1,
b: {
c: 2,
},
}
let newObj = JSON.parse(JSON.stringify(obj));
obj.b.c = 20;
console.log(obj); // { a: 1, b: { c: 20 } }
console.log(newObj); // { a: 1, b: { c: 2 } } (New Object Intact!)
- 另一种
function cloneObject(obj) {
var clone = {};
for(var i in obj) {
if(obj[i] != null && typeof(obj[i])=="object")
clone[i] = cloneObject(obj[i]);
else
clone[i] = obj[i];
}
return clone;
}