views:

406

answers:

7

There's lots of articles and posts explaining how JavaScript inheritance works, but I'm curious why JavaScript was implemented using prototypal inheritance instead of classical inheritance. I love JavaScript so I'm not saying it's bad thing... I'm just curious.

+1  A: 

I think it was chosen because it is easy to implement, needs no extra keywords and users don't need to understand it to be able to use the language. It is also more powerfull and flexible than class based inheritance.

It's a natural choice for a untyped language. The main advantages of class based inheritance are that it allows static typing and thus type checking and a faster table based lookup implementation.

x4u
I wonder about the "easy to implement" argument. While this may be correct with respect to object inheritance, it doesn't seem to hold true when you consider that JavaScript's first-class functions are really powerful, and, I believe, not so straightforward to implement at all (partial applications, closures, etc.).
stakx
+13  A: 

Unless one of the designers of JavaScript stops by to weigh in, we can only speculate. That having been said, here's my take:

Being an interpreted/scripting language, it is executed as it is interpreted - there is no concept of separating the declaration of an object's type from the object itself. The instance is coming into existence as it is being described. We are always operating on active instances. Because of this, the concept of a class - or a passive "instance template" - has no real place.

Rex M
+6  A: 

JavaScript was originally supposed to be very much like Lisp. Even after the syntax was changed to more closely resemble C/Java, it is still Lisp in C's clothing. I think the answer lies in it's functional programming origins. In pure FP, there is no mutable state, which means no mutable objects. If you relax the rules a bit and get slightly creative, you end up with something like protypal inheritance, i.e., you can extend objects but not modify the original object. It provides the same power as inheritance and still gives you some immutability.

Finally, twist the language around to make it look like C++ and Java, and viola, you have new someFunction() and the rest is history.

noah
What do you mean by "there is no mutable state, which means no mutable objects"?
Ciwee
@Andre: In **pure** functional programming (like Erlang for example) all variables are constants. The values they hold can't be modified after the variable is instantiated. Since we refer to objects using variables that means that objects in pure FP cannot be modified: all objects are constants.
slebetman
Alright but, in javascript, what if I do this: var a = {name="n",age=1}. a.age = 2. What am I doing? re-instantiating 'a'?
Ciwee
@Andre My point was that JavaScript relaxes the rules and allows mutable state, but because it has its origins in FP, prototypal inheritance makes a sort of sense because it allows you to extend an object while keeping the original unchanged.
noah
+1  A: 

Prototypical inheritance (with closures) allows others to do things that were never envisioned. It's the meshing of several paradigms that have come together to achieve general purpose programming.

With a prototype language, you can have "mix-ins" for your classes. You can accomplish the level of encapsulation you desire, without language specific keywords. In short, prototype languages are awesome.

I hate to say it, but JavaScript, plus some libraries, can do everything I need it to. It was subversive in its development (supposed to be subservient to Java). It has much power, in the simplest of implementations.

With enough study / playing around, you'll begin to see the advantages of it's inspiration. JavaScript is one of the few languages that "hid" it's potential intentionally. You gotta get into the politics if you want to know the "why." But, it's for this reason, that it's awesome.

Pestilence
@Pestilence, can you point me to some resources for "to do things that were never envisioned"? For example with mix-ins, I can get the methods from an object by setting my prototype to it, but I can only do this once, right? Unless I do something without needing prototypes like:- I have an object X, I want it to possess Y.doSomething- X.doSomething = Y.doSomething- (that just sets a reference to Y.doSomething though, right? What if I want it to have that independently)
ambertch
Pestilence
The prototype attribute that you're referring to is, can be considered optional, for custom classes. You can take control and bypass it entirely.
Pestilence
This is a decent description of different ways of constructing classes in JS:http://www.ruzee.com/blog/2008/12/javascript-inheritance-via-prototypes-and-closuresTake notice to how he creates and extends (in-line). I don't think at the the time JS was created, this design pattern existed.
Pestilence
+3  A: 

Because it was heavily influenced by Self. Both Wikipedia and the ECMA-spec mention this.

Christoph
A: 

because it's simple.

Kevin Yang
+3  A: 

Here's what Brendan Eich has to say about what happened: http://weblogs.mozillazine.org/roadmap/archives/2008/04/popularity.html

As I've often said, and as others at Netscape can confirm, I was recruited to Netscape with the promise of "doing Scheme" in the browser. At least client engineering management including Tom Paquin, Michael Toy, and Rick Schell, along with some guy named Marc Andreessen, were convinced that Netscape should embed a programming language, in source form, in HTML.

The diktat from upper engineering management was that the language must "look like Java". That ruled out Perl, Python, and Tcl, along with Scheme.

I'm not proud, but I'm happy that I chose Scheme-ish first-class functions and Self-ish (albeit singular) prototypes as the main ingredients. The Java influences, especially y2k Date bugs but also the primitive vs. object distinction (e.g., string vs. String), were unfortunate.

dshaw