Concise Object Oriented Javascript
I learned a lot about Javascript this summer. I wrote a blog post about one of my more useful revelations:
http://blog.gageh.us/object-oriented-javascript/
Here's the post. Sorry about the weird code formatting. Not sure how to fix that on here.
Contrary to its name, Javascript has little to do with Java. It’s not based on Java, it doesn’t run on the JVM, apparently it’s just a marketing term. What Javascript really is, or was meant to be, is Lisp with C style syntax. That little nugget only really helps you if you know Lisp and C. If you do know both you might say, as I did, “Ah, now it makes sense.”
The hard thing about Javascript, coming from an object oriented worldview, is that you’re not sure at first if you should treat it like an imperative language, like C (do this, then that, then that, then that…), or an OO language, such as C# or Java (make one of these, then make it do this). The answer is neither. The answer is that Javascript is multi-paradigm.
Is it functional like Lisp? Yes.
Is it object oriented? Yes.
Is it imperative/scripting? Yes.
If you’re reading this then you’re interested in, like I was, learning how to better organize your Javascript code, similar to how you organize your C# or C++ or Java code. Maybe you write a lot of Javascript already and it’s a mess. You find yourself thinking, “Gee, I wish I could make this var private.” and “Man, if only I could stick this JQuery stuff I use all the time into a nice neat container, then I wouldn’t have to worry about all those nasty ‘$’ symbols and selectors anymore.”
Okay, let’s dive right into some examples.
We’ve all written this kind of thing before:
$(document).ready(function(){
function openTheMenu() {
$('.contact').addClass("selected");
$('.contact').addClass("menuLinkHoverOrVisit");
$('#menu').animate({
bottom: '0px'
});
menuClosed = false;
}
function closeTheMenu() {
$('.contact').removeClass("selected");
$('.contact').removeClass("menuLinkHoverOrVisit");
$('#menu').animate({
bottom: '-330px'
});
menuClosed = true;
}
});
It’s not great and I’m sure you’ve seen a lot worse. Unfortunately it’s only going to get more complex as our app grows. Let’s clean it up and start organizing it before it’s too late.
We will start by making ourselves a class called Menu. You might want to put this in a seperate .js file. Maybe menu.js?
function Menu () {
this.contactButton = $('.contact');
this.menu = $('#menu');
this.isClosed = true;
}
The two members assigned to “this” (which will be our menu object) are references to the jQuery objects we will be using. Those two lines are the last time we’ll have to use jQuery syntax in this tutorial.
Next we need those two functions, “openTheMenu” and “closeTheMenu”, to be members of our class. Let’s add the following to our menu.js file under the Menu constructor.
Menu.prototype.open = function () {
this.contactButton.addClass("selected");
this.contactButton.addClass("menuLinkHoverOrVisit");
this.menu.animate({
bottom: '0px'
});
this.isClosed = false;
};
Menu.prototype.close = function() {
this.contactButton.removeClass("selected");
this.contactButton.removeClass("menuLinkHoverOrVisit");
this.menu.animate({
bottom: '-330px'
});
this.isClosed = true;
};
There are a few different ways to add member functions to a class. For a more in depth explanation, read this: http://eloquentjavascript.net/chapter8.html
Important
There is one more thing to remember. Javascript has no way to make something “private” other than by placing a var or function inside of another function. If you do that then the var or function is local to its containing function. It can not be accessed outside of it.
Written by Gage Herrmann
Related protips
4 Responses
Man, that's one sweet bit of explanation to what could OOP in js!
One think I always remember is that thinking of private vars, methods or objects, one should always have one word in mind: "scope". Each time you define something in js, no matter if in an object, function, or the document itself, always have the word "scope" on a sticky note in the right edge of the screen! Saves hours of debugging sometimes.
Thanks!
I'm giving a presentation on this at work on Monday. I'll definitely throw the word "scope" in there a few times.
Good stuff! Thanks!
@gagege Thanks for the endorsement! Hope you didn't hit someone on the head with the scope trows ;) joking