基于原型的面向对象与基于类的面向对象相比有哪些优势?

IT技术 javascript oop class programming-languages selflanguage
2021-02-27 15:41:59

为什么基于类的 OO 比基于原型的 OO 如此受欢迎?他们在学校教后者吗?尽管 Javascript 是基于原型的,但大多数人主要是在功能上使用它,或者通过试图模拟基于类的系统的框架来使用它。

我知道 Sun 对Self进行了一些研究- 是否还有其他关于基于原型的 oo 的知识来源?最好是可以自学的东西。

我找到了一本书,其中包含已发表的论文:Prototype-Based Programming: Concepts, Languages and Applications

有人读过吗?

——

所以我为给我最多的答案提供了赏金。尽管如此,我还是不太满意。我希望听到更多技术性的答案。也许我没有很好地解释自己。

6个回答

原型继承的优势在于它可能允许以一种直接的方式进行花哨的元编程,因为原型链很容易操作。这是一个相当学术的优势,因为元编程在 99% 的情况下都是错误的答案。例如,您可以拥有一个带有特殊 DSL 的 Javascript Key-Value Observer 样式数据操作层,可以在离线时通过原型交换在本地 SQLite 支持和在线时基于 REST 的服务器存储之间透明地切换。我不确定这是最好的方法,但这是我这么晚能想到的最好方法。这不是你通常想要在项目代码中做的那种事情,因为一旦你开始在多个层上运行这种间接性,调试就会很糟糕,但是当你将它保存在库中时,这也不错。

另一个不太有用的优点是它允许您设计自己的类系统。我说不太有用,因为或多或少所有 javascript 库都有自己稍微不兼容的方法来将“类”放在一起。

有很多人将继承模型与该模型中实现的语言混合在一起。javascript 是动态的、弱类型的,因此难以使用这一事实与它是一种原型语言无关。

使用 Javascript 的实现,您无法切换原型对象。它只是将实际原型对象本身从 SQLite 更改为 REST 吗?
2021-04-24 15:41:59
en.wikipedia.org/wiki/Weak_typing -> 绝对弱类型。它也在描述中:en.wikipedia.org/wiki/JavaScript我认为混淆了您可以同时拥有动态和弱类型语言的事实,这就是 JS。它绝不是强类型的。
2021-04-29 15:41:59
是的。如果您通过 save() 函数完成所有技巧,您可以将 SQLite save() 替换为 REST save(): >>> rest_save = function(){return "REST"} >>> sql_save = function (){return "SQL"} >>> Storage = function(){/*初始化等*/} >>> Storage.prototype.save = rest_save >>> my_obj = new Storage() >>> my_obj.save( ) "REST" >>> Storage.prototype.save = sql_save function() >>> my_obj.save() "SQL" 通过使用所有主要 js 库中可用的更新/合并函数,可以轻松地为整个对象完成此操作。不是“真正的”交换,但它可能很有用。
2021-05-03 15:41:59
JavaScript 不是弱类型,而是强类型。你很弱地与动态混合...
2021-05-03 15:41:59
我讨厌这些评论中缺少换行符。
2021-05-07 15:41:59

如果您正在寻找某人指出每个人的优点/缺点作为其受欢迎程度的解释,我认为您会陷入一种谬论中,这种谬论出于某种原因在技术中非常普遍 - 这种流行与某些有关质量的绝对衡量标准。

事实要平淡得多——基于类的 OO 很受欢迎,因为 Java 使用经典的 OO,而 Sun 花费了数百万美元和很长时间来建立 Java 的普及——确保人们知道它在公司中成功使用,在大学中广泛教授,以及高中 AP 考试。

原型/经典面向对象只是组织想法的不同方式。您可以使用本机不支持它的语言(想到PythonJava,而另一方面是JavaScript来实现其中任何一个

在经典 OO 中,您为对象定义类的抽象层次结构,然后实际使用这些类的实例。在原型继承中,您创建对象实例的层次结构。尽管我认为这在两个阵营中都可能有点异端,但我看不出有什么理由不能将两者混为一谈……

抱歉,我所说的经典是指基于类的。
2021-05-01 15:41:59
@Orclev:那完全不相关。而且不真实。例如,在 Ecmascript5 中,您将能够“冻结”对象,保证它们以后不会被修改。@egaga:我只有作为罗格斯大学本科生的经验,没有人在那里教授任何接近原型继承的东西(并且有充分的理由 - 在大学课堂上有更难教的东西,可以(并且应该)学习次要语言范式己方)。
2021-05-01 15:41:59
我想知道经典的 OO 是什么?它是像 Smalltalk & CLOS(类似于原型)还是 Simula(类似于基于 Java 的对象)?哪个模型是真正经典的?
2021-05-11 15:41:59
我只是好奇是否有什么东西可以让基于原型的面向对象对开发人员更具挑战性。主要只是想知道在创建复杂的软件时会出现什么样的问题。我并不是说流行是基于范式的质量,但这可能是出于某种原因。
2021-05-20 15:41:59
基于原型是危险的,因为它很强大,你可以随时修改任何东西,它会影响一切。这是反对全局变量的旧论点,你永远不知道谁掌握了什么。正因为如此,你必须非常小心,不要踩到任何人的脚趾,但它允许你做一些在其他语言中非常困难或不可能的事情(可以说是有充分理由的)。
2021-05-21 15:41:59

我不知props体的原因,但这是我的原因

我认为这个争论与动态与静态相同,类是对象的静态定义,可以很容易地使用它来了解对对象的期望,它还有助于使语言获得适当的智能支持和文档,因为您可以很容易地知道对象中的不同成员和方法是什么,另一件事是具有在类中声明私有成员的能力的不同范式,这些成员没有显示在对象上,这不能在原型中完成范例。

原型范式很好,但是它缺乏提供有关对象中方法和成员的信息的能力,这使得工具更加困难,并且对于动态类型编程也更有意义。

实际上,可以编写一种静态类型的基于原型的语言
2021-04-25 15:41:59
同意。但是请注意,虽然 Javascript 本身支持基于原型的继承,但使用闭包实现一些 OO 功能并不难。例如,您可以很容易地获得对私有方法和变量的真正保护。Dustin Diaz 的关于这个主题的书是一流的:“Pro Javascript Design Patterns”(jsdesignpatterns.com) 重点表明为这种动态语言提供工具是很困难的。使用像 Javascript 这样灵活的语言,您的开发环境很难知道您正在使用什么继承模式。
2021-05-02 15:41:59
我不同意“基于原型的缺乏提供有关对象中的方法和成员的信息的能力”。与基于类相反,它很容易在运行时枚举。
2021-05-06 15:41:59
就在。静态语言需要类,以便编译器知道期望/禁止什么。动态语言不需要它们,所以使用原型更方便。
2021-05-08 15:41:59
此外,在基于原型的语言中,您可以将代码解释为数据,将数据解释为代码。这是相对于基于类的静态语言的一大优势。这就是为什么大多数 Javascript 程序都反对在提议的 ECMA 4 标准中引入静态类的原因。
2021-05-21 15:41:59

这个问题让我很感兴趣,所以我回去阅读了一些关于这个概念的原始论文。它似乎始于 1980 年代中期的 Smalltalk 世界,但最终成为Self的创始人之一很久以后 Javascript 也采用了它。

论文中提出的论点是它更容易学习。除了学习之外,真的没有任何技术上的好处。这些论文都解释了它如何与基于类的语言一样具有表现力,但更容易学习。人们自然地以具体的方式而不是抽象的方式思考事物。我们想到的是我们在动物园看到的大象,而不是一般的“大象”。当我们看到其他大象时,我们将它们归类为与第一个不同。基于原型的语言促进了这种思考。将其视为差分编程。

这是在语言中使用它的充分理由吗?也许。在这个想法开始渗透的 25 年里,我认为像基于类的面向对象这样的抽象概念对于大多数人来说并不太难学习。另一方面,也许需要一种更容易的蓝领编程语言(如 Javascript),这可能是实现这一目标的一种方式。

如果有兴趣,你可以从这篇关于自我的论文开始

很高兴看到这个问题引起了一些兴趣!谢谢 :)
2021-05-11 15:41:59