重新评估的匿名构造函数对原始实例化对象的重新评估匿名构造函数上的原型结合



这更像是一个理论问题,而不是一个方法问题。我正在研究一个项目,在该项目中,对象可以"区分"为几种不同类型,因此我决定探索JavaScript的一些动态功能,但是有一件事让我真正感到困惑:

OriginalConstructor = function() {this.value = 42;}
originalInstance = new OriginalConstructor();
ModifiedConstructor = eval(originalInstance.constructor);
ModifiedConstructor.prototype.addedFunction = function(x) {return this.value + x;}
modifiedInstance = new ModifiedConstructor();
document.write("modified: " + modifiedInstance.addedFunction(10));
document.write("<br>original: " + originalInstance.addedFunction(20));

即使ModifiedConstructor是通过eval()复制的,为什么addedFunction绑定到originalInstance?当然,这两个构造函数不能具有相同的参考,它们可以吗?

是否有一种方法可以修改对象(或将来的实例)而不影响已经从同一构造函数实例化的其他对象?我知道还有其他方法可以解决此问题,但是我想更深入地了解JavaScript。感谢您提供的任何见解。

@felix kling:感谢您的快速,清晰和完整的答案。由于某种原因,我认为构造函数属性是可以通过eval()解析的字符串,所以现在我明白了为什么这不起作用。我仍然不完全了解原型的遗传,但至少现在我知道我需要学习什么。谢谢!

编辑:我现在明白了。如果您来自古典OOP的背景,原型的继承似乎很奇怪,但是从概念上讲,它更简单,更容易理解,并且实际上在某些方面更强大。如果您想了解有关JavaScript的原型继承的更多信息,我强烈推荐这些文章:

http://javascript.crockford.com/prototypal.html

http://www.laktek.com/2011/02/02/understanding-prototypical-inheritance-inheritance-in-javascript/

http://blog.vjeux.com/2011/javascript/how-prototypal-inheritance-really-works.html

http://howtonode.org/prototypical-inheritance

另外,如果您需要这种灵活性,则可能需要考虑使用"实体系统",该系统将提供多种优势,以替代复杂的继承层次结构。关于实体系统的大多数文章都集中在游戏开发上,但是我认为这种体系结构也对其他应用程序也很有用。对于OOP程序员来说,这是一个非常陌生的概念,因此请搁置您对OOP的了解,并在关系数据库设计方面进行更多思考。检查一下:

http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/

http://t-machine.org/index.php/2007/09/03/entity-systems-are-thare-the-the-future-of-mmog-development-prvevement-prvevelomp-part-1/

ModifiedConstructor 不是 OriginalConstructor的副本,它是一个且相同的功能。

eval的算法中的第一个指令是:

如果类型( x )不是字符串,请返回 x

即。您只需收回您的传递。OriginalConstructor === ModifiedConstructor产生true

是否有一种方法可以修改对象(或将来的实例),而不会影响已经从同一构造函数实例化的其他对象?

您可以通过原型继承:

ModifiedConstructor = function() {
    OriginalConstructor.apply(this, arguments);
};
ModifiedConstructor.prototype = Object.create(OriginalConstructor.prototype);
ModifiedConstructor.prototype.constructor = ModifiedConstructor;

现在,您可以将功能添加到ModifiedConstructor.prototype,而不会影响OriginalConstructor创建的实例。

如果您只想防止已经创建的实例扩展,则可以覆盖OriginalConstructor.prototype,但不是一个干净的解决方案,也会破坏现有实例的instanceOf

相关内容

最新更新