对象拷贝
对象拷贝分成浅拷贝和深拷贝
浅拷贝
即只拷贝对象第一层的属性值,如果属性是引用类型,拷贝的是其引用:
1 | let origin = { list: [1, 2, 3], foo: 'foo' }; |
实现
除了上面的 Object.assign
方法,还有许多 API 和方法来实现浅拷贝:
遍历实现:
1
2
3
4let cp = {};
for (const key in origin) {
cp[key] = origin[key];
}ES6 展开运算符:
1
let cp = { ...origin };
迭代器:
1
let cp = Object.fromEntries(Object.entries(origin));
通过
Object.create
的第二个参数传入拷贝对象的属性描述列表:1
2
3
4let cp = Object.create(
Object.prototype,
Object.getOwnPropertyDescriptors(origin)
);通过
Object.defineProperties
的第二个参数传入拷贝对象的属性描述列表:1
Object.defineProperties({}, Object.getOwnPropertyDescriptors(origin));
深拷贝
在浅拷贝的基础上,遇到引用类型的值,进行递归处理,有两点需要注意:
ES6 部分新的内置数据结构对象要特殊处理下,例如
Set
,Map
,Symbol
循环引用也需要用一个
weakMap
来存储复用,防止陷入无限递归
实现
我推荐用工具库实现的深拷贝,例如 lodash
,ramda
等等
这边也放上一个掘金上找到的不错的实现,其实有很多可以优化的地方,但是我懒得改了,加些注释就算了:
1 | // 深拷贝具体版,非完全,但大部分都可以 |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 乱炖锅!
评论