Class based inheritance is a way of extending the defining features (such as type, methods, and variables) of one class to another. The class whose functionality is extended is known as the parent class. The class which receives the features is known as the child class.
The Prototypal Inheritance is a feature in javascript used to add methods and properties in objects. It is a method by which an object can inherit the properties and methods of another object. Traditionally, in order to get and set the [[Prototype]] of an object, we use Object.
Prototype-based programming is a style of object-oriented programming in which classes are not explicitly defined, but rather derived by adding properties and methods to an instance of another class or, less frequently, adding them to an empty object.
Classical inheritance is limited to classes inheriting from other classes. However prototypal inheritance includes not only prototypes inheriting from other prototypes but also objects inheriting from prototypes.
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:
Now, as far as comparison:
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.
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.
A comparison, which is slightly biased towards the prototypes based approach, can be found in the paper Self: The Power of Simplicity. The paper makes the following arguments in favor of prototypes:
Creation by copying. Creating new objects from prototypes is accomplished by a simple operation, copying, with a simple biological metaphor, cloning. Creating new objects from classes is accomplished by instantiation, which includes the interpretation of format information in a class. Instantiation is similar to building a house from a plan. Copying appeals to us as a simpler metaphor than instantiation.
Examples of preexisting modules. Prototypes are more concrete than classes because they are examples of objects rather than descriptions of format and initialization. These examples may help users to reuse modules by making them easier to understand. A prototype-based system allows the user to examine a typical representative rather than requiring him to make sense out of its description.
Support for one-of-a-kind objects. Self provides a framework that can easily include one-of-a-kind objects with their own behavior. Since each object has named slots, and slots can hold state or behavior, any object can have unique slots or behavior. Class-based systems are designed for situations where there are many objects with the same behavior. There is no linguistic support for an object to possess its own unique behavior, and it is awkward to create a class that is guaranteed to have only one instance [think singleton pattern]. Self suffers from neither of these disadvantages. Any object can be customized with its own behavior. A unique object can hold the unique behavior, and a separate "instance" is not needed.
Elimination of meta-regress. No object in a class-based system can be self-sufficient; another object (its class) is needed to express its structure and behavior. This leads to a conceptually infinite meta-regress: a
point
is an instance of classPoint
, which is an instance of metaclassPoint
, which is an instance of metametaclassPoint
, ad infinitum. On the other hand, in prototype-based systems an object can include its own behavior; no other object is needed to breathe life into it. Prototypes eliminate meta-regress.
Self is probably the first language to implement prototypes (it also pioneered other interesting technologies like JIT, which later made its way into the JVM), so reading the other Self papers should also be instructive.
You should check out a great book on JavaScript by Douglas Crockford. It provides a very good explanation of some of the design decisions taken by JavaScript creators.
One of the important design aspects of JavaScript is its prototypal inheritance system. Objects are first class citizens in JavaScript, so much that regular functions are also implemented as objects ('Function' object to be precise). In my opinion, when it was originally designed to run inside a browser, it was meant to be used to create lots of singleton objects. In browser DOM, you find that window, document etc all singleton objects. Also, JavaScript is loosely typed dynamic language (as opposed to say Python which is strongly typed, dynamic language), as a result, a concept of object extension was implemented through the use of 'prototype' property.
So I think there are some pros for prototype-based OO as implemented in JavaScript:
Here are some of the cons of prototypal OO:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With