Javascript伪古典继承与功能继承

时间:2011-11-23 16:25:07

标签: javascript oop prototypal-inheritance

我最近一直在玩javascript,我正试图掌握伪古典继承的优点(正如Crockford使用对象的prototype属性所描述的那样)。 Crockford说他很少使用它并且更喜欢功能性方法,即创建一个增强对象的功能,如

var obj = function() {
  var self = {};
  self.method = function() {
  };
  return self;
}

我更喜欢这种方法,它更容易理解并且看起来更灵活。

但是,我看到许多仍然使用prototype属性的代码,包括像jQuery这样的流行框架。我想知道有什么好处?我对使用原型属性的理解是,它使我们能够通过遍历原型链来询问对象是否是特定类型。然而,作为一种动态语言,问对象是否可以做某事而不是它是什么不是更好?

5 个答案:

答案 0 :(得分:4)

我看到使用prototype代替此方法的优势是效率。以“经典”方式完成的对象的每个实例(使用prototype)将共享方法,而功能方法将为每个方法创建新方法。

答案 1 :(得分:3)

是的,它通常是“更好地询问一个物体是否可以做某事,而不是它是什么”(有时被称为“鸭子打字”,因为如果一个物体看起来像一只鸭子而且像鸭子一样嘎嘎叫...... )。但有时候,你真的想知道某个对象是否是一个数组而不仅仅是一个具有长度属性的对象。

然而,在创建大量对象时,原型或伪​​经典方法也具有性能优势。

使用伪经典方法覆盖方法也更容易。请参阅https://stackoverflow.com/q/4508498/9897上的说明。

答案 2 :(得分:1)

我认为两个相对重要的方面是速度和RAM使用率。如果你的构造函数创建了所有这些方法的新实例,这将既减慢代码速度又可能导致其外部作用域(构造函数)被保留,从而导致更多的RAM使用。

证明:http://jsperf.com/in-constr-vs-on-proto - 至少在chrome中,在构造函数中执行此操作的速度要慢89%。

答案 3 :(得分:1)

人们使用原型,因为它是一个继承构造。

如果你想从另一个对象继承方法和属性,那么你来使用原型。

var Proto = {
  method: function () { }
}

var obj = function() {
  return Object.create(Proto);
}

答案 4 :(得分:0)

使用委托原型和使用伪经典继承之间存在重要区别。原型继承依赖于为委托设置原型,在Object.create()之前,唯一的方法是设置构造函数的prototype属性。现在我们有Object.create(),我使用它而不是构造函数,用于相同的目的。

使用委托原型的主要原因是通过在委托给该原型的所有实例之间共享相同的内存来节省资源。

您列出的示例称为工厂函数,它经常与Object.create()结合使用,以实现方便的原型继承。