【问题标题】:The difference between a class-based language (like Java or Python) and a prototype-based language (like Javascript)? [duplicate]基于类的语言(如 Java 或 Python)和基于原型的语言(如 Javascript)之间的区别? [复制]
【发布时间】:2012-07-22 03:56:16
【问题描述】:

可能重复:
prototype based vs. class based inheritance

前几天在工作中提出了这个问题——像 Python 这样的基于类的语言和像 Javascript 这样的基于原型的语言有什么区别?除了不同的方法之外,这两种方式看起来都非常相似,我们努力寻找基于类的语言可以做而基于原型的语言不能做的事情,反之亦然。

谁能详细说明或详细说明它们的根本区别?

我没有在网上找到太多关于差异的信息,只是一些网站向您展示了如何实现一个与另一个(例如:Simulating classes with prototypes in JavaScript)

感谢任何启发!

【问题讨论】:

标签: javascript python class prototype


【解决方案1】:

查看this article。这是一篇详细讨论基于类和基于原型的语言之间差异的文章。

总结差异的表格副本:

基于类 (Java)

  • 类和实例是不同的实体。
  • 用类定义定义一个类;使用构造方法实例化一个类。
  • 使用 new 运算符创建单个对象。
  • 通过使用类定义来定义现有类的子类来构造对象层次结构。
  • 按照类链继承属性。
  • 类定义指定类的所有实例的所有属性。无法在运行时动态添加属性。

基于原型 (JavaScript)

  • 所有对象都是实例。
  • 使用构造函数定义和创建一组对象。
  • 一样。
  • 通过将对象分配为与构造函数关联的原型来构造对象层次结构。
  • 按照原型链继承属性。
  • 构造函数或原型指定一组初始属性。可以为单个对象或整个对象集动态添加或删除属性。

【讨论】:

  • 你真的可以复制表格。将文本格式化为像素数据从来都不是一个好主意。
  • 谢谢杰夫,很有帮助。但是 Python 与 Java 的不同之处在于类也是一等对象,而且您还可以在运行时动态添加属性——那么这与 Javascript 的原型方法有何不同?
  • @Bergi - SO 甚至不允许表格标记。我个人更喜欢这些图像,而不是试图用文本模拟表格。
  • 当然,在更“纯”的面向对象语言中,类本身就是对象。例如,Python 有“类”,但您可以动态分配属性(嗯,除非它是内置或扩展类或正在使用 __slots__),并且 Python 类在大多数情况下本身就是类的实例type。因此,可以这么说,有一点范围。
  • @Ben - 我从未使用过 Python,但您也可以为 Javascript 对象动态添加属性。
【解决方案2】:

您似乎熟悉实际的语言,所以您知道它们之间的区别,对吧?我想您是在更深层次,也许是更“哲学”的层面上询问差异。

基于类的语言倾向于自上而下地工作,从一般到特殊。经典的例子是你定义一个“Vehicle”类,然后是“Car”、“Train”等子类。

一种基于原型的语言倾向于从特定的开始,实际上是从特定的实例开始并对其进行修改。

我喜欢这个:http://steve-yegge.blogspot.ie/2008/10/universal-design-pattern.html

归根结底,这不是您是否可以在 JS 中进行继承,或者您是否可以用一种语言做某事而另一种语言不能做的问题。他们解决问题的方式有很大的不同。对于一个特定的问题,一个能够充分利用语言特性的良好惯用解决方案在基于原型的语言中可能与基于类的语言中的解决方案完全不同。

【讨论】:

  • 在原型语言中,您可以从特定开始,然后进行概括,但您也可以从一般开始,然后再进行具体化。在基于类的语言中,灵活性较低 [然而,Python、Ruby 和 Smalltalk 都允许它们的类通过 getattr、method_missing、类装饰器、开放类、更改类型等东西具有原型语言的灵活性对象,向对象添加方法,从类中删除方法等...]
【解决方案3】:

MDN 的 JavaScript 指南有一些好处,看看:https://developer.mozilla.org/en/JavaScript/Guide/Details_of_the_Object_Model

【讨论】:

    【解决方案4】:

    嗯,它们(通常)都已完成。 :)

    类是关于强制封装的,以牺牲一些(或很多)运行时可扩展性为代价。原型鼓励封装并允许几乎无限的运行时扩展。

    说真的,基于原型的 OO 使得从对象动态扩展/派生变得非常容易——有些人会说非常容易。因此,原型语言不容易与静态类型共存。因此,如果您喜欢编译器捕获类型错误的方式,那么您几乎肯定会排除基于原型的语言。

    这里实际上有一个很好的讨论:http://yehudakatz.com/2011/08/12/understanding-prototypes-in-javascript/ 虽然还有其他的和我一样好我喜欢那个。

    【讨论】:

    • 我不认为继承模型和类型系统是相互依赖的。
    猜你喜欢
    • 2011-10-20
    • 1970-01-01
    • 2015-01-20
    • 2018-05-21
    • 2013-03-04
    • 2012-08-25
    • 2023-03-11
    • 2014-09-19
    • 1970-01-01
    相关资源
    最近更新 更多