0

Quick Note: OOP in Javascript is a topic that is beaten to death on Stackoverflow and elsewhere, but I cannot find this specific question answered anywhere.

The "hanging code" in Javascript objects has always bothered me, as it seems to break the flow of the code. What I mean by "hanging code" is the following:

function newObject()
{
    var thisObject = this;

    // HANGING CODE DOING VARIOUS THINGS SUCH AS
    // $('#someDiv').click(function(){}); OR
    // var someObjectLiteral = {value:'value'};
}

I wanted to mimic class-based OOP constructors by doing the following:

function newObject()
{
    var thisObject = this;

    function construct()
    {
        //WHAT USED TO BE HANGING CODE
    }

    construct();
}

Is any of the following true or likely to be true about the second methodology:

  1. It is significantly slower
  2. It will simply not work at all in certain situations
  3. It breaks proper coding practice
  4. It will be harder to debug
  5. There is a superior methodology to achieve the same result

Thank you.

4
  • 1
    What is the assignment to a global, thisObject = this, supposed to accomplish? Commented Sep 28, 2011 at 23:20
  • You're right. Should be var thisObject = this;. Poor sample code! Commented Sep 28, 2011 at 23:36
  • 2
    In my opinion your second example is less readable: if you showed me only your second example without any explanation I'd be left wondering why you have a function that is defined and then called immediately but not referenced anywhere else. What you are calling "hanging code" is not really "hanging" because it is already inside a function, and the function it is in is the constructor for your "class". It's still completely OO. The fact that it looks a bit different to a class-based OO language isn't a problem that needs solving because it isn't a problem at all. Commented Sep 29, 2011 at 0:09
  • @nnnnnn That is a perfectly fair statement. It may reflect my lack of familiarity with prototype-based OOP or my over-familiarity with class-based OOP. Commented Sep 29, 2011 at 1:24

2 Answers 2

2

There is nothing wrong per-se about wrapping code inside an inner function. The only thing you have to watch out is that you can't use this inside other functions (you need to use an intermediate variable such as yout thisObject.

Having taken that out of the way, I see no problem at all in having "hanging code" (at least the kind shown in your example). A language such as Java may have trained you to put everything inside a class but in Javascript you only really need to oop-things-up in cases where you explicitly want to take advantage of inheritance or polymorphism.

You probably need to get away from the oop mindset a little. For example, in your case, "hanging code" inside a new object constructor might look bad but I would instead just rename the function to "addClickHandler" or "setLiterals" and call it a day.

Sign up to request clarification or add additional context in comments.

2 Comments

This is a very reasonable point. I am letting the aesthetics of other languages influence how I code Javascript. Thanks.
"You probably need to get away from the oop mindset a little." - JS is still OO, so you want to stay with the OOP mindset. Just remember (as per Vivek's comment) that not all languages do OO the same way.
1

You could use something like the MooTools Class which will be slower than your method with the 'hanging' code. This is mostly due to the fact that the MooTools Class has overhead associated with their 'Native' structure. A lot of stuff you may not, and will likely not, need. It sounds like you want something straight-to-the-point.

You could do something like:

var Klass = function(attrs) {
    var key, newClass;

    attrs = attrs || {};

    newClass = function() {
        if(this.init) {
            this.init.apply(this, Array.prototype.slice.call(arguments));
        }
    };

    for(key in attrs) {
        newClass.prototype[key] = attrs[key]
    }

    return newClass;
};

Then, you could do something like:

var Person = new Klass({
    init: function(name, bg) {
        this.name = name;
        document.getElementById('container').styles.background = bg;
    },

    speak: function() {
        'I am ' + this.name;
    }
});

var tim = new Person('tim', 'blue');
// background now blue
tim.speak();
// 'I am tim'

var jane = new Person('jane', 'purple');
// background now purple
jane.speak();
// 'I am jane'

So, this code will fire off the init() when you make a new instance of a class. Passing it whatever arguments. In which you can put your 'hanging' code. Node that, due to the way prototypes work, this does not allow you to make a new instance of a new instance. And you would need to change it further to allow for things like building off of a parent class. But this is a pretty simple way of building a class structure.

This should work fine for what you want. If you were to come across something it "can't do" there will certainly be a way to correct that. You may just have to finagle the code. As I said in the previous paragraph. There will be a little overhead since a class is basically a function being returned, which you then make a new instance of. But nothing too significant. As for best practices, I would say it is not bad. There are a number of JS libraries that have quite extensive class structures in place for you to use. And a lot of people do use classes. But there are and will be arguments over the use of them since they are not real native JS types.

1 Comment

BTW I use the var Klass since class is a reserved word. Even though I could technically use the uppercase Class it is probably wise to shy away from it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.