基于原型与基于类的继承 [英] prototype based vs. class based inheritance

查看:39
本文介绍了基于原型与基于类的继承的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 JavaScript 中,每个对象同时是一个实例和一个类.要进行继承,您可以使用任何对象实例作为原型.

In JavaScript, every object is at the same time an instance and a class. To do inheritance, you can use any object instance as a prototype.

在 Python、C++ 等中,有类和实例,它们是独立的概念.为了进行继承,您必须使用基类创建一个新类,然后可以使用该类生成派生实例.

In Python, C++, etc.. there are classes, and instances, as separate concepts. In order to do inheritance, you have to use the base class to create a new class, which can then be used to produce derived instances.

为什么 JavaScript 朝这个方向发展(基于原型的面向对象)?与传统的基于类的 OO 相比,基于原型的 OO 有哪些优点(和缺点)?

Why did JavaScript go in this direction (prototype-based object orientation)? what are the advantages (and disadvantages) of prototype-based OO with respect to traditional, class-based OO?

推荐答案

这里有大约一百个术语问题,主要是围绕某人(而不是你)试图让他们的想法听起来像最好的.

There are about a hundred terminology issues here, mostly built around someone (not you) trying to make their idea sound like The Best.

所有面向对象的语言都需要能够处理几个概念:

All object oriented languages need to be able to deal with several concepts:

  1. 数据的封装以及对数据的相关操作,也称为数据成员和成员函数,或数据和方法等.
  2. 继承,能够说这些对象与其他对象集一样,除了这些更改
  3. 多态性(多种形状"),其中对象自行决定要运行哪些方法,以便您可以依赖语言来正确路由您的请求.

现在,就比较而言:

首先是整个类"与原型"的问题.这个想法最初始于 Simula,其中使用基于类的方法,每个类表示一组共享相同状态空间(读取可能值")和相同操作的对象,从而形成一个等价类.如果你回顾一下 Smalltalk,因为你可以打开一个类并添加方法,这与你在 Javascript 中可以做的实际上是一样的.

First thing is the whole "class" vs "prototype" question. The idea originally began in Simula, where with a class-based method each class represented a set of objects that shared the same state space (read "possible values") and the same operations, thereby forming an equivalence class. If you look back at Smalltalk, since you can open a class and add methods, this is effectively the same as what you can do in Javascript.

后来的面向对象语言希望能够使用静态类型检查,因此我们在编译时获得了固定类集的概念.在开放班版本中,您有更多的灵活性;在较新的版本中,您可以在编译器中检查某些类型的正确性,否则需要进行测试.

Later OO languages wanted to be able to use static type checking, so we got the notion of a fixed class set at compile time. In the open-class version, you had more flexibility; in the newer version, you had the ability to check some kinds of correctness at the compiler that would otherwise have required testing.

在基于类"的语言中,复制发生在编译时.在原型语言中,操作存储在原型数据结构中,在运行时被复制和修改.但是,抽象地说,类仍然是共享相同状态空间和方法的所有对象的等价类.当您向原型添加方法时,您实际上是在创建新等价类的元素.

In a "class-based" language, that copying happens at compile time. In a prototype language, the operations are stored in the prototype data structure, which is copied and modified at run time. Abstractly, though, a class is still the equivalence class of all objects that share the same state space and methods. When you add a method to the prototype, you're effectively making an element of a new equivalence class.

现在,为什么要这样做?主要是因为它在运行时提供了一种简单、合乎逻辑、优雅的机制.现在,要创建一个新对象,创建一个新类,您只需执行深度复制,复制所有数据和原型数据结构.你或多或少免费获得继承和多态性:方法查找总是包括按名称查询方法实现的字典.

Now, why do that? primarily because it makes for a simple, logical, elegant mechanism at run time. now, to create a new object, or to create a new class, you simply have to perform a deep copy, copying all the data and the prototype data structure. You get inheritance and polymorphism more or less for free then: method lookup always consists of asking a dictionary for a method implementation by name.

最终出现在 Javascript/ECMA 脚本中的原因基本上是,当我们 10 年前开始使用它时,我们处理的计算机功能要弱得多,浏览器也不那么复杂.选择基于原型的方法意味着解释器可以非常简单,同时保留了面向对象的理想属性.

The reason that ended up in Javascript/ECMA script is basically that when we were getting started with this 10 years ago, we were dealing with much less powerful computers and much less sophisticated browsers. Choosing the prototype-based method meant the interpreter could be very simple while preserving the desirable properties of object orientation.

这篇关于基于原型与基于类的继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