4 ms·
Simple JavaScript Inheritance with Backbone
- thegoleffect 16y agoYou can also use CoffeeScript to get more "traditional" OOP from JavaScript.
- jimmydo 16y agoCoffeeScript does have really nice syntax for OOP, but I think JavaScript deserves some lovin' too. Well-written JavaScript (such as Backbone) looks pretty beautiful. Another plus is that new devs (if you have to worry about that sort of thing) don't have to learn a new language.
- krmmalik 16y agoYes, that would be me. I'm still getting my head round Javascript, cant take something new on at the moment. I havent even learned what inheritance is yet, so have no idea how Backbone.js would benefit me, even though im working on a project where i need to use a class.
- jashkenas 16y agoIn 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#section-115 http://documentcloud.github.com/backbone/docs/backbone.html#...
- jimmydo 16y agoThat'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 16y agoInterestingly 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-performance/ http://www.broofa.com/2009/02/javascript-inheritance-perform...
- jpallen 16y agoWhen 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.
- tbeseda 16y agoSlick but there has to be a way to do this without another utility. Backbone objects already have an extend method.
- jimmydo 16y agoYup, 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 https://github.com/documentcloud/backbone/pull/276
- city41 16y agoI'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?
- oscilloscope 16y agoTake a look at the source-- Backbone itself is written in the module pattern. Underscore and Backbone will both teach you a lot. This chapter from Eloquent Javascript will also help motivate the rationale behind Underscore: http://eloquentjavascript.net/chapter6.html http://eloquentjavascript.net/chapter6.html
- jimmydo 16y agoThe mostly likely reason is probably familiarity. Most languages use the 'new' operator to create new objects, so it seems natural to follow the same pattern when creating a JS API that will likely be consumed by people who come from other languages. The main advantage of Douglas Crockford's power constructor pattern is that it allows truly private variables or functions. I used to be adamant that this was the right way to go (and I still appreciate the pattern), but then I found that just following the convention of prefixing private members with an underscore worked fine--most people understand that it means "private". My code also started to look a little neater. All of my instance members are actually tied to the 'this' context object, rather being spread between nested functions or local variables declared within the constructors, and public/privileged methods declared on the new object itself.
- munificent 16y agoPerformance. 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 16y agoAs 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 http://www.aminutewithbrendan.com/pages/20110216
- wulczer 16y agoShouldn't the first example read: george.roar(); // displays: "George, the lion ROARS!!!"
- jimmydo 16y agoYou're right! Fixed. Thanks for letting me know.