为什么在javascript中使用基于类的OOP样式继承?

时间:2009-05-04 20:53:39

标签: javascript oop inheritance prototypal-inheritance

如果我不完全错误,javascript中的每个框架/库/方法都会模仿基于类的OOP样式继承。原因似乎是人们认为基于类的OOP继承更容易理解并且大多数程序员都知道OOP。

根据我的经验,我没有找到任何一种观点的证据。我认为javascript原型继承很好(我怀疑强制另一种语言的有用性而不是它构建的语言)。我遇到的大多数开发人员在经典OOP中都没有那么好。那么选择经典OOP样式继承而不是原型继承的原因是什么呢?

8 个答案:

答案 0 :(得分:6)

我认为答案在你的问题中 - 大多数程序员对基于类的OOP比基于原型的更为熟悉。

事实上,我甚至说大多数人都不相信没有课程就可以拥有对象。

答案 1 :(得分:6)

请注意,即使您正在争论基于原型的OOP,您也称之为'原型',而基于类的OOP只是'OOP'。所以,你自己也会受到这种偏见的困扰,认为OOP =>类,原型=>别的什么。

并且由于大多数人认为OOP是正确的方式,无论问题如何,原型必须低劣。

所以,回答你的问题,有两个因素:

  1. 一个错误的定义:“OOP => classes”
    • 宣传:“它必须是OOP,否则你就不值得”
  2. 因为你仍然受到第一个的限制,你试着解释原型是第二个的例外。更容易纠正它们:

    1. 有很多方法可以做对象,类只是静态语言最简单的方法。大多数人都被教导用静态语言编程,他们中的大多数都尝试使用任何语言,就像他们学到的第一语言一样。

      • 有很多方法可以构建一个编程解决方案,OOP在某些方面很棒而在其他方面很糟糕。

答案 2 :(得分:4)

我觉得你好像已经知道了你问题的答案,因为当你说

时你说了一部分
  

这个原因似乎是人   基于思维类的OOP继承   更容易理解和那样   大多数程序员都知道OOP。

对于解决问题,这两种范式都不比另一种范式更正确。我认为主要原因是这些天每个人都通过Java教授OOP。因此,当人们遇到OOP时,他们会想“哦班级”,因为这是他们所熟悉的。每当他们想要解决问题时,他们很可能会使用他们所知道的东西。

我还要说程序员使用他不熟悉的范例没有任何好处。我们大多数人必须使用javascript进行客户端Web开发,并在服务器上使用基于类的OOP语言。每当我不得不查看应用程序的javascript端时,我个人不希望OOP阻抗不匹配。

在某种程度上,每个人都试图在javascript中实现基于类的OOP这一事实是一个教育问题。在另一个层面上,这是一个心理上的。

答案 3 :(得分:3)

很长一段时间以来,我认为基于原型的OOP是基于类的OOP的弱,坏和错版本。然后,在我的脑海中泄漏了大量的信息之后,我现在以更抽象的方式理解OOP,并且发现两种方式都是可接受的。

答案 4 :(得分:3)

  

那么选择经典OOP样式继承而不是原型继承的原因是什么?   实际上,我认为某些框架是“某种”组合方法。以Parasitic Combination Inheritance模式为例。这就是YAHOO.lang.extend正在做的事情。

它使用原型继承和辅助函数来继承原型和构造函数窃取。哇,这听起来很复杂......好吧是 - 这是我的实现和测试,例如:

// Prototypal Inheritance
Object.prototype.inherit = function(p) {
    NewObj = function(){};
    NewObj.prototype = p;
    return new NewObj(); 
};

// Paraphrasing of Nicholas Zakas's Prototype Inheritance helper
function inheritPrototype(subType, superType) {
    var prototype = Object.inherit(superType.prototype);
    prototype.constructor = subType;
    subType.prototype = prototype;
};
function SubType(name, age) {
    Parent.call(this, name);
    this.age = age;    
};
inheritPrototype(SubType, Parent);  
SubType.prototype.getAge = function() {
    return this.age;
};

我对此代码进行了测试:

   describe 'Parisitic Combination Inheritance'
 it 'should use inheritPrototype (to call parent constructor once) and still work as expected'
     sub = new SubType("Nicholas Zakas", 29)
     sub.toString().should.match /.*Nicholas Zakas/
     sub.getAge().should.eql 29
     charlie = new SubType("Charlie Brown", 69)
     charlie.arr.should.eql([1,2,3])
     charlie.arr.push(999)
     charlie.arr.should.eql([1,2,3,999])
     sub.arr.should.eql([1,2,3]) 
     sub.should.be_an_instance_of SubType
     charlie.should.be_an_instance_of SubType
     (sub instanceof SubType).should.eql true 
     (sub instanceof Parent).should.eql true 
 end
    end

当然,如果你关注我的文字,你会看到:Nicholas Zakas,我得到的那个人;)这个人的大赢家:instanceof工作(有些人说很多,我有点同意) ;实例不会像数组这样的引用类型共享状态(一个biggie!);父构造函数只调用一次(一个biggie!)。

顺便说一下,我在这里有大多数流行的继承模式的例子:My TDD JS Examples

答案 5 :(得分:1)

我认为语言本身会引导人们进入经典思维模式,选择“新”作为关键词,并在语言规范中引入“构造函数”等概念。在某种程度上,这是一种限制 - 想象一下心态的变化,相反,我们有一个克隆关键字,以及特征ala SELF的概念。

答案 6 :(得分:0)

当我编写我的第一个脚本时,使用这么简单的语言很酷很方便。 但是今天你不仅想要切换按钮颜色,而是想用JavaScript构建复杂的应用程序。其他人可能喜欢使用您的热门应用程序,并希望看到社区提供插件。

现在,使用OOP更容易实现 - 特别是因为许多程序员熟悉OOP概念。

答案 7 :(得分:0)

一个原因可能是您的服务器端可能是OO(ASP.NET,Java等),因此在客户端上使用相同的范例更容易思考。不一定更好,但更容易。