一、浅拷贝
1. 概念
在JavaScript中,拷贝一般是指变量的复制过程。
对于简单类型,拷贝就是直接赋值的过程;
对于复杂类型,浅拷贝是指复制对象的引用地址的过程。如果修改了源对象的某个属性,由于引用相同,所以目标对象的属性也会被改变。
2. 测试
// 测试1
function test() {
var obj = {
id: 1,
name: 'Tom',
props: {
age: 18,
},
color: ['red', 'green'],
};
const res = copy(obj);
obj.props.age = 20; // 修改原对象的属性值,观察目标对象是否受影响
console.log(res.props.age === 20); // true // 表示目标对象受到影响
}
3. 实现
function copy(source) {
let res = {};
for (const key in source) {
res[key] = source[key];
}
return res;
}
二、深拷贝
1. 概念
对于复杂类型,浅拷贝是指完全复制一个全新的对象,修改原对象的属性,不会影响目标对象。因为复制出来的2个对象引用不同,也就是指向内存的地址不同。
2. 测试
function test() {
var obj = {
id: 1,
name: 'Tom',
props: {
age: 18,
},
color: ['red', 'green'],
};
let res = deepCopy(obj);
obj.props.age = 20; // 修改原对象的属性值,观察目标对象是否受影响
console.log(res.props.age === 18); // true // 表示不受影响
}
3. 实现
// 第一版
function deepCopy(target, source) {
for (const key in source) {
const item = source[key];
if (Array.isArray(item)) {
target[key] = [];
deepCopy(target[key], item);
} else if (typeof element === 'object') {
target[key] = {};
deepCopy(target[key], item);
} else {
target[key] = item;
}
}
}
仔细观察发现第一个版本有很多冗余的代码,改造一下:
// 第二版
function deepCopy(target, source) {
for (const key in source) {
const item = source[key];
if (typeof item === 'object') {
deepCopy(Array.isArray(target[key]) ? [] : {}, item);
} else {
target[key] = item;
}
}
}
三、总结
-
如果一个已知对象,属性都是简单类型,可以通过
JSON.parse(JSON.stringify(source))
来实现深拷贝 -
但是如果原对象中有函数、日期、正则等复杂类型的属性,转换后会出现属性丢失问题
-
产生这种问题的根本原因是
JSON
不支持这些上述复杂类型,具体解释可以看这里。
// 测试 JSON方式的深拷贝
function test() {
var obj = {
name: 'bird',
speak: function() {
console.log('ji ji ji')
}
}
let res = deepClone(obj);
console.log(res.speak); // undefined // 表示方法属性丢失了
}
function deepClone(source) {
return JSON.parse(JSON.stringify(source));
}
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!