Wednesday, April 25, 2012

Bare Minimum JS - Part 2 - Scoping

Scoping Things Out

In our last post, we talked about ways to create objects in order to keep our code tidy and organized.  The next concept we're going to explore is also a way to keep our code tidy and out of the way of each other; Closures and Scoping.

The Old and Busted way

Here's a common story.  You start out with just a couple pages on your website.  You don't see the harm in just throwing your javascript on each page, maybe even (<gasp>) directly calling javascript from html event attributes.  But, quickly, you've added a bunch of new objects to the global scope and if your application ever gets much more complicated your going to end up having a hard time finding what functions are firing and debugging code paths because of the lack of structure.


First off, shame on you for putting javascript in an HTML attribute.  Somebody has to make a value judgement at some point, and for me, it's javascript event handlers on HTML tags.  Sorry, had to be said.
The New Hotness

Here is a much more stable way to encapsulate your page logic using a "closure" technique.

Whoa.  Settle down.  I know, it's a little bit more complicated.  Let's start with the toughest thing on the page; the self executing function we wrapped everything in.

Breaking it Down

All we are doing is creating a function and immediately executing it.  The main reason we would want to wrap our code like this is to keep it out of the global scope and therefore more modular and tidy.  After running this function, we've created a new page1 object and subscribed to the document.ready event with the page1.ready handler all without any artifacts in the global scope.  Plus, we get a nice way to represent the logic on our page in an object oriented way.

The "use strict" is kind of esoteric, but it brings some helpful checks for some of the quirks of javascript.  I won't go too much into detail here, but check out John Resig's great article on strict mode.

Next, we use the handy dandy object initialization syntax we talked about in our last post to group together the functionality for page1.  Also, in the setupEvents() method I show an example of how to subscribe to events on elements in a more isolated way than putting functions in html attributes.

Next Time

Classes and scoping can really start to make your Javascript heavy projects much easier to handle.  But, it gets even better when we start to introduce another concept called the Module Export pattern.  Stay tuned, it's gonna be good for you, I promise.

Wednesday, April 18, 2012

Bare Minimum JS - Part 1

The Bare Minimum You Need To Know About Javascript

Part 1 -Getting Classy

These days, it seems JavaScript is taking over the whole earth.  Chances are, if you're starting a new project it's probably going to involve some JavaScript.


A wise man once told me, "JavaScript is for hackers" and, that is both a blessing and a burden for the common developers relationship with the language.  A common developer coming from a strict OOP language like C# or Java is going to be turned off by some of the functional concepts and the lack of an easy way to keep things modular and tidy.

With that in mind, let's dive in by introducing one of the basics that will help keep your code organized.

Get Object Oriented

JavaScript has two common ways to create an object.  First, let's take a look at the quick and dirty way to make an object.

That is the easiest way to just group a bunch of variables into a class.  It's quick and easy but has some downsides to keep an eye out for.  If you need to make a lot of these you're going to have to type that out a lot which could lead to fat-fingering it some place.  There's also the fact that the `speak()` function we created is an instance variable on each object, which means it will take up more memory than if we defined it in the more classical prototype fashion that would share the function across objects.

The classical prototype way is a little more verbose, but it comes with the benefit that we now have a way to really pump out some `Baby` objects if we needed to.  Notice the way we use `this` in the constructor to make instance variables on the object (more on the magic of `this` in another post.

My rule of thumb is to use the quick and dirty way when I'm making a "one off" object that is just temporary and won't have many instantiations.  

I try to be strict about using the classical approach when I'm creating something that will have more than one instance of itself in my app.

Next time, we'll talk about closures and some of the ways we can keep our newly created objects from banging into each other in the global scope.


Wednesday, March 7, 2012

Ramblings On the Magnitude of Our Work

I love code.  I like to write code, I like to read code.  I dream about code, sometimes good dreams, sometimes bad repetitive ones where I’m stuck in a for loop and can’t get out (anybody else ever have that dream?).

Although not the best metric, sometimes a project is measured by lines of code.  As of right now, the GDCT Next Gen site has over 10,000 lines of javascript code alone; not counting the server side code that handles the database interactions, authentication, logging, profiling and business rules.

Here is some code that updates a timer questions response.  There is certainly more code that this code relies on, but it’s the front line in how we start the process of updating the bubbles and scores for a timer question.

This is about 17 lines of a 1200 line file called pages.surveyTimers.js.  All of the code in this file is written by hand, none of it is generated by a tool; blood, sweat, tears and quite a bit of dubstep music have gone into every line.

... blood, sweat, tears and quite a bit of dubstep music have gone into every line.

But, there’s a bug in this code.  It’s a small one, a sneaky little one character bug that causes the score not to update in certain situations and in other situations the scoring bubble will not update either.  There is no compiler error in the console because of this bug, no indication from anywhere that there is an incorrect character that will cause 5 new tasks, and widespread panic, to be created.  This character could be the result of just a small instantaneous lapse in focus while refactoring one of the other 1200 lines of code in this one particular file; perhaps while adding a new feature or abstracting out this common code from somewhere else.

I wanted to share a bit of the magnitude of our work with you.  This app is no small feat of software engineering.  It’s a complex and mysterious bird.  That’s why when I hear about the tasks coming up as a result of testing, I am not disheartened.  No piece of software comes out perfect the first time and we have the processes in place to fix issues and respond to feedback.

Now Playing - M83 - Midnight City