问题:
如何从类的实例生成类的新实例?
我发现了什么:
考虑下一个类及其实例:
// Create a new class
var Foo = function Foo () {
console.log('New instance of FOO!');
};
Foo.prototype.generate = function(first_argument) {
this.arr = [1,2,3,4,5];
};
var foo = new Foo();
foo.generate();
console.log(foo.arr); // [1,2,3,4,5]
请注意,foo
是 Foo
的实例,我将在示例中使用该实例。
对象创建
使用 Object.create 我可以生成 foo 实例的新副本,但它们将共享状态数据:
var bar = Object.create(foo);
console.log(bar.arr); // [1,2,3,4,5]
bar.arr.push(6);
console.log(foo.arr); // [1,2,3,4,5,6]
console.log(bar.arr); // [1,2,3,4,5,6]
如果某些逻辑在构造函数中,则不会调用它。
原型(prototype)继承
这类似于对象创建,但它调用构造函数。它仍然存在相同的状态数据问题:
var Bar = function () {
foo.constructor.call(this);
};
Bar.prototype = foo;
var bar = new Bar();
console.log(bar.arr); // [1,2,3,4,5]
bar.arr.push(6);
console.log(foo.arr); // [1,2,3,4,5,6]
console.log(bar.arr); // [1,2,3,4,5,6]
Firefox 原型(prototype)
这是我真正想做的事的一个例子,但它只适用于 Firefox:
// Create Bar class from foo
var Bar = foo.constructor;
Bar.prototype = foo.__proto__; // Firefox only
这里我有类 Bar,它是类 Foo 的副本,我可以生成新实例。
var bar = new Bar();
console.log(bar.arr); // undefined
bar.generate();
console.log(bar.arr); // [1,2,3,4,5]
是否有任何其他方法可以实现在所有浏览器中都适用的相同目标?
最佳答案
1) proto 由于显而易见的原因必须避免,您有 Object.getPrototypeOf 以标准方式读取对象的原型(prototype)。
2)你没有构造函数来完成所有的工作,而是有一种带有生成的初始化方法。
因此,在构造函数的末尾调用 this.generate 会更有意义。
这就是原型(prototype)继承不起作用的原因:构造函数不起作用。
同样的想法,你不能责怪 Object.create 因为它既不构造函数,也不在你的例子中生成,所以你基本上构建了一个具有相同原型(prototype)的对象,仅此而已。
如果您确实将对 this.generate 的调用添加到构造函数中,也许最简单的方法是使用 foo 的构造函数属性来构建一个新对象:
var bar = new foo.constructor();
这会给你一个全新的项目。
所以回答你的问题:是的,还有另一种方法,使用对象实例的构造函数属性来构建一个新项目。
但是没有继承方案能够“猜测”完整的初始化应该用这样那样的方法来执行。初始化是构造函数的工作。例如,我们可能会想象您在构造函数中构建了一个新数组 this.arr = [];
并且 generate() 将 push() 该数组中的项目,这将是一种有效的方法。但是您必须避免通过方法添加属性,既为了优化又为了清晰:在构造函数中设置所有实例属性,并可能在原型(prototype)上设置共享属性,并且仅在方法中使用这些属性。
关于javascript - 如何在没有类的情况下生成对象的新实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17591203/