Benefits of prototypal inheritance over classical? - javascript

So I finally stopped dragging my feet all these years and decided to learn JavaScript “properly”. One of the most head-scratching elements of the languages design is its implementation of inheritance. Having experience in Ruby, I was really happy to see closures and dynamic typing; but for the life of me can’t figure out what benefits are to be had from object instances using other instances for inheritance.

Note: Since I wrote this answer 10 years ago, I have learned that inheritance is harmful. There's no good reason to ever use inheritance in software development. Everything that you can do with inheritance, you can do better with composition. Consider using algebraic data types instead.
I know that this answer is 3 years late but I really think the current answers do not provide enough information about how prototypal inheritance is better than classical inheritance.
First let's see the most common arguments JavaScript programmers state in defence of prototypal inheritance (I'm taking these arguments from the current pool of answers):
It's simple.
It's powerful.
It leads to smaller, less redundant code.
It's dynamic and hence it's better for dynamic languages.
Now these arguments are all valid, but nobody has bothered explaining why. It's like telling a child that studying Maths is important. Sure it is, but the child certainly doesn't care; and you can't make a child like Maths by saying that it's important.
I think the problem with prototypal inheritance is that it's explained from the perspective of JavaScript. I love JavaScript, but prototypal inheritance in JavaScript is wrong. Unlike classical inheritance there are two patterns of prototypal inheritance:
The prototypal pattern of prototypal inheritance.
The constructor pattern of prototypal inheritance.
Unfortunately JavaScript uses the constructor pattern of prototypal inheritance. This is because when JavaScript was created, Brendan Eich (the creator of JS) wanted it to look like Java (which has classical inheritance):
And we were pushing it as a little brother to Java, as a complementary language like Visual Basic was to C++ in Microsoft’s language families at the time.
This is bad because when people use constructors in JavaScript they think of constructors inheriting from other constructors. This is wrong. In prototypal inheritance objects inherit from other objects. Constructors never come into the picture. This is what confuses most people.
People from languages like Java, which has classical inheritance, get even more confused because although constructors look like classes they don't behave like classes. As Douglas Crockford stated:
This indirection was intended to make the language seem more familiar to classically trained programmers, but failed to do that, as we can see from the very low opinion Java programmers have of JavaScript. JavaScript’s constructor pattern did not appeal to the classical crowd. It also obscured JavaScript’s true prototypal nature. As a result, there are very few programmers who know how to use the language effectively.
There you have it. Straight from the horse's mouth.
True Prototypal Inheritance
Prototypal inheritance is all about objects. Objects inherit properties from other objects. That's all there is to it. There are two ways of creating objects using prototypal inheritance:
Create a brand new object.
Clone an existing object and extend it.
Note: JavaScript offers two ways to clone an object - delegation and concatenation. Henceforth I'll use the word "clone" to exclusively refer to inheritance via delegation, and the word "copy" to exclusively refer to inheritance via concatenation.
Enough talk. Let's see some examples. Say I have a circle of radius 5:
var circle = {
radius: 5
};
We can calculate the area and the circumference of the circle from its radius:
circle.area = function () {
var radius = this.radius;
return Math.PI * radius * radius;
};
circle.circumference = function () {
return 2 * Math.PI * this.radius;
};
Now I want to create another circle of radius 10. One way to do this would be:
var circle2 = {
radius: 10,
area: circle.area,
circumference: circle.circumference
};
However JavaScript provides a better way - delegation. The Object.create function is used to do this:
var circle2 = Object.create(circle);
circle2.radius = 10;
That's all. You just did prototypal inheritance in JavaScript. Wasn't that simple? You take an object, clone it, change whatever you need to, and hey presto - you got yourself a brand new object.
Now you might ask, "How is this simple? Every time I want to create a new circle I need to clone circle and manually assign it a radius". Well the solution is to use a function to do the heavy lifting for you:
function createCircle(radius) {
var newCircle = Object.create(circle);
newCircle.radius = radius;
return newCircle;
}
var circle2 = createCircle(10);
In fact you can combine all of this into a single object literal as follows:
var circle = {
radius: 5,
create: function (radius) {
var circle = Object.create(this);
circle.radius = radius;
return circle;
},
area: function () {
var radius = this.radius;
return Math.PI * radius * radius;
},
circumference: function () {
return 2 * Math.PI * this.radius;
}
};
var circle2 = circle.create(10);
Prototypal Inheritance in JavaScript
If you notice in the above program the create function creates a clone of circle, assigns a new radius to it and then returns it. This is exactly what a constructor does in JavaScript:
function Circle(radius) {
this.radius = radius;
}
Circle.prototype.area = function () {
var radius = this.radius;
return Math.PI * radius * radius;
};
Circle.prototype.circumference = function () {
return 2 * Math.PI * this.radius;
};
var circle = new Circle(5);
var circle2 = new Circle(10);
The constructor pattern in JavaScript is the prototypal pattern inverted. Instead of creating an object you create a constructor. The new keyword binds the this pointer inside the constructor to a clone of the prototype of the constructor.
Sounds confusing? It's because the constructor pattern in JavaScript unnecessarily complicates things. This is what most programmers find difficult to understand.
Instead of thinking of objects inheriting from other objects they think of constructors inheriting from other constructors and then become utterly confused.
So what are the benefits of prototypal inheritance over classical inheritance? Let's go through the most common arguments again, and explain why.
1. Prototypal Inheritance is Simple
CMS states in his answer:
In my opinion the major benefit of prototypal inheritance is its simplicity.
Let's consider what we just did. We created an object circle which had a radius of 5. Then we cloned it and gave the clone a radius of 10.
Hence we only need two things to make prototypal inheritance work:
A way to create a new object (e.g. object literals).
A way to extend an existing object (e.g. Object.create).
In contrast classical inheritance is much more complicated. In classical inheritance you have:
Classes.
Object.
Interfaces.
Abstract Classes.
Final Classes.
Virtual Base Classes.
Constructors.
Destructors.
You get the idea. The point is that prototypal inheritance is easier to understand, easier to implement, and easier to reason about.
As Steve Yegge puts it in his classical blog post "Portrait of a N00b":
Metadata is any kind of description or model of something else. The comments in your code are just a a natural-language description of the computation. What makes metadata meta-data is that it's not strictly necessary. If I have a dog with some pedigree paperwork, and I lose the paperwork, I still have a perfectly valid dog.
In the same sense classes are just meta-data. Classes aren't strictly required for inheritance. However some people (usually n00bs) find classes more comfortable to work with. It gives them a false sense of security.
Well, we also know that static types are just metadata. They're a specialized kind of comment targeted at two kinds of readers: programmers and compilers. Static types tell a story about the computation, presumably to help both reader groups understand the intent of the program. But the static types can be thrown away at runtime, because in the end they're just stylized comments. They're like pedigree paperwork: it might make a certain insecure personality type happier about their dog, but the dog certainly doesn't care.
As I stated earlier, classes give people a false sense of security. For example you get too many NullPointerExceptions in Java even when your code is perfectly legible. I find classical inheritance usually gets in the way of programming, but maybe that's just Java. Python has an amazing classical inheritance system.
2. Prototypal Inheritance is Powerful
Most programmers who come from a classical background argue that classical inheritance is more powerful than prototypal inheritance because it has:
Private variables.
Multiple inheritance.
This claim is false. We already know that JavaScript supports private variables via closures, but what about multiple inheritance? Objects in JavaScript only have one prototype.
The truth is that prototypal inheritance supports inheriting from multiple prototypes. Prototypal inheritance simply means one object inheriting from another object. There are actually two ways to implement prototypal inheritance:
Delegation or Differential Inheritance
Cloning or Concatenative Inheritance
Yes JavaScript only allows objects to delegate to one other object. However it allows you to copy the properties of an arbitrary number of objects. For example _.extend does just this.
Of course many programmers don't consider this to be true inheritance because instanceof and isPrototypeOf say otherwise. However this can be easily remedied by storing an array of prototypes on every object which inherits from a prototype via concatenation:
function copyOf(object, prototype) {
var prototypes = object.prototypes;
var prototypeOf = Object.isPrototypeOf;
return prototypes.indexOf(prototype) >= 0 ||
prototypes.some(prototypeOf, prototype);
}
Hence prototypal inheritance is just as powerful as classical inheritance. In fact it's much more powerful than classical inheritance because in prototypal inheritance you can hand pick which properties to copy and which properties to omit from different prototypes.
In classical inheritance it's impossible (or at least very difficult) to choose which properties you want to inherit. They use virtual base classes and interfaces to solve the diamond problem.
In JavaScript however you'll most likely never hear of the diamond problem because you can control exactly which properties you wish to inherit and from which prototypes.
3. Prototypal Inheritance is Less Redundant
This point is a little more difficult to explain because classical inheritance doesn't necessarily lead to more redundant code. In fact inheritance, whether classical or prototypal, is used to reduce the redundancy in code.
One argument could be that most programming languages with classical inheritance are statically typed and require the user to explicitly declare types (unlike Haskell which has implicit static typing). Hence this leads to more verbose code.
Java is notorious for this behavior. I distinctly remember Bob Nystrom mentioning the following anecdote in his blog post about Pratt Parsers:
You gotta love Java's "please sign it in quadruplicate" level of bureaucracy here.
Again, I think that's only because Java sucks so much.
One valid argument is that not all languages which have classical inheritance support multiple inheritance. Again Java comes to mind. Yes Java has interfaces, but that's not sufficient. Sometimes you really need multiple inheritance.
Since prototypal inheritance allows for multiple inheritance, code which requires multiple inheritance is less redundant if written using prototypal inheritance rather than in a language which has classical inheritance but no multiple inheritance.
4. Prototypal Inheritance is Dynamic
One of the most important advantages of prototypal inheritance is that you can add new properties to prototypes after they are created. This allows you to add new methods to a prototype which will be automatically made available to all the objects which delegate to that prototype.
This is not possible in classical inheritance because once a class is created you can't modify it at runtime. This is probably the single biggest advantage of prototypal inheritance over classical inheritance, and it should have been at the top. However I like saving the best for the end.
Conclusion
Prototypal inheritance matters. It's important to educate JavaScript programmers on why to abandon the constructor pattern of prototypal inheritance in favor of the prototypal pattern of prototypal inheritance.
We need to start teaching JavaScript correctly and that means showing new programmers how to write code using the prototypal pattern instead of the constructor pattern.
Not only will it be it easier to explain prototypal inheritance using the prototypal pattern, but it will also make better programmers.

