Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

深拷贝 #9

Open
huitoutunao opened this issue Jul 4, 2021 · 0 comments
Open

深拷贝 #9

huitoutunao opened this issue Jul 4, 2021 · 0 comments
Labels

Comments

@huitoutunao
Copy link
Owner

深拷贝

前言

这个话题在面试上已经是老生常谈了,今天让我们一起来学习下深拷贝。

定义

在引出定义前,我们先来看下面的例子:

var arr = [{
    name: 'foo'
}, {
    age: 20
}]
var newArr = arr.concat()

newArr[0].name = 'bar'
newArr[1].age = 24

console.log(arr) // [{name: "bar"}, {age: 24}]
console.log(newArr) // [{name: "bar"}, {age: 24}]

分析:首先 concat() 方法拷贝了 arr 对象到 newArr,但是我们改变 newArr 数组对象的值时,arr 的数组对象也会随着变化。为了不影响原数组对象的值,我们就需要使用深拷贝。

因此,深拷贝指的是创建一个新的对象和数组,将原对象的各项属性的「值」(数组的所有元素)拷贝过来,是「值」而不是「引用」。

实现

在拷贝的时候判断一下属性值的类型,如果是对象,我们就递归调用深拷贝函数。见下方:

function cloneDeep (val) {
    if (typeof val === 'object') {
        var newVal = val instanceof Array ? [] : {}
        for (var key in val) {
            if (val.hasOwnProperty(key)) {
                newVal[key] = typeof val[key] === 'object' ? cloneDeep(val[key]) : val[key]
            }
        }
        return newVal
    }
}

var arr = [{
    name: 'foo'
}, {
    age: 20
}]
var newArr = cloneDeep(arr)

newArr[0].name = 'bar'
newArr[1].age = 24

console.log(arr) // [{name: "foo"}, {age: 20}]
console.log(newArr) // [{name: "bar"}, {age: 24}]

性能问题

尽管使用深拷贝会完全的克隆一个新对象,不会产生副作用,但是深拷贝因为使用递归,性能会不如浅拷贝,在开发中,还是要根据实际情况进行选择。

结语

本文到这里就结束了。通过这篇文章了解深拷贝的定义和实现,以及它的性能问题。希望本文能够帮助到你,共勉!

参考文献

JavaScript专题之深浅拷贝

@huitoutunao huitoutunao added the 专题系列 JS专题 label Jul 4, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant