Reputation: 3399
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?
Upvotes: 7
Views: 898
Reputation: 14676
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
}
};
Upvotes: 2
Reputation: 6114
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.
Upvotes: 2
Reputation: 137320
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:
var
keyword,Upvotes: 1
Reputation: 49141
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
Upvotes: 1
Reputation: 2967
I have never used this personally, but have seen backbone.js referenced many times to this question. See at: http://documentcloud.github.com/backbone/
Upvotes: 1