2013/01/28

Doing OO - the JS Way!

I was fighting to understand how to do object-oriented design with Javascript for years and this week I finally think I'm onto something.

I keep seeing the same scenario almost every time I start a new project:
* Start simple, customer says. We don't need fancy UI, customer says. Just make it work on the back-end, let's not worry about async-shmasync.
* First delivery - beautiful, they say. But can we make a bit more pop-y, they say. Let's start by auto-updating the grid "dashboard" every 5 seconds.

So I start building a PageManager (I know, don't let me get started on the name). At first, it's only retrieving the dashboard. Then, I need to register any number of "widgets" that need to be updated async. After that - modal "dialogs", on-demand script loading, etc. It all goes (relatively) well until the third or fourth sprint where it becomes clear that it's all good and everything, but we need to do it a little bit differently in one specific section of the application.

And it was my brain-twister for a long time - how do I get to reuse what I already had in this PageManager and add on it or change it completely. In other words - how do I get to do my inheritance and overriding in Javascript? Is there even a way to do it?

Turns out there is. And it lies in the magic property of every object that is called prototype.

Now, when I set off to learn "proper" Javascript, I decided to take a classic problem and to use it to build a working solution. I chose Conway's Game of Life because it is simple enough to understand and design and yet gives me plenty of possibilities to experiment and learn.

So, the Game of Life consists of a rectangular plane where each cell is either dead or alive. This concept can be easily modeled with a simple class which has one boolean variable indicating whether the cell is dead or alive.

var Cell = function (isAlive) {
    var _isAlive = isAlive != undefined ? isAlive : false;

    this.IsAlive = function () {
        return _isAlive;
    };

    this.IsDead = function () {
        return !_isAlive;
    };
};

That looks pretty well and it works too. You can create new Cells, passing them the initial state. And when you ask them back whether they are dead or alive, they respond properly. Go on and try it now, if you want.

What if I want to create an alternate universe where the rules of the game remain the same:
- a living cell with 2 or 3 alive neighbors survives in the next generation
- a dead cell with exactly 3 alive neighbors springs to life

But in my universe once a dead cell is resurrected, it will be neither dead nor alive. It will be a Zombie, who can never die but will not count as alive when counting the poor souls.

Knowing a bit about the Javascript call hierarchy, my first attempt was this very simple code:

var ZombieCell = function () {

    this.IsDead = function () {
        return _isAlive;
    };
};

ZombieCell.prototype = new Cell();

Nothing too complicated, and it looks fine. With only one drawback - it doesn't actually work.
The first problem is that the _isAlive field is not visible from ZombieCell. Because it is, well, private!
The other problem is that the constructor logic is never executed. Not when you set the prototype and not even when you create zombie cells.

After a lot of experimenting and trying to find the best syntactic support (there isn't any), this is what I came up with.

var ZombieCell = function () {
    Cell.call(this, false);

    this.IsDead = function () {
        return false;
    };
};

ZombieCell.prototype = Object.create(Cell);

A few things worth noting:
- the prototype property has to point to a valid "instance". Since my base class has constructor parameters, I had to use Object.create() to get one
- although the prototype points to a valid base class instance, the construction logic is NOT inherited and has to be explicitly invoked using call()
- ZombieCell cannot see the private variable _isAlive. Because it is exactly this - private, which means it is not visible by anything else but the entity that declares it.

2013/01/07

Start Simple - Equivalence is NOT Equality

If you, like me, come from a curly-brace language, Javascript has some surprises for you. And not all of them are nice.

One of the first face-palm moments I had with Javascript was with the equality operators. Or what I thought were the equality operators. Because, you see, in C++ and C#, == means "is equal to" and != means "is not equal to". And they are type-safe, so you can't easily shoot yourself in the foot (unless you overload them).

So you happily start using them churning out validation code until you realize there is something wrong - comparisons sometimes work, but sometimes don't. And they are not always transitive. What's is going on?

First, you have to be sure that you are comparing apples to apples. Are you really comparing numbers to numbers? Look closer:

Hmm. So comparing a number to its string representation works - magically. Neat, you think, it simplifies code. Then what about
Hey, that's really neat - automatic type conversion. But what if I don't want it? Is there a way to get rid of it?

Turns out there is. Because these two operators are not testing equality - instead they are testing equivalence.
In general numbers are equivalent to their string representation (as is NaN), but dates (Date objects) are not. null is equivalent to undefined but to nothing else.

Now, if I want true equality, there is one solution - the triple equal (===) and its triple non-equal buddy (!==). The previous examples then become


Next time you are chasing weird validation bugs, think whether:

  • you are comparing the right things (numbers to numbers)
  • you are comparing what matters (actual value vs string representation).
Rules of thumb to decide which one to use (work for me, feel free to use them or leave them)
  • Good candidates for equivalence are cases where type conversion does not matter or is even welcome. Think integer-to-float comparisons. null-to-undefined is also a good candidate.
  • Think hard what kind of input you receive in your routines. If it is whatever jQuery's val() is returning, you are better off parsing it to the target  type first and then deciding which one of the two approaches is best.
  • In general avoid comparing anything to strings (unless it is also a string).
A lot of bugs and confusion can be avoided if you remember - equivalence is powerful, but it is not transitive. If a == b and b == c, it does not mean that a == c.
Equality is strict, but it is often more straight-forward, with less nasty surprises. And yes, if a === b and b === c, you are guaranteed that a === c.

2013/01/05

The Beginning

I am starting this blog as a part of a new year's resolution - to start contributing to the programming community.

Recently I realized that I have many things to say, I just didn't know it. And I didn't know how to say it.
But now I know I can share what I know and it doesn't matter much how I do it. So a blog it is.

I come from a hard-core programming background. Back when I started, I was programming in C++ for Windows. Then the .Net Framework appeared and I started using it to create simple websites running on ASP.Net. Only after ASP.Net MVC became available I really grasped the power of the web. And it has been an adventure ever since.

This year my primary goal would be to learn mobile programming for Windows 8 using HTML 5 and Javascript.

Jump on the train with me to join the adventure!