
The world's smallest and fastest classical JavaScript inheritance pattern - codecurve
https://github.com/javascript/augment
======
kybernetikos
Weird. As far as I'm concerned, the smallest classical inheritance pattern in
javascript is

    
    
        Subclass.prototype = Object.create(Superclass.prototype);
    

And combined with calling your superclasses constructor in your own
constructor, that's it. Two lines at most.

You can get a little more complex if you want. In topiarist, I also copy all
the 'static' properties from the superconstructor onto the child constructor,
check that the prototype hasn't already been modified before replacing it so
as to fail fast, and set up the constructor field. But all this stuff is just
icing. The smallest classical inheritance pattern is just what I wrote above,
and I tend to think that all these articles that make it sound like some deep
magic is going on are doing more of a disservice to javascript developers than
a service.

~~~
camus2
nodejs has the util.inherits function which gives you an extra super_ shortcut
to the superclass constructor,it makes sense to use it in node.

~~~
kybernetikos
Quite right, if you're in node, you may as well use util.inherits, especially
since it basically does exactly the same thing (plus super_ and constructor):

    
    
        exports.inherits = function(ctor, superCtor) {
          ctor.super_ = superCtor;
          ctor.prototype = Object.create(superCtor.prototype, {
            constructor: {
              value: ctor,
              enumerable: false,
              writable: true,
              configurable: true
            }
          });
        };

------
jashkenas
While this README is very kindly worded, there are several things to be
careful of here:

Patching in Object.create with a version that will break third-party code?

[https://github.com/javascript/augment/blob/master/lib/augmen...](https://github.com/javascript/augment/blob/master/lib/augment.js#L25-L27)

Extending Object.prototype (!!!) inconsistently between old and new browsers?

[https://github.com/javascript/augment/blob/master/lib/augmen...](https://github.com/javascript/augment/blob/master/lib/augment.js#L38-L42)

Just because this is voted to the top of the HN front page ... apparently
doesn't mean you don't still need to watch your step.

If you'd like a safe, small and fast function for conveniently setting up the
prototype chain (a.k.a. classical inheritance in JavaScript), that works
cross-browser, try this one on for size:

    
    
        function augment(parent, properties) {
          var child = properties.constructor || function() { 
            return parent.apply(this, arguments); 
          };
        
          var Surrogate = function(){ this.constructor = child; };
          Surrogate.prototype = parent.prototype;
          child.prototype = new Surrogate;
        
          for (var key in properties) {
            child.prototype[key] = properties[key];
          }
      
          return child;
        };
    

... the nasty bit of JavaScript-specific business there being the intermediate
Surrogate, so that you don't need a concrete instance of the parent class to
be instantiated, in order to set your prototype chain. Used like so:

    
    
        var Person = augment(Model, {
          sortableName: function() {
            return this.lastName + ', ' + this.firstName;
          }
        });

~~~
yuchi
I still don’t understand why no one does `child.__proto__ = parent;` to
inherit properties on the constructor chain too.

~~~
nevir
There's a bunch of caveats to __proto__: [https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Refe...](https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto)

------
Kiro
A bit OT and naive question maybe but when do you need OOP in JavaScript? I
code a lot of web stuff but the only time I've used OOP in JS is when I make
games (where inheritance etc makes sense). Does anyone have a real-world
example?

~~~
jashkenas

        > I code a lot of web stuff but the only time 
        > I've used OOP in JS is when I make games
    

That's very doubtful. Ever used a String in JavaScript? Ever used an Array?
Ever used a regular expression? How about a function? All of those things are
objects in JavaScript — and are used and useful as such.

The notion that OOP === single-inheritance needs to be put out of its misery.
An object is anything that binds together data and code in a single value, and
you use them _all the time_.

~~~
dustingetz
Your first paragraph is true of functional languages too, which are decidedly
_not_ OO by any modern definition. OOP is about inheritance and encapsulating
mutable state.

~~~
e12e
An object is by definition data with associated functions to operate on that
data. One might say that functional programming couples functions(methods)
with data, while object oriented programs couple data with methods(functions).

In an object oriented paradigm, you send messages between objects, in a
functional paradigm you pass data to functions. But, functions can normally
take functions as arguments as well -- and all in all you can do one thing in
the other -- but I think the big difference is on whether you model "smart
data" or operations/functions.

Classes comes in when you have many objects that share behaviour. That can be
modelled as traits/interfaces or as classes (grouping methods, and possibly
singleton state). These things can be inherited, or assigned (as in
javascript/self).

------
rubiquity
Wait a second. I thought you made a library for classical inheritance in
JavaScript. What's all this functional and Array#from crap you're trying to
sell with it? Do one thing and do it well.

Another thing that sits a little weird with me is that this is in the
"javascript" organization on GitHub. I think that's a bit misleading, people
might mistake this as some official JS library.

------
alfl23
JavaScript inheritance library? JS does this by default, no need for more
useless boilerplate. The below works in all browsers, IE5 included.

function inherits(child, parent) { function tmp() {}; tmp.prototype =
parent.prototype; child.prototype = new tmp(); child.prototype.constructor =
child; }

function A() { this.x_ = 5 }; function B() {A.call(this);};inherits(B, A);

------
noiv
> var bindable = Function.bindable = bind.bind(bind);

The latter part of this line needs a bit of documentation.

------
kemayo
This is cool, but I like jashkenas' version in the comments here better.

As much as anything, this is because I maintain a reflexive aversion to
touching `Object.prototype`.

If you're disciplined about avoiding this you can use `for ... in` loops
without having to dick around with testing whether the properties are actually
directly on your object every time, or writing a wrapper that takes a
callback.

------
mistercow
This is pretty neat. A minor nitpick:

>You can easily include it in fiddles and benchmarks using the following HTML
code...

You really shouldn't use raw.github.com like that. If you're doing something
to show a couple of people, or for your own testing, you could use
rawgithub.com instead, but otherwise, you should just upload it somewhere
reliable.

------
jwmerrill
PJs [https://github.com/jayferd/pjs](https://github.com/jayferd/pjs) is the
sanest js classical inheritance library I've seen. It's very lightweight,
doesn't mess with Object.prototype, and interoperates seamlessly with
coffeescript classes.

------
bruceboughton
It's interesting that so much time and effort is spent by JavaScript
developers implementing classical inheritence when this is a concept
increasingly shunned in classically typed languages.

~~~
Tloewald
I think it's almost like a challenge people do for its own sake because it's
something even Crockford failed to do correctly. Write an awesome classical
inheritance pattern, write a bunch of tests to convince yourself it works, and
then ignore it.

Indeed, the fact Crockford's stuff on classical inheritance in The Good Bits
was wrong but the book got (and retains) so much traction indicates just how
much no-one cares.

~~~
SimHacker
Could you link to a good explanation of how that stuff fails please? Not
doubting you, just want to read more.

~~~
Tloewald
It's been a while since I used it, and I can't remember what the problems were
off the top of my head but they were face palm level.

Here's a discussion on stack exchange:

[http://programmers.stackexchange.com/questions/173176/javasc...](http://programmers.stackexchange.com/questions/173176/javascript-
objects-and-crockfords-the-good-parts)

The general problem with all classical inheritance patterns in Javascript is
that they don't really work (they treat Javascript as a static language so you
get all kinds of nasty surprises because it isn't). This is particularly sad
in comparison with older, conceptually simple languages like Objective-C that
do this stuff properly.

Crockford himself says it was a mistake to even include the section in the
book (in 8 years he's never used it)

[http://www.crockford.com/javascript/inheritance.html](http://www.crockford.com/javascript/inheritance.html)

The takeaway point is that doing classical inheritance in Javascript is a Bad
Idea. If you think you've done it, you probably haven't. And no-one will use
it.

------
kimjotki2
this, let's implement inheritance movement nonsense is crufts of Java and C++.
(and only C++ can be forgiven, for performance reasons.)

Python has proven that a successful dynamic language should have duck-typing,
via what called late-binding. you perform lookups on a live object. And this
makes even more sense for javascript, which intentionally violates whole
notion of typing.

In python, yes, there are such things like 'abstract base classes', but
they're mostly for convenience, not forced like interfaces in Java. which
means no one write codes like:

    
    
      If not isinstance(obj, JavaicMentalMasturbationBase):
        raise TypeError, "rogue object does not follow holy Javaland commandments: %r" %obj
    

instead, they exist that a framework provider can tell developers, on what are
the possible objects that can be fed to their framework. e.g) _to use our
SessionInterface, your custom session has to provide get_session and
save_sesion methods._

It seems like Branden Eich's original intention has came to fruition - create
a sub-par language and name it after Java. sub-sub-par developers from Java
will like the language, it even has closures! But I think he didn't expected
Java idiots to force their idioms and harm the whole ecosystem - usually,
enterprisey code monkeys were very silent in their cubicles.

~~~
coldtea
> _Python has proven that a successful dynamic language should have duck-
> typing, via what called late-binding. You perform lookups on a live object._

It has proven nothing of the short. For one, other languages have done it
before (and much better, like Smalltalk). Second, it's not something that, in
Python's implementation, makes it particularly suited or pleasant for large
codebases.

> _e.g) to use our SessionInterface, your custom session has to provide
> get_session and save_sesion methods._

So, relegate work that the computer can do to the programmer. Make him do
tedious and error-prone housekeeping.

The rest of the comment reads like a teenager's attempt at sounding like
"cool" and in the know. Things line "JavaicMentalMasturbationBase", "create a
sub-par language and name it after Java", "Java idiots" and the like.

I assure you that there are Java developers who run circles around whatever
your coding skills are. And from your description you don't sound that good at
Python either.

