针对引用类型来说 赋值 浅拷贝的区别
1.浅拷贝 赋值的区别
- 当我们把一个对象赋值给一个新的变量时,赋的其实是该对象的在栈中的地址,而不是堆中的数据。也就是两个对象指向的是同一个存储空间,无论哪个对象发生改变,其实都是改变的存储空间的内容,因此,两个对象是联动的。
- 浅拷贝是创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址 ,所以如果其中一个对象改变了这个地址,就会影响到另一个对象。
深拷贝 浅拷贝
- 浅拷贝是创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址 ,所以如果其中一个对象改变了这个地址,就会影响到另一个对象。简单来说:(浅拷贝只拷贝一层,更深层次的对象级别只靠被引用)
- 深拷贝是将一个对象从内存中完整的拷贝一份出来,从堆内存中开辟一个新的区域存放新对象,且修改新对象不会影响原对象。简单来说:(深拷贝拷贝多层,每一级别的数据都会拷贝)
浅拷贝的实现
var obj = {
name: 'andy',
msg: {
age: 18 //引用数据类型
}
}
function shallowClone(Obj) {
var newObj = {}
for (var k in Obj) {
//hasOwnProperty()方法用于检测一个对象是否含有特定的自身属性,
返回一个boolen值
if(Obj.hasOwnProperty(k)) {
newObj[k] = Obj[k]
}
}
return newObj
}
var newObjShallowClone = shallowClone(obj)
newObjShallowClone.name = 'mary'
newObjShallowClone.msg.age = 20
console.log(newObjShallowClone);
console.log(obj);
//es6中的语法
var newObj = {}
Object.assign(newObj, obj)
console.log(newObj);
深拷贝的实现
var person = {
name: 'js',
msg: {
age: 18 //引用数据类型
},
language: ['c', 'c++', 'java', 'python'] //引用数据类型
}
var o = {}
// 利用函数的递归实现
function deepClone(newPerson, oldPerson) {
for(var k in oldPerson) {
// 判断属性值属于哪种数据类型
// 获取属性值 oldPerson[k]
var item = oldPerson[k]
// 数据类型属于数组
if(item instanceof Array) {
newPerson[k] = [],
deepClone(newPerson[k], item)
// 数据类型属于对象
} else if(item instanceof Object) {
newPerson[k] = {}
deepClone(newPerson[k], item)
} else {
// 属于简单数据类型
newPerson[k] = item
}
}
return newPerson
}
var newPerson = deepClone(o, person)
newPerson.name = 'ts'
newPerson.msg.age = 20
newPerson.language[0] = 'c#'
console.log(newPerson);
console.log(person);