After reading about both, I just have curiosity, how programming community uses this? In what situation which?
3 Answers
There are lots of problems with classical inheritance that don't exist with prototypal inheritance, such as:
Classical Inheritance
Tight coupling. Inheritance is the tightest coupling available in OO design. Descendant classes have an intimate knowledge of their ancestor classes.
Inflexible hierarchies (aka duplication by necessity). Single parent hierarchies are rarely capable of describing all possible use cases. Eventually, all hierarchies are "wrong" for new uses -- a problem that necessitates code duplication.
Multiple inheritance is complicated. It's often desirable to inherit from more than one parent. That process is inordinately complex and its implementation is inconsistent with the process for single inheritance, which makes it harder to read and understand.
Brittle architecture. Because of tight coupling, it's often difficult to refactor a class with the "wrong" design, because much existing functionality depends on the existing design.
The Gorilla / Banana problem. Often there are parts of the parent that you don't want to inherit. Subclassing allows you to override properties from the parent, but it doesn't allow you to select which properties you want to inherit.
Prototypal Inheritance
To understand how prototypal inheritance solves these problems, you should first understand that there are two different types of prototypal inheritance. JavaScript supports both:
Delegation. If a property is not found on an instance, it is searched for on the instance's prototype. This enables you to share methods among many instances, giving you the flyweight pattern for free.
Concatenation. The ability to dynamically add properties to an object enables you to freely copy any properties from one object to another, all together, or selectively.
You can combine both forms of prototypal inheritance to achieve a very flexible system of code reuse. So flexible in fact, that it's trivial to implement classical inheritance with prototypes. The reverse is not true.
Prototypal inheritance allows most of the important features you'll find in classical languages. In JavaScript, closures and factory functions allow you to implement private state, and functional inheritance can be easily combined with prototypes in order to add mixins that support data privacy, as well.
Some advantages of prototypal inheritance:
Loose coupling. An instance never has a need to make a direct reference to a parent class or prototype. It's possible to store a reference to an object's prototype, but it's ill advised, because that would promote tight coupling in the object hierarchy -- one of the biggest pitfalls of classical inheritance.
Flat hierarchies. It's trivial with prototypal OO to keep inheritance hierarchies flat - using concatenation and delegation, you can have a single level of object delegation and a single instance, with no references to parent classes.
Trivial multiple inheritance. Inheriting from multiple ancestors is as easy as combining properties from multiple prototypes using concatenation to form a new object, or a new delegate for a new object.
Flexible architecture. Since you can inherit selectively with prototypal OO, you don't have to worry about the "wrong design" problem. A new class can inherit any combination of properties from any combination of source objects. Due to the ease of hierarchy flattening, a change in one place doesn't necessarily cause ripples throughout a long chain of descendant objects.
No more gorillas. Selective inheritance eliminates the gorilla banana problem.
I am not aware of any advantage that classical inheritance has over prototypal inheritance. If anybody is aware of any, please enlighten me.

- 4,711
- 1
- 25
- 33
-
1Isn't an advantage of classical inheritance that it can be made faster than prototypal inheritance, especially for example with compile-time static classes as in C++? Or do you mean strictly limited to discussion involving JavaScript only? – Todd Lehman May 16 '14 at 05:57
-
how to inherit selectively in javascript? – Lakshay Dulani Aug 03 '15 at 16:59
-
1@Lakshay using concatenative inheritance. Covered here: [Common Misconceptions About Inheritance in JavaScript](https://medium.com/javascript-scene/common-misconceptions-about-inheritance-in-javascript-d5d9bab29b0a) – Eric Elliott Aug 15 '15 at 00:56
-
Good answer although a bit biaised, your last comment proves you haven't given lots of thoughts about classical advantages. I am a JS developper, but I could see the benefits of static analysis, stronger refactoring capabilities from IDE, on-the-fly documentation and to sums things up a faster way to dwelve into some foreign code, especially if its owner does not believe in the same principles as you do. – floribon Jan 28 '17 at 01:06
-
I'm speaking specifically about JavaScript (tagged by the OP), which does not have static types. A class in JavaScript is in no way similar to a static class in Java. `instanceof` is an unreliable check that don't work when objects are extended or across execution context boundaries. Even in TypeScript, interfaces are a more reliable mechanism for dev tooling. – Eric Elliott Jan 28 '17 at 17:25
-
I think the gorilla banana problem is due more than just inheritance it also has to do with the assumptions that different code uses, and especially it has to do with state (even when changing the private state of objects). Unless your writing Clojure or Haskell you have something like the gorilla banana problem, although you could code functionally in JavaScript. However, prototypes are more flexible than classes, yes! – aoeu256 Jul 09 '19 at 00:14
-
Yes, the gorilla/banana problem is about both class inheritance and state. Specifically, what you get when you instantiate or get passed an object, including props and state. It was coined by Joe Armstrong in the book, Coders at Work. "I think the lack of reusability comes in object-oriented languages, not functional languages. Because the problem with object-oriented languages is they’ve got all this implicit environment that they carry around with them. You wanted a banana but what you got was a gorilla holding the banana and the entire jungle." – Eric Elliott Jul 10 '19 at 02:37
Prototype-based inheritance is more flexible. Any existing object can become a class from which additional objects will be spawned. This is handy where your objects offer several sets of services and/or they undergo a lot of state transformation before your program arrives at the point where the inheritance is needed.
A broad-spectrum discussion of modeling approaches is available here: http://steve-yegge.blogspot.com/2008/10/universal-design-pattern.html

- 30,277
- 10
- 88
- 118
Since Javascript doesn't support "Classic" inheritance as most would understand (and you haven't given any references to what you've been reading) I'll assume you mean inheritance handled like this:-
function base() {
var myVar;
this.someBaseFunc = function() { }
}
function derived() {
base.call(this);
var someOtherVar;
this.SomeOtherFunc = function() { }
}
My general rule of thumb is:
- If the Classes are complex and the instances are few use a "classical" approach. This allows the classes to expose publicly only those features that should be made public.
- If the Class are simple and the instances are many use a prototypal approach. This limits the overhead of defining and storing references to functions over and over again as instances are created.

- 187,081
- 35
- 232
- 306
-
3I hate to downvote things, but none of your answer is correct. I'm sorry. ); * You don't need classical inheritance in order to achieve encapsulation. All you need is a closure (which can be accomplished easily using a factory function and a prototype). * Classical inheritance in JavaScript can still take advantage of prototype delegation (and frequently does). Classical inheritance just means that a new instance inherits from a parent class in a parent-child hierarchy, as opposed to an object instance as in prototypal. – Eric Elliott Aug 02 '13 at 17:31
-
Oh yeah closures (partially evaluated functions), or functions which make use of variables from the surrounding scope can be used like objects complete with polymorphism and encapsulation are more lightweight than objects, although your limited to calling the function while objects usually have several methods. – aoeu256 Jul 09 '19 at 00:21
-
All methods defined inside a function have access to that function's private data via closure. That data is encapsulated. const createSecret = secret => ({ getSecret: () => secret, setSecret: newSecret => createSecret(newSecret) }) – Eric Elliott Jul 10 '19 at 02:46