在JavaScript中使用原型是否具有任何现实世界的优势?

时间:2010-08-29 00:11:07

标签: javascript inheritance function prototype

我刚刚完成了Doug Crockford的The Good Parts,他提供了三种不同的继承方式:经典模型的emulation,基于原型的继承和功能继承。

在后者中,他创造了一个功能,一个各种各样的工厂,它们使用在其他物体上构建的所需方法来增加对象。类似的东西:

var dog = function(params) {
    // animal is the 'super class' created
    // the same way as the dog, and defines some
    // common methods
    var that = animal(params);
    that.sound = 'bark';
    that.name = function () {};
    return that;
}

由于以这种方式创建的所有对象都将引用相同的函数,因此内存占用量将远低于使用new运算符时的内存占用率。问题是,原型方法在这种情况下会提供任何优势吗?换句话说,对象原型是否以某种方式“更接近金属”提供了性能优势,或者它们只是一种便利机制?

编辑:我会简化问题。原型与通过对象组合进行仿真。只要您不要求所有对象实例都使用新方法进行更新,这只是原型所提供的便利,那么首先使用原型是否有任何优势?

我通过电子邮件向Doug Crockford发送电子邮件,他说:

  

[使用上面的功能方法与原型]并没有那么多的记忆。如果你有大量的对象和大量的方法,那么你可能想要成为原型。但是现在记忆很丰富,只有极端的应用才能注意到它。

     

原型可以使用更少的内存,但可以稍微慢一些,特别是如果链很长。但一般来说,这并不明显。

3 个答案:

答案 0 :(得分:1)

实例都引用相同的函数等。每次调用“dog”都会创建一个新的“name”函数实例。

答案 1 :(得分:1)

对此有很多意见,而Crockford不一定是正确的。

修改原型的主要缺点是它可能使得使用其他JavaScript库变得更加困难。

但Crockford创建类​​的功能方式的缺点是你不能轻易地将方法或字段添加到类型的所有实例中。

有关Crockford关于javascript中的类和继承的观点的一些批评意见,请参阅Closure:The Definitive Guide: http://my.safaribooksonline.com/9781449381882/I_sect1_d1e29990#X2ludGVybmFsX0ZsYXNoUmVhZGVyP3htbGlkPTk3ODE0NDkzODE4ODIvNTE0

像Dojo,Google Closure Library(它似乎复制Dojo的风格)这样的库,也许YUI有自己的类系统似乎是一个很好的中间地带。我喜欢Dojo的系统可能是最好的,因为它支持Mixins,不像Closure。其他一些与gui工具包无关的类系统包括Joose,JS.Class和JavascriptMVC(如果使用jquery,请查看最后一个esp。)。

答案 2 :(得分:0)

我曾经创建过一个由一个类支持的GUI,该类没有对所需信息提供基于事件的支持。 GUI实现了一个通用接口,其中传递了该类的实例,因此我不能从该类继承,所以我做了类似于基于原型的继承,我创建了一个包装该代理对象的代理对象当它传递给我的GUI时该类的实例。代理拦截变异状态的感兴趣的方法,并将它们报告为事件。然后整个GUI围绕着使用这些事件。

在这种情况下,创建一个包装传入实例并重现相同接口的单独类会很烦人。由于创建了所有冗余函数,这实际上会导致更多开销(并不重要)。

根本没有其他可行的选择。唯一的选择是:

  1. 创建一个对象,该对象组成传递给GUI的对象(如上所述)。然后,该对象将重现原始类中的每个函数以实现相同的接口,并添加事件,因此它实际上与代理对象方式相同。
  2. 在其传入的对象中具有GUI跟踪状态变异。这可能是痛苦而且容易出错。