关于深拷贝和浅拷贝的问题

可能很多同学会有这样的疑问,明明使用JSON.parse和JSON.stringfy就能实现深拷贝,为什么很多面试官在面试的时候还是喜欢提问怎么自己去实现一个深拷贝?

其实这里面大有玄机!!

一、JSON.stringfy只能序列化可枚举的属性

我们在设计一个类或者定义一个对象的时候,很多时候不想让这个属性在被Object.keys方法遍历到,因此就可以使用Object.defineProperty将这个属性的enumerab值设置为false,如此在对象被迭代或者被循环时就会自动忽略这个属性。如下图深紫色的属性就是可枚举的,浅色的属性就是不可枚举的

二、prototype原型对象

我们知道每个不同的类都有自己的原型对象,而原型对象也是属于不可枚举的属性,因此如Date类型、Dom节点类型、XMLHttprequest等在被JSON.stringfy后就会丢失自己的原型对象,沦落为最为普通的Object对象。但是很多时候我们在深拷贝之后还想使用这些原型对象上的方法,譬如Dom节点的addEventListener、appendChild方法,如今JSON.stringfy之后变成了普通对象自然就无法使用了。因此我们需要自己实现能保留原来对象类型的深拷贝方法!!!

三、使用lodash的cloneDeep

lodash是一款提供很多好玩的工具方法的插件,这里面的cloneDeep就可以满足我们上述需求

以下是使用cloneDeep方法和普通的JSON方法深拷贝的结果

function People(){  }
People.prototype.name = 'wyr'
var obj = _.cloneDeep(new People())
var obj2 = JSON.parse(JSON.stringify(new People()))

使用cloneDeep的结果,保留了原型

使用stringfy的结果,变成了普通的Object对象

 

posted @ 2022-09-20 10:57  姜小希  阅读(61)  评论(0编辑  收藏  举报