对于js基本数据类型是不存在深拷贝与浅拷贝的问题。因为基本数据类型只会在栈中开辟地址,每声明一个基本数据类型,就会在栈中开辟一个新的栈地址,每个地址之间互不干预,所以只有引用类型才有深浅拷贝。
对于js中的对象(object)和数组(array)才会出现深拷贝与浅拷贝的问题。说说浅拷贝的原理:有两个变量,变量obj1在栈中开辟了一个obj1的地址,同时变量obj2变量也在栈中开辟了一个obj2的地址。浅拷贝,只是将内部的基本数据类型指向不同的栈,但内部的引用类型还是指向相同的堆。
<script>
// 对象的拷贝
var obj1 = {
name: 'zs',
age: 18,
sex: '男',
dog: {
name: '金毛',
age: 2,
yellow: '黄色'
}
}
var obj2 = {};
// 封装函数 - 把o1 的成员,复制给o2
function copy(o1, o2) {
for (var key in o1) {
o2[key] = o1[key];
}
}
copy(obj1, obj2);
// 修改obj1中的成员
obj1.name = 'xxxx';
obj1.dog.name = '大黄';
console.dir(obj2);
</script>
输出的值为(这里面的obj2.name的数值没有改变)
深拷贝的原理是在堆中开辟一个另外的一个全新的地址,并且将obj1中的堆地址的中的数值复制到新开辟的堆中,obj2中的栈地址指向于新开辟的堆地址中,因此改变了obj1的堆地址的数值,并不会影响到obj2堆地址中的数值
<script>
// 深拷贝
var obj1 = {
name: 'zs',
age: 18,
sex: '男',
dog: {
name: '金毛',
age: 2
},
friends: ['ls', 'ww']
}
// 深拷贝 把o1的成员拷贝给o2
function deepCopy(o1, o2) {
for (var key in o1) {
// 获取key属性对应的值
var item = o1[key];
// 如果item 是对象?
// var o = {}
if (item instanceof Object) {
// var o = {};
o2[key] = {};
deepCopy(item, o2[key]);
} else if (item instanceof Array) {
// 如果item 是数组呢?
// var arr = [];
o2[key] = [];
deepCopy(item, o2[key]);
} else {
// 如果是简单类型
o2[key] = o1[key];
}
}
}
var obj2 = {};
deepCopy(obj1, obj2);
// 修改obj1中的成员 是否会影响obj2?
obj1.dog.name = 'xxx';
obj1.friends[0] = 'xxx';
console.dir(obj2);
</script>
输出的值为