This is the second part of the JavaScript Quirks for Classical OO Developers. I will cover a bit of the most important things that you may have missed (I certainly did) with JavaScript as a C#/Java Developer without going into too much detail and some references for further reading.

How do I create a class?

In C# and Java, it is simple to think about how you would write a class - it is the blueprint for objects in its purest form - your object is simply an instance of a type (class) that has some methods. In JavaScript, writing a class isn’t quite as obvious, so here are some common patterns used for writing your class.

Before we go into the common patterns though, what is a class in JavaScript? Well, good point, there is no class in JavaScript. You have a type, function and object.

A class then in JavaScript is simply a constructor or a function that binds things to this or its prototype or a function that returns an object.

Anonymous Object

Anonymous functions allow creation of Objects without the need for Constructors. The anonymous Object is most commonly used for passing as arguments - you’ll see this commonly used in jQuery plugins for passing option arguments.

1
2
3
4
5
6
7
8
9
10
var chuckNorris = {
    name : "Chuck Norris",
    logName: function()  {
        console.log(this.name);
    }
};

console.log(chuckNorris.logName()); // Chuck Norris
chuckNorris.name = "Bruce Lee";
console.log(chuckNorris.logName()); // Bruce Lee

Revealing Module Pattern

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function Person(name)
{
    // private
    var name = name;

    // private function
    function MyFunction() {
        console.log("hello " + name);
    }

    // another way of creating private function
    var AnotherPrivateFunction = function() {
        console.log("hello " + name + " this is AnotherPrivateFunction");
    }

    // return anonymous objects with functions bound to them
    return {
        MyFunction: MyFunction
    };
}

This is also known as the “Revealing Pattern”. With this pattern, nothing is exposed to public, instead, it returns an anonymous object at the end with everything defined exposed to public. This makes it easy for developers to see what’s available for them to use and this also makes it a bit easier to decide later what needs to be exposed and what needs to remain private without much modification. This approach makes use of the fact that JavaScript keeps the state of variables inside a function, so long as it is referenced somewhere - in this case, it is referenced by the returned anonymous object.

The revealing module pattern keeps track of its state using closure shown in part 1.

The problem with this pattern when used purely by itself without the use of prototype is that you are essentially having a copy of each and every single function you define in each instance of your Object - it is highly encouraged to share functions using a prototype.

To demonstrate, see this example:

this

1
2
3
4
5
6
7
8
9
10
11
12
function Person(name) {
    this.name = name;

    var sayName = function() {
        console.log(this.name);
    }

    this.sayName = sayName;
}

var me = new Person("Andy");
me.sayName() // Andy

This one is a fairly common pattern, simply bind the object to this to expose for public use - this has the same issue as revealing pattern where you are duplicating a function over and over again for each object created.

Let’s have a look at how using this looks in the heap.

Notice that this.sayName for each Object memory reference are different, each one taking up 36 bytes.

Prototype

1
2
3
4
5
6
7
function Person(name) {
    this.name = name;
}

Person.prototype.sayName = function() {
    console.log(this.name);
}

This should be your preferred way of adding functions whenever possible as this makes the function shared through the Object’s prototype - it is highly performant and costs less on memory since functions are shared across multiple Objects rather than having a copy of the function for each Object instance.

Remember that an Object’s prototype is shared between all Objects inheriting from the same prototype.

Check this example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function MyType(value) {
    this.value = value;
}

MyType.prototype.logValue = function() {
    console.log(this.value);
};

var myObj1 = new MyType('world');

myObj1.logValue();

// add new prototype method
MyType.prototype.logValueWithHello = function() {
    console.log('hello ' + this.value);
};

var myObj2 = new MyType('larry');
myObj2.logValue();
myObj2.logValueWithHello();

// myObj1 also received a new method
myObj1.logValueWithHello();

Notice that myObj1 also received a new method named logValueWithHello even though it existed before we added the new method. To truly understand the nature of prototype, check mozilla’s write-up on Inheritance and the prototype chain.

Wow, prototype is cool, that means I can add new functions to pre-existing objects, so that means I can add new functionalities to built-in types like string and array right? Before you think of doing this, think again… It’s usually better to just create a wrapper that adds functions to the object (as what jQuery does) or create a helper/utility function - otherwise you will have the headache of having to ensure that no name’s ever clash with the native methods.

Let’s see how this is referenced in our heap.

Notice that both methods have the same reference.

Further Reading

Addy Osmani’s book - JavaScript Design Patterns

Checking equality

== Might not be what you expect it be. == operator compares only by value, === on the other hand compares both type and value without coercion.

Some examples to illustrate:

1
2
3
4
5
6
7
8
9
10
11
12
13
1 == "1"  // true
1 === "1" // false
0 == ""   // true
0 === ""   // false
0 == "0"   // true
0 === 0    // true
1.0 == 1  // true
// JavaScript only has a single primitive type of numerical values, which is a double precision floating point
1.0 === 1 // true
true == 1   // true
true === 1  // false
false == 0  // true
false === 0 // false

Funnily enough, NaN doesn’t equal to itself or any value for that matter as the code example below shows.

// all of these return false
NaN == NaN;
NaN === NaN;
NaN == 0;
NaN == false;
NaN == null;
NaN == undefined;

Since NaN is the only type not equal to itself, you could check for NaN by doing something like this:

1
2
3
function isNaN(x) {
    return typeof x === "number" && x != x;
}

Just a fun fact :).

Truthy and falsy

In JavaScript, when you use any value in place of a boolean in an if statement, they are coerced into boolean value known as truthy or falsy value - so you need to understand what the current’s truthy or falsy value of the type you are using.

Find the truth table for JavaScript here

Other Concepts you need to understand

People to follow

  • Douglas Crockford
  • Addy Osmani
  • Nicholas Zakas
  • Paul Irish
  • John Resig

Books

JavaScript is a fun language, it’s easy to get into but difficult to master - have fun !!