7

I've recently been playing with javascript, HTML5, chrome extensions, jQuery, and all that good stuff. I'm pretty impressed so far with the possibilities of javascript, the only thing I struggle with is structuring my code and keeping it tidy. Before I know it, functions are scattered all over the place. I've always done my programming in an object oriented manner (C++ and C#), and I find myself not being able to keep things tidy. It feels like I always end up with a bunch of static util functions, were I to 'think' in C#.

I've been looking for some information on objects in javascript, but it seems to come down to wrapping functions in functions. Is this a good way of structuring your codebase? On the surface it seems a bit hackish. Or are there other ways of keeping things tidy for an OO mindset?

3
  • 1
    addyosmani.com/blog/essential-js-namespacing and dustindiaz.com/namespace-your-javascript are good reads Commented Dec 29, 2011 at 21:34
  • "Wrapping functions in functions" isn't "hackish" at all. Haskell programmers do it all the time. Commented Dec 31, 2011 at 0:05
  • I've since read up on functional programming and closures and you're right. It's just a bit of a mindset change from OOP, so it at a first glance it might seem a bit odd. Commented Dec 31, 2011 at 0:08

5 Answers 5

2

One important aspect to remember about Javascript is that it is a prototypical language. Functions can be objects, and anything can be put on the object, often affecting related objects in the process. There's no official way to 'extend' an object because of this. It's a concept that I still have a hard time understanding.

Javascript 'acts' like any other OOP language for the most part, with some exceptions, namely extending objects (http://jsweeneydev.net84.net/blog/Javascript_Prototype.html).

After extensive research, I did find a very, very light-weight way to simulate expanding objects (I'm using using it in my GameAPI). The first field is the parent object, the second is the object that expands.

extend  : function(SuperFunction, SubFunction) {

    //'Extends' an object

    SubFunction.prototype = new SuperFunction();
    SubFunction.prototype.constructor = SubFunction;
},

This link might clear up some problems and misconceptions: http://www.coolpage.com/developer/javascript/Correct%20OOP%20for%20Javascript.html

Personally, I tend to be anti-framework, and I haven't seen a framework yet that doesn't force the programmer to significantly change their programming style in this regard anyway. More power to you if you find one, but chances are you won't really need one.

My best advise is to try to adapt to Javascript's prototypical style, rather than force old methodologies on it. I know it's tricky; I'm still trying to myself.

Best of luck diggingforfire.

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

Comments

2

I generally follow the make-an-anonymous-function-then-call-it pattern. Basically, you create an inner scope and return a single object containing your interface. Nothing else escapes, because it's all trapped within the function scope. Here's an example using jQuery:

var FancyWidget = (function($) {
    // jQuery is passed as an argument, not referred to directly
    // So it can work with other frameworks that also use $

    // Utility functions, constants etc can be written here
    // they won't escape the enclosing scope unless you say so
    function message(thing) {
       alert("Fancy widget says: " + thing);
    }

    // Make a simple class encapsulating your widget
    function FancyWidget(container) {
        container = $(container); // Wrap the container in a jQuery object
        this.container = container; // Store it as an attribute

        var thisObj = this;
        container.find("#clickme").click(function() {
            // Inside the event handler, "this" refers to the element
            // being clicked, not your FancyWidget -- so we need to
            // refer to thisObj instead
            thisObj.handleClick();
        });
    }

    // Add methods to your widget
    FancyWidget.prototype.handleClick = function() {
        this.container.find("#textbox").text("You clicked me!");
        message("Hello!");
    };

    return FancyWidget; // Return your widget class
                        // Note that this is the only thing that escapes;
                        // Everything else is inaccessible
})(jQuery);

Now, after all this code executes, you end up with one class, FancyWidget, which you can then instantiate.

You can define multiple classes this way too; instead of using return FancyWidget, you can return an object literal instead:

    return {
        FancyWidget: FancyWidget,
        Frobnicator: Frobnicator,

        // Nested namespaces!
        extra: {
            thing: thing,
            blah: blah
        }
    };

Comments

1

One of the best OOP javascript libraries out there is Google's Closure library http://closure-library.googlecode.com/svn/docs/index.html

It's structured in a way that OOP programmers will be familiar with especially if you come from a java/C# background. Have a look at the source code of any file and it should feel right at home as an OOP programmer. http://closure-library.googlecode.com/svn/docs/closure_goog_graphics_canvasgraphics.js.source.html

1 Comment

The source does indeed look very familiar, and the usage of closures gives me a pretty good idea of how to work things out.
1

I have never used this personally, but have seen backbone.js referenced many times to this question. See at: http://documentcloud.github.com/backbone/

Comments

1

Using some framework designed to meet similar requirements may be a good idea.

But there are some things you should really follow to be efficient:

  • remember about closures in JavaScript and do not forget about var keyword,
  • use callbacks where possible and reasonable, JavaScript is asynchronous by nature,

Comments

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.