Allow me to actually answer the question inline.
Prototype inheritance has the following virtues:
It is better suited to dynamic languages because the inheritance is as dynamic as the environment it is in. (The applicability to JavaScript should be obvious here.) This permits you to do things quickly on the fly like customizing classes without huge amounts of infrastructure code.
It is easier to implement a prototyping object scheme than the classic class/object dichotomy schemes.
It eliminates the need for the complex sharp edges around the object model like "metaclasses" (I never metaclass I liked... sorry!) or "eigenvalues" or the like.
It has the following disadvantages however:
Type checking a prototype language isn't impossible, but it's very, very difficult. Most "type checking" of prototypical languages is pure run-time "duck typing"-style checks. This is not suitable to all environments.
It is similarly difficult to do things like optimizing method dispatch by static (or, often, even dynamic!) analysis. It can (I stress: can) be very inefficient very easily.
Similarly object creation can be (and usually is) much slower in a prototyping language than it can be in a more conventional class/object dichotomy scheme.
I think you can read between the lines above and come up with the corresponding advantages and disadvantages of traditional class/object schemes. There are, of course, more in each area so I'll leave the rest up to other people answering.

IMO the major benefit of prototypal inheritance is its simplicity.
The prototypal nature of the language can confuse people who are classically trained, but it turns out that actually this is a really simple and powerful concept, differential inheritance.
You don't need to make classification, your code is smaller, less redundant, objects inherit from other, more general objects.
If you think prototypically you will soon notice that you don't need classes...
Prototypal inheritance will be much more popular in the near future, the ECMAScript 5th Edition specification introduced the Object.create method, which allows you to produce a new object instance that inherits from another one in a really simple way:
var obj = Object.create(baseInstance);
This new version of the standard is being implemented by all browser vendors, and I think we will start to see more pure prototypal inheritance...

There is really not a lot to choose between the two methods. The basic idea to grasp is that when the JavaScript engine is given a property of an object to read, it first checks the instance and if that property is missing, it checks up the prototype chain. Here is an example that shows the difference between prototypal and classical:
Prototypal
var single = { status: "Single" },
princeWilliam = Object.create(single),
cliffRichard = Object.create(single);
console.log(Object.keys(princeWilliam).length); // 0
console.log(Object.keys(cliffRichard).length); // 0
// Marriage event occurs
princeWilliam.status = "Married";
console.log(Object.keys(princeWilliam).length); // 1 (New instance property)
console.log(Object.keys(cliffRichard).length); // 0 (Still refers to prototype)
Classical with instance methods (Inefficient because each instance stores it's own property)
function Single() {
this.status = "Single";
}
var princeWilliam = new Single(),
cliffRichard = new Single();
console.log(Object.keys(princeWilliam).length); // 1
console.log(Object.keys(cliffRichard).length); // 1
Efficient classical
function Single() {
}
Single.prototype.status = "Single";
var princeWilliam = new Single(),
cliffRichard = new Single();
princeWilliam.status = "Married";
console.log(Object.keys(princeWilliam).length); // 1
console.log(Object.keys(cliffRichard).length); // 0
console.log(cliffRichard.status); // "Single"
As you can see, since it is possible to manipulate the prototype of "classes" declared in the classical style, there is really no benefit to using prototypal inheritance. It is a subset of the classical method.

Web Development: Prototypal Inheritance vs. Classical Inheritance
http://chamnapchhorn.blogspot.com/2009/05/prototypal-inheritance-vs-classical.html
Classical Vs prototypal inheritance - Stack Overflow
Classical Vs prototypal inheritance

Related

OOP vs JavaScript

I have a background in OOP. I started to work a lot with JavaScript. As the project grows it's becoming more difficult to maintain it. In Java I apply OOP principles to keep things under control. What should I do with JavaScript, what should I study that is aimed at keeping a JavaScript application under control?
You can apply OOP principles to Javascript development too. Javascript uses prototypal inheritance, but that is an implementation detail. The concepts are still the same. Most of the concepts with which you are familiar have direct analogues in javascript.
Other tried and true methods apply as well:
1) Stay DRY -- Do not Repeat Yourself. Duplicate code is always evil.
2) Separate concerns -- Use the MVC or MVVM patterns to keep code clean and doing only 1 thing.
3) Test -- When I hear "Difficult to maintain" my brain translates that into lack of tests. You can certainly write unit tests for javascript projects.
4) Code Review -- Code reviews can be a good way of rejecting duplicated code, code that is not crafted properly, not formatted, etc....
This is how you define objects and methods in javascript.
function SomeObj() {
this.someMethod = function() {
alert('boo');
}
}
var o_obj = new SomeObj();
o_obj.someMethod(); //alerts "boo"
Hope it helps.
You can also use prototype to create static functions.
this.prototype.someMethod = function() {
alert('boo');
}
When I was in the same situation I started to look at "how other did". Its ended up with http://dojotoolkit.org/ and http://jquery.com and I was looking how they implement widgets/plugins so other could extend the framework.
Another way of defining simple objects and methods in javascript (without the need for new).
function creaeSomeObj() {
var that = {};
that.someMethod = function() {
alert('boo');
}
return that;
}
var o_obj = createSomeObj();
o_obj.someMethod(); //alerts "boo"
This pattern doesn't support inheritance, but many times it is sufficient.
Why "vs"? JavaScript supports object-oriented programming, but not in the traditional class-based way that you see in e.g. Java.
The way JavaScript's OOP works is usually known as "prototypal inheritance", or more specifically "delegative prototypal inheritance". This can be boiled down to "if you're looking for the property 'foo' in an object, and you can't find it there, then try looking for 'foo' inside the object's prototype instead". That is, the lookup of the property is delegated to the object's prototype (we say that the object inherits the properties from the prototype).
The way prototypal inheritance works has a couple of implications. For instance:
Objects in JavaScript are "dynamic" in the sense that they're just a bunch of name-value pairs. New properties can be added and removed during runtime, so they're much less "static" than objects in the typical class sense.
The way delegative prototypal inheritance works ("if you can't find the prototype here, then look here instead") means it's much simpler than classical OOP. From a purely prototypal point of view, you don't need constructors, for example. "Methods" are just regular functions that happen to be attached to the prototype (which means they are available as properties on all inheriting objects).
There are pro's and con's with both prototypal and classical inheritance, but it's important to remember that they're different.
Now, JavaScript is in some senses inspired by Java and other classical languages, so therefore they decided to make the syntax "class-like" to make it easier for people used to classes to get started. I won't elaborate a lot on this; it's documented to a great extent in other places already.
Some interesting posts:
hughfdjackson's introduction to JavaScript OOP -- short and more to-the-point,
Sorella's longer "Understanding Javascript OOP" -- rather in-depth and very complete resource.
Pluralsight has a course on just this topic: Structuring JavaScript Code that may provide some insight. Two caveats: 1. I haven't sat through the course yet - but content looks great and I've been impressed with other Pluralsight courses I've taken, and 2. it is not free (but may be worth the small $ if it saves you time down the road b/c you have better code structure). No, I don't work for Pluralsight.
In addition to the js frameworks mentioned in this thread, can also look at Knockoutjs - great tutorials here learnknockoutjs.com. Knockout is MVVM focused. Note, there is a good discussion in stackoverflow comparing Backbone to Knockout, and Pluralsight also has a course on using Knockout which I have watched and do recommend.
In JavaScript, Functions are Objects; Mozilla Developer Network, McKoss, SitePoint, and JavaScript Kit explain further.
Example JavaScript Object
function myObj() {
this.myMethod = function() {
alert('hello');
}
}
var demo_obj = new myObj();
demo_obj.myMethod();
Patterns to keep things under control
The patterns listed here are particular to JavaScript.
Use a Script Loader.
Use a JS Framework.
Lint your JavaScript. - Tools are availble to run this on your desktop in Rhino or node.
Minify your JS.
The patterns listed here are typical of OOP Languages, and are not
particular to JavaScript.
DRY - Don't Repeat Yourself.
Observer (Pub/Sub) pattern.
Anti-Patterns to let things out of control
Polluting the namespace
use of eval()
Prototyping against the Object object
Inline Script Tags.
use of document.write

