关于克隆JS
对象有很多问题,但似乎这个问题不存在。
我有一个函数A
扩展函数B
,如下所示:
function A () {}
function B () {}
B.prototype = new A()
然后我有一个b
类型的对象B
。我想克隆它,并保留其类型,以便b
的克隆类型为B
。
以下是我克隆它的方式:(jsfiddle)
function A() {}
function B() {}
B.prototype = new A()
var b = new B()
var bPrime = new b.constructor()
$("#a").text(b instanceof A)
$("#b").text(b instanceof B)
$("#aPrime").text(bPrime instanceof A)
$("#bPrime").text(bPrime instanceof B)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
b is of type A: <span id="a"></span>
<br>b is of type B: <span id="b"></span>
<br>bPrime is of type A: <span id="aPrime"></span>
<br>bPrime is of type B: <span id="bPrime"></span>
在我的示例中,克隆的类型为A
。我怎么能得到键入B
的b的克隆?
答案 0 :(得分:1)
您需要将B.prototype.constructor
设置回B
。实际上,它继承自A
,构造函数为A
。因此,当您执行new b.constructor()
时,您实际上正在获得new A()
。
function A() {}
function B() {}
B.prototype = new A()
B.prototype.constructor = B
var b = new B()
var bPrime = new b.constructor()
$("#a").text(b instanceof A)
$("#b").text(b instanceof B)
$("#aPrime").text(bPrime instanceof A)
$("#bPrime").text(bPrime instanceof B)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
b is of type A: <span id="a"></span>
<br>b is of type B: <span id="b"></span>
<br>bPrime is of type A: <span id="aPrime"></span>
<br>bPrime is of type B: <span id="bPrime"></span>
答案 1 :(得分:1)
Object.create()方法使用指定的原型对象和属性创建一个新对象。
function A() {}
function B() {}
B.prototype = new A()
var b = new B();
var c = Object.create(b);
console.log(c instanceof B); // -> true
答案 2 :(得分:0)
克隆是一个非常含糊的词。如果你想创建一个没有引用任何与源对象相关的东西的全新对象,那么如果你事先不知道有关该对象的东西就很难做到,尽管你可以根据需要做一些基于原型的东西(不是特别的)可取)。在ES6中,由于对象/构造函数/原型可能拥有私有符号,WeakMaps等,因此在这种“逐个属性”的意义上可靠地深度克隆事物几乎是不可能的。
但是,您可以使用Object.create(b)创建一个新对象,将b作为自己的原型。如果你替换
var bPrime = new b.constructor()
与
var bPrime = Object.create(b)
然后你得到四个true
。但是,由于b在这里充当bPrime的原型,b的更改将反映在bPrime中,除非bPrime提供了自己的定义来覆盖这些内容。这可能不适用于克隆目的,因为:
b.prop; // undefined
bPrime.prop; // undefined
b.prop = 7;
bPrime.prop; // 7!
但我们可以做一些改进:
var bPrime = Object.create(Object.getPrototypeOf(b));
现在你得到四个真相,但对b的进一步修改将不会反映在bPrime上。