0

I've been wondering for a long time how to do Javascript correctly, and I've read about it but never really tried anything myself. I chose to use the Object.create method. The con with Object.create is that there is no constructor function, which is something I kinda like. So I came up with my "own" way of including it.

My question is simply - is this a good way of doing Javascript OOP?

http://pastebin.com/AkG0KpAR

edit: updated Object.init

edit2: removed inline code and added pastebin link

William Boman
  • 2,079
  • 5
  • 26
  • 39

2 Answers2

2

I'll start by answering your question with how I would achieve your goal, but then provide you with how I would achieve it in a different way.

Your way is certainly one way of doing it, but I tend to flinch when people use JS OOP style since it's a prototypal language. It's far too big to discuss here, but you should read up on Douglas Crockford's Classical Inheritance in Javascript - he is considered one of the authorities on JS and was Yahoo's chief JS framework engineer for years if I recall correctly. This will help you understand how to approach OOP through JS.

However, JS is not really intended to be used that way. JS is a prototypal language, and you can achieve an incredible number of things using prototypes instead- and it's really not that much different.

Since you mentioned that you've been wondering how to "do javascript correctly", I'd say the following: If I were to achieve what you want, which is to add an init method to all objects, I'd target the object's prototype:

Object.prototype.init = function(){...}

A really solid approach to modular Javascripting is to make a function type that has a defined prototype like so:

var CalendarObject = function(){}  //<-- Essentially a class definition

CalendarObject.prototype = {
    init:function(){
        //Do init stuff
    },

    launchYear2k:function(){
        //Destroy the world
    }
}

To use this, all you have to do is make a "new" calendar object:

var c = new CalendarObject();

You can code this out just like most OOP style constructors. Anything you put in the CalendarObject definition function will be executed when you call new CalendarDefinition(). That means that you can auto-call the init function if you want, you can initialize variables, etc.

A serious boon to this is that protypes are JSON objects. That's it. If you know JSON you can understand how super powerful this can be. Read up on Crockford's site and you can start to see how to make getters and setters if you want that type of functionality but this is really, depending on what camp youre talking to, the "correct" way to code javascript. Technically this is faster/more memory efficient than using an OOP style as well since all objects reference the global CalendarObject rather than making a new object every time as well.

That's just my two cents.

dudewad
  • 13,215
  • 6
  • 37
  • 46
  • 1
    +1. Also, read up on Crockford's book [JavaScript, The Good Parts](http://www.amazon.com/JavaScript-Good-Parts-Douglas-Crockford/dp/0596517742) which covers this in depth. – Matt Johnson-Pint Dec 30 '13 at 01:12
  • Alright, I saw a [video](http://vimeo.com/69255635#at=890) telling that prototypes are old and `Object.create` is the new way. I didn't watch through the whole video so I might've missed something. I remade the code a bit and it looks like [this](http://pastebin.com/yyUhyaaJ) now (sorry for all the comments in it). Is that the way to go? – William Boman Dec 30 '13 at 05:18
  • 1
    Yep, looks like this could work fine. I caution you to understand that "prototypes are old" is an erroneous statement. That's like saying that classical inheritance or even constructs like arrays in C++ are old- of course they're "old"; they are the constructs of the language and the very fabric of what makes it unique. "Object.create is the new way" I think likely refers to "Object.create" may be the current up-and-coming industry standard to *simulate OOP classical inheritance techniques* in javascript. But object prototypes won't be going away anytime soon. It's part of what makes JS JS! :) – dudewad Dec 30 '13 at 06:14
0

Look at this answer to a similar question.

Also, check out Details of the object model from MDN.

JavaScript is a prototype-based language. You don't need to come up with your own way to define a constructor, unless you want to; JavaScript already supports its own way of doing it.

//constructor
function Ninja(name) {
    this.name = name;
}

//the "class"
Ninja.prototype = {
    swung: false,
    swingSword: function() {
        this.swung = !this.swung;
    },
    get: function(prop) {
        return this.prop;
    },
    set: function(prop,val) {
        this.prop = val;
    }
}

//instantiation
var awesomeNinja = new Ninja('Jet Li');

//show a member
awesomeNinja.get('name'); //Jet Li

//some random method
awesomeNinja.swingSword();  //this.swung = true    
Community
  • 1
  • 1
Josh Beam
  • 19,292
  • 3
  • 45
  • 68
  • I've done it that way before and honestly, I prefer my way. Is there anything that I miss out on when doing it my way? (I know `Object.create` isn't supported in old browsers but for this project I dont care) – William Boman Dec 30 '13 at 00:36
  • 1
    You miss out on people understanding your code. It's definitely not a crime to experiment with new things but you're sort of talking about reinventing the wheel here. – dudewad Dec 30 '13 at 00:37