Is JavaScript 's “new” Keyword Considered Harmful (Part 2)? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
Reading through the following question, I feel the majority of the answers miss the point of why some people (Crockford) choose not to use the "new" keyword. It's not to prevent accidental calling of a function without the "new" keyword.
According to the following article by Crockford regarding prototypal inheritance, he implements an object creation technique that more clearly demonstrates the prototypal nature of JS. This technique is now even implemented in JS 1.8.5.
His argument against using new can be more clearly summed up as:
"This indirection was intended to make the language seem more familiar to classically trained programmers, but failed to do that, as we can see from the very low opinion Java programmers have of JavaScript. JavaScript's constructor pattern did not appeal to the classical crowd. It also obscured JavaScript's true prototypal nature. As a result, there are very few programmers who know how to use the language effectively."
I don't necessarily consider "new" harmful, but I do agree that it does "obscure JavaScript's true prototypal nature," and therefore I do have to agree with Crockford on this point.
What is your opinion of using a "clearer" prototypal object creation technique, over using the "new" keyword?
You right, using new is considered harmful as it doesn't place enough emphasis on OO in JavaScript being prototypical. The main issue is that acts too much like classical classes and one should not think about class. One should think about Object's and creating new Objects with existing objects as blueprints.
new is a remnant of the days where JavaScript accepted a Java like syntax for gaining "popularity".
These days we do Prototypical OO with Object.create and use the ES5 shim.
There is no need for new anymore.
Before the days of ES5 being commonly implemented (only FF3.6 and IE8 are slacking) we used new because we had little choice. someFunction.prototype was the way to do prototypical inheritance.
I recently wrote up a "nice" demonstration of Object.create although I still need to iron out some kinks in the usage. The important thing is to separate Objects from factory functions.
I don't find that new obscures the prototypical nature of the language for me. Granted I've now spent some years getting to know the language well (having made the mistake originally of diving in and starting writing code without a clue how the language actually worked, to my initial cost).
I find new expressive in a way that prefixing "new" on function names or using a helper function, etc., isn't:
var fido = new Dog(); // Simple, clear
var rover = Dog(); // Very unclear (fortunately people mostly don't do this, but I've seen it)
var scruffles = newDog(); // Clearer, but hacky
var fifi = Object.create(Dog); // (Crockford) Verbose, awkward, not esp. clear
Whether it's prototypical or class-based (and most of that doesn't relate to the new keyword at all), I still think best in terms of functionality grouped together into building blocks (objects or classes or whatever) and then specific objects I can muck about without affecting those building blocks. For me, new as a means of clearly identifying my intent is neither classy or prototypical, it's just clear.
For me, new is just as vital a part of JavaScript as prototypes themselves are, as the wonderfully dexterous functions are. The is is no conflict.
And speaking practically, there are a lot more programmers out there used to using new to create new instances of things than not, and it's a widespread practice in the JavaScript community despite Crockford's efforts (don't misunderstand, I have a lot of respect for Crockford). If I'm staffing up a project, I don't want the retraining hassles.
This is not to say that the way that you define hierarchies of prototypical objects in JavaScript is a thing of beauty and a joy forever. It's a royal pain, especially without the ECMAScript5 enhancements. But define a helper function to help you wire up your hierarchies (whatever you want to call them), and you're done. (See update below.)
[And yes, the whole thing about constructor functions being called without new really is a red herring (you did say you didn't think it was a main point either). You almost never see it happen in the real world. Actually, some of what JavaScript does with that is quite nice (the way String and Number cast, for instance); other parts (what Date does **shudder**) are not so nice...]
As of ES2015 (ES6), creating hierarchies of prototypes and constructors is a breeze, thanks to the new class syntax. No need for helpers anymore.
class Base {
constructor(name) {
this.name = name;
}
greeting() {
return "Hi, I'm " + this.name;
}
}
class Derived extends Base {
constructor(name, age) {
super(name);
this.age = age;
}
greeting() {
return super.greeting() + " and I'm " + this.age + " years old";
}
}
That doesn't mean we want them for everything, of course. I use Object.create to great effect when I need to extend a single object.
My biggest problem with new is that it violates the Open/Closed principle. Because of the way that new manipulates the value of this, constructors are closed for extension, which means if you need to extend it, you must modify it, possibly breaking callers in the process.
Some examples of how factories can be extended that new doesn't allow:
Hide the details of object creation. (The rest of these are examples of why you might want to do that)
Store mutable prototypes and init functions on the factory object, accessible with this. (With new, this always refers to the newly created object).
Extend the pool of possible object types by allowing you to add capabilities to the factory object (extensible polymorphism).
Redefine the meaning of this during instantiation with .call() or .apply() (extending code-reuse).
Return a proxy to a new object in another memory space (iframe, window, different machine).
Conditionally return a reference to an existing object (Actually, you can do that with new and constructors, but then this is meaningless and misleading inside the constructor because a new instance gets allocated and then thrown away if you return something other than a new object).
Enable changes to instantiation strategy without breaking callers.
Note: I'm constantly irritated that I can't easily use any of these strategies with Backbone.js because it forces you to use new, unless you wrap it, but then you close off its standard inheritance mechanism. By way of contrast, I have never found myself irritated that jQuery uses a factory function to instantiate jQuery-wrapped DOM collections.

Does using prototypes in JavaScript have any real world advantages?

I just finished Doug Crockford's The Good Parts, and he offers three different ways to go about inheritance: emulation of the classical model, prototype-based inheritance, and functional inheritance.
In the latter, he creates a function, a factory of sorts, which spits out objects augmented with desired methods that build upon other objects; something along the lines of:
var dog = function(params) {
// animal is the 'super class' created
// the same way as the dog, and defines some
// common methods
var that = animal(params);
that.sound = 'bark';
that.name = function () {};
return that;
}
Since all objects created this way will have a reference to the same functions, the memory footprint will be much lower than using when using the new operator, for instance. The question is, would the prototype approach offer any advantages in this case? In other words, are object prototypes somehow 'closer to the metal' that provide performance advantages, or are they just a convenience mechanism?
EDIT: I'll simplify the question. Prototypes vs. their emulation through object composition. So long as you don't require all object instances to get updated with new methods which is a convenience offered only by prototypes, are there any advantages to using prototypes in the first place?
I emailed Doug Crockford, and he had this to say:
[Using the functional approach above vs. prototypes] isn't that much memory. If you have a huge number of objects times a huge number of methods, then you might want to go prototypal. But memories are abundant these days, and only an extreme application is going to notice it.
Prototypes can use less memory, but can have slightly slower retrieval, particularly if the chains are very long. But generally, this is not noticeable.
The instances don't all reference the same functions etc. Each call to "dog" will create a new "name" function instance.
There are many opinions about this, and Crockford's isn't necessarily the right one.
The main disadvantage to modifying the prototypes is that it may make it harder to work with other javascript libraries.
But the disadvantage of Crockford's functional way of creating classes is that you can't add a method or field to all instances of a type as easily.
See Closure: The Definitive Guide for some critical comments on Crockford's view about classes and inheritance in javascript:
http://my.safaribooksonline.com/9781449381882/I_sect1_d1e29990#X2ludGVybmFsX0ZsYXNoUmVhZGVyP3htbGlkPTk3ODE0NDkzODE4ODIvNTE0
Libraries like Dojo, Google Closure Library (which seems to copy Dojo's style), and perhaps YUI have their own class system that seems to be a good middle ground. I like Dojo's system probably the best because it has support for Mixins, unlike Closure. Some other class systems not tied to gui toolkits include Joose, JS.Class, and JavascriptMVC (check out last one esp. if using jquery).
I once created a GUI that was backed by a class that didn't have great event-based support for the information it needed. The GUI implemented a generic interface where an instance of that class is passed in, so I cannot inherit from that class, so I did something similar to prototype-based inheritance, I created a proxy object that wraps the instance of that class when it's passed to my GUI. The proxy intercepts methods of interest that mutate state, and report them as events. The entire GUI then revolved around using these events.
In this case, it would have just been annoying to create a separate class that wraps the passed in instance and reproduces the same interface. This would actually have lead to more overhead (not that it matters) due to creating all the redundant functions.
There was simply no other viable alternative. The only alternatives were:
Create an object that composes the object passed to the GUI (like I mentioned above). This object would then reproduce every function in the original class to implement the same interface, and add events, so it's effectively just the same as the proxy object way.
Have the GUI track state mutation in its passed in object. This would have been a pain and bug prone.

Why to use class based OOP style inheritance in javascript?

If I'm not completely wrong every framework/library/approach in javascript tends today to mimick class based OOP style inheritance. Reasons for this seem to be people thinking class based OOP inheritance is far easier to understand and that most programmers know OOP.
In my experience I don't find evidence for either of this opinions. I think javascript prototypal inheritance is just fine (and I doubt the usefulness to force another paradigm upon a language than the one it is built on). Most of the developers I meet aren't even that good in classical OOP either. So what are the reasons to choose classical OOP style inheritance over prototypal inheritance?
I think the answer is in your question - most programmers are far more familiar with class-based OOP than prototype-based.
In fact I'd go so far as to say the majority don't believe you can have objects without classes.
note that even if you're arguing for prototype-based OOP, you call it 'prototypal', and class-based OOP just 'OOP'. so, you yourself suffer from this bias, thinking OOP=>classes, prototypes => something else.
and since most people think that OOP is the right way no matter the problem, then prototypes must be inferior.
so, to answer your question, it's two factors:
a bad definition: "OOP => classes"
propaganda: "it must be OOP, or you're not worthy"
since you're still bounded by the first, you try to explain that prototypes are an exception of the second. much easier is to correct them:
there are many ways to do objects, classes are just the easiest one for static languages. most people are taught to program with static languages, and most of them try to use any language just like the first one they learned.
there are many ways to structure a programming solution, OOP are great at some and lousy at others.
I feel as if you already know the answer to your question because you stated a part of it when you said
Reasons for this seem to be people
thinking class based OOP inheritance
is far easier to understand and that
most programmers know OOP.
Neither paradigm is more right than the other for tackling a problem. I believe the main reason is that everyone is taught OOP through Java these days. So when people encounter OOP they think "oh classes" because it's what they are familiar with. And whenever they want to solve a problem they will most likely use what they know.
I would also state that it does no benefit for the programmer to use a paradigm he is unfamiliar with. Most of us must use javascript for client side web development and use a class based OOP language on the server. I personally would not want that OOP impedance mismatch whenever I had to look at the javascript side of an application.
At a certain level the fact that everyone is trying to implement class based OOP in javascript is an educational issue. At another level it's a psychological one.
For a long time I considered prototype-based OOP as weak, bad and wrong version of class-based OOP. Then, after a critical amount of information leaked into my head, I now understand OOP in more abstract way, and find both ways acceptable in general.
So what are the reasons to choose classical OOP style inheritance over prototypal inheritance?
Actually, I believe that some frameworks are "sort of" combining approaches. Take for example the Parasitic Combination Inheritance pattern. This is what YAHOO.lang.extend is doing.
It uses prototypal inheritance and a helper function to inherit prototypes and constructor stealing. Wow, that sounds complex...well yes it is - here's my implementation and test for example:
// Prototypal Inheritance
Object.prototype.inherit = function(p) {
NewObj = function(){};
NewObj.prototype = p;
return new NewObj();
};
// Paraphrasing of Nicholas Zakas's Prototype Inheritance helper
function inheritPrototype(subType, superType) {
var prototype = Object.inherit(superType.prototype);
prototype.constructor = subType;
subType.prototype = prototype;
};
function SubType(name, age) {
Parent.call(this, name);
this.age = age;
};
inheritPrototype(SubType, Parent);
SubType.prototype.getAge = function() {
return this.age;
};
I have a test for this code:
describe 'Parisitic Combination Inheritance'
it 'should use inheritPrototype (to call parent constructor once) and still work as expected'
sub = new SubType("Nicholas Zakas", 29)
sub.toString().should.match /.*Nicholas Zakas/
sub.getAge().should.eql 29
charlie = new SubType("Charlie Brown", 69)
charlie.arr.should.eql([1,2,3])
charlie.arr.push(999)
charlie.arr.should.eql([1,2,3,999])
sub.arr.should.eql([1,2,3])
sub.should.be_an_instance_of SubType
charlie.should.be_an_instance_of SubType
(sub instanceof SubType).should.eql true
(sub instanceof Parent).should.eql true
end
end
And of course, if you're paying attention to my literals you see: Nicholas Zakas, the guy I got this from ;) The big wins for this one: instanceof works (big deal some say and I kind of agree); instances don't share state on reference types like arrays (a biggie!); parent constructor only called once (a biggie!).
BTW, I have examples of most of the popular inheritance patterns here: My TDD JS Examples
I'd argue that the language itself steers people into the classical mindset with it's choice of "new" as a keyword, and by introducing concepts like "constructors" in the language specification. In a way this is limiting - imagine the change in mindset if instead we had a clone keyword, and the concept of traits ala SELF.
When I was writing my first scripts, it was cool and handy to have such a simple language.
But today you do not just want to toggle a buttoncolor, you want to build complex applications in JavaScript. Others might like to use your popular application and would love to see s community providing plugins.
Now, this is much easier to realize with OOP - especially because a lot of programmers a familiar with OOP concepts.
One reason may be that your server side is likely to be OO (ASP.NET, Java, etc.), so it's just easier to think in the same paradigm on the client. Not necessarily better, but easier.

What does it mean that Javascript is a prototype based language?

One of the major advantages with Javascript is said to be that it is a prototype based language.
But what does it mean that Javascript is prototype based, and why is that an advantage?
Prototypal inheritance is a form of object-oriented code reuse. Javascript is one of the only [mainstream] object-oriented languages to use prototypal inheritance. Almost all other object-oriented languages are classical.
In classical inheritance, the programmer writes a class, which defines an object. Multiple objects can be instantiated from the same class, so you have code in one place which describes several objects in your program. Classes can then be organized into a hierarchy, furthering code reuse. More general code is stored in a higher-level class, from which lower level classes inherit. This means that an object is sharing code with other objects of the same class, as well as with its parent classes.
In the prototypal inheritance form, objects inherit directly from other objects. All of the business about classes goes away. If you want an object, you just write an object. But code reuse is still a valuable thing, so objects are allowed to be linked together in a hierarchy. In javascript, every object has a secret link to the object which created it, forming a chain. When an object is asked for a property that it does not have, its parent object will be asked... continually up the chain until the property is found or until the root object is reached.
Each function in JavaScript (which are objects themselves) actually has a member called "prototype", which is responsible for providing values when an object is asked for them. Having this member allows the constructor mechanism (by which objects are constructed from functions) to work. Adding a property to the prototype of a function object will make it available to the constructed object, as well as to all of the objects which inherit from it.
Advantages
There may not be a hard and fast rule as to why prototypal inheritance is an advantageous form of code-reuse. Code reuse itself is advantageous, and prototypal inheritance is a sensible way of going about it. You might argue that prototypal inheritance is a fairly simple model of code reuse, and that code can be heavily reused in direct ways. But classical languages are certainly able to accomplish this as well.
Sidenote: #Andrew Hedges makes a good point, that there are actually many prototypal languages. It's worth noting that these others exist, but also worth noting that none of them are anything close to mainstream. NewtonScript seemed to have some traction for a while, but died with its platform. It's also possible to extend some modern languages in ways which add prototypal capabilities.
A prototype-based language, does not make the distinction of classes vs objects: it simply has objects. A prototype-based language has the notion of a prototypical object, an object used as a template from which to get the initial properties for a new object. Any object can specify its own properties, either when you create it or at run time. In addition, any object can be associated as the prototype for another object, allowing the second object to share the first object's properties.
Prototype-based programming is a style of object-oriented programming where classes are not present, and behavior reuse (or inheritance in class-based languages) is performed by cloning existing objects that serve as prototypes.
The advantage/disadvantage is that, we can create new kinds of objects at run time without need for defining classes (static code). Like most features it is upto the developer to turn it to a advantage/disadvantage.
Above is possible because objects are essentially functions in java script (closures too).
Instead of declaring a class structure, you can create objects of the same type, and add to their definition any time you like using the object's prototype.
It's more flexible than the normal way of doing things.
After reading all the answers this is the conclusion
1) Inheritance in which objects are inherited directly from other objects
2) That does not use classes
3) Also called instance based programming or classless prototype oriented programming
4) Behaviour reuse is performed by cloning existing objects that serve as prototypes
5) Object used as template from the new object get initial properties
If you just use objects at runtime instead of a class at compile to build new objects, this opens up the possibility of extending an object without knowing any details about it. Of course, it may become a disadvantage pretty quickly depending on usage. I make no assumptions about the language here, so it is applicable to languages other than javascript which are not as dynamic.
myobject.prototype=unkownobject;
myobject.newproperty=1;
You may get the object from just about anywhere; your own code, from the network, from the database, from external linkage and so on.
Note that, a language don't have to implement prototype inheritance like javascript. In javascript, a prototype object is merely shared, so is its properties, among the inheritors. The alternative is copying over all the properties of the prototype to the new object. Each approach has its strengths in different situations. I like the second more but it isn't what javascript does.
Memory conservation is one of the benefits of prototypal inheritance in JS. In a language like Java, objects generate their own copies of the superclass' instance variables and methods, while in JS, the "super"-object offers get-access to its variables and methods to each "sub"-object that inherits from it without the need to recreate them.

Categories