

Simple JavaScript Inheritance with Backbone - jimmydo
http://blog.usefunnel.com/2011/03/js-inheritance-with-backbone/

======
jpallen
When I first started with Javascript I used to think it was an awful excuse
for a programming language, with its weird prototypal inheritance and
functions pretending to be classes. The more I get to know it though, the more
impressed I am by how all these features can be used and built upon to create
an easy and flexible language. It has been taken in so many directions and I
think Backbone is a prime example of how it can be built upon well. I love
coding using the Backbone framework but I like that it's not the only option
for doing things in an object oriented way.

------
city41
I've just started down my path of really learning JavaScript. My first stop
was "JavaScript: The Good Parts", and the author there really advocates using
closures to define objects and enable encapsulation. It seems in practice this
approach isn't used often (such as Backbone here), why is that?

~~~
munificent
Performance. If you have n objects with m methods, that creates n * m function
objects. With "normal" prototypal inheritance where those methods are on the
prototype, it only requires n objects + m functions.

~~~
jashkenas
As always, munificent is right on the money.

The "closure pattern" is one of the most serious JavaScript anti-patterns --
it doesn't make much of a difference in tiny scripts, but for any decent-size
JavaScript application, it can hurt performance terribly, especially regarding
memory use.

For example, benchmarking the creation of 1 million objects, each with 10
member functions, in both the prototypal style and the closure style (in
Chrome):

    
    
        1 million prototypal objects: Brief pause, 32.4 MB
    
        1 million closure objects: Minutes wait, 368.1 MB
    

If you're doing object-oriented code in JS, please use the "prototype"
property, like the language is designed to do.

For more info, here's Brendan Eich on the subject:

<http://www.aminutewithbrendan.com/pages/20110216>

~~~
nxn
I don't even know if this can be considered the "closure" pattern anymore, but
I wanted to try to get method sharing among the objects by doing something
like this: <https://gist.github.com/877259>

The hope was that since the functions were created and bound within the
function literal, the "create" method could simply assign references to the
existing functions instead of creating a new function each time (ie, avoid
what munificent mentioned).

Funny thing is, even though the last line indicates that the first and last
objects' "ten" method is actually shared between them, I'm still getting about
370 MB of memory usage after creating 1 million objects. I am under assumption
that the cause of this memory increase is the fact that each one of the
million objects has its own local references to each of the 10 functions. When
I put the 10 functions inside of the "create" method, memory usage goes up
again to roughly 750 MB.

------
thegoleffect
You can also use CoffeeScript to get more "traditional" OOP from JavaScript.

~~~
jashkenas
In fact, they're both implemented in the same way, using the "standard"
JavaScript pattern for setting up a prototype chain. (With a few minor extra
features). Here's the annotated source code:

[http://documentcloud.github.com/backbone/docs/backbone.html#...](http://documentcloud.github.com/backbone/docs/backbone.html#section-115)

~~~
jimmydo
That's really what I liked the most about the Backbone implementation. It
stays very close to the standard JS pattern--essentially mirroring what
someone would do if they wanted to setup the prototype chain and attach
methods manually.

It asks you to name the constructor method 'constructor' (when it could've
easily been called something short like 'init' instead, for brevity). This
corresponds well with the standard 'constructor' property available on each
object, which points back to the constructor function that created the object.

The '__super__' property is also a nice convenience, without doing something
"fancy" like wrapping each method with logic that temporarily injects a
'super' property into the current instance for the duration of a method call.
Although that's definitely clever and convenient, I prefer the simplicity of
using '__super__'.

~~~
jashkenas
Interestingly enough, the fancy approach for calling "super()" is actually
prohibitively expensive ... making any method call in a subclass far slower
than it otherwise could be. I don't think it's a viable option for a baseline
library.

[http://www.broofa.com/2009/02/javascript-inheritance-
perform...](http://www.broofa.com/2009/02/javascript-inheritance-performance/)

------
wulczer
Shouldn't the first example read:

    
    
      george.roar(); // displays: "George, the lion ROARS!!!"

~~~
jimmydo
You're right! Fixed. Thanks for letting me know.

------
tbeseda
Slick but there has to be a way to do this without another utility. Backbone
objects already have an extend method.

~~~
jimmydo
Yup, I agree. I recently submitted a pull request for changes I made to expose
a primitive Base class in Backbone:
<https://github.com/documentcloud/backbone/pull/276>

