How to clone a javascript ES6 class instance
如何使用ES6克隆JavaScript类实例。
我对基于jquery或$extend的解决方案不感兴趣。
我已经看过很多关于对象克隆的老讨论,这些讨论表明这个问题非常复杂,但是有了ES6,一个非常简单的解决方案出现了——我将把它放在下面,看看人们是否认为它是令人满意的。
编辑:有人建议我的问题是重复的;我看到了这个答案,但它已经7岁了,使用ES6JS之前的版本涉及非常复杂的答案。我建议,考虑到ES6,我的问题有一个非常简单的解决方案。
- 如果您对堆栈溢出的旧问题有了新的答案,请将该答案添加到原始问题中,而不仅仅是创建一个新的答案。
- 我确实看到了Tom所面临的问题,因为ES6类实例的工作方式不同于"常规"对象。
- 另外,当我试图在ES6类的一个实例上运行它时,您的"可能的副本"中接受的答案中的第一段代码实际上提供了崩溃。
- 我认为这不是重复的,因为尽管ES6类实例是一个对象,但并非每个对象都是ES6类实例,因此另一个问题并没有解决这个问题。
- 它不是复制品。另一个问题是纯Object用作数据持有者。这是关于es6 classes和不丢失类类型信息的问题。它需要一个不同的解决方案。
- 进行第二次重新投票。类实例不一定与普通对象相同。
1
| let clone = Object.assign( Object.create( Object.getPrototypeOf(orig)), orig) |
我试了很多次,最后这对我很管用。
它还避免设置原型,因为他们说它会大大降低代码的速度。
这是一条单行线!
- 这不会复制静态方法,因为它们实际上不是可枚举的自身属性。
- @Lavalamp先生,您如何复制静态方法?
- 这将摧毁阵列!它将把所有数组转换为具有"0"、"1"的对象…钥匙。
- @怎么处理这个?
- @Keshaantonov您可以找到一个类型和数组方法的解决方案。我自己更喜欢手动克隆所有属性。
- 不要期望它克隆本身是对象的属性:jsbin.com/qeziwetexu/edit?控制台
- 静态方法不需要克隆!它们是类的一部分而不是实例
- 这将使orig成为新创建对象的原型。考虑使用Object.create(orig.__proto__)而不是Object.create(orig),或者如果重复这100次,您将以100+长的原型链结束。
- @Heimdell实际上已经做了Object.create(orig.getPrototypeOf()),相当于你的Object.create(orig.__proto__)。
1 2
| const clone = Object.assign( {}, instanceOfBlah );
Object.setPrototypeOf( clone, Blah.prototype ); |
注意object.assign的特性:它执行一个浅复制,不复制类方法。
如果您希望对副本进行深度复制或进行更多控制,那么可以使用lodash clone函数。
- 既然Object.create用指定的原型创建了新的对象,为什么不直接创建const clone = Object.assign(Object.create(instanceOfBlah), instanceOfBlah)。同时也将复制类方法。
- @但是Barbatus使用了错误的原型,Blah.prototype != instanceOfBlah。你应该使用Object.getPrototypeOf(instanceOfBlah)。
- @不,ES6类实例并不总是有原型。查看codepen.io/techniq/pen/qdzezm,它也可以与实例一起工作。
- @巴贝图斯对不起,什么?我不明白。所有的实例都有一个原型,这就是它们成为实例的原因。试一下Flori答案中的代码。
- @我认为这取决于巴别塔的形状或者其他什么。我现在正在实现一个反应式本机应用程序,没有继承属性的实例的原型在那里为空。也可以在这里看到developer.mozilla.org/en-us/docs/web/javascript/reference/…getprototypeof可能返回空值。
- @Barbatus,但从未用于从正常的class中用new实例化的对象。即便如此,你还是希望克隆人有相同的原型…
- @那么,Object.create(instance)和Object.create(Object.getPrototypeOf(instance))创建的对象原型有什么不同(假设它是为了克隆的)?
- @巴贝图斯是不是很明显他们是不同的?如果您使用该实例,然后克隆克隆克隆的克隆等,您将得到一个无限长的原型链,其中最后一个包括所有其他的。它们的行为将完全不同于仅使用原始相同原型的克隆。
- 埃多克斯1〔8〕怎么样?它不会进行深度克隆,但在大多数情况下都非常有效。