Despite what you might believe JavaScript does not actually have classes. But you can emulate them using functions, variables, prototypes and closures.

There are many ways of making classes each has advantages and limitations so I will go over each of them in turn.

Let’s start at the beginning with the most basic element. The Variable.

 
var widget = "orange";
A variable can hold many kinds of data and properties but the most important thing to remember about it is that it can hold anonymous objects.  And in javascript everything is an object. Even “orange” is an object with a set of properties and methods that I could use to manipulate it. But that is for another lesson. Just keep in mind that variables are able to point to elements with and without names.

The next most important element is the Function.

function widget(color) {
    return color;
}

The function allows me to store a series of commands, variables and even further functions. The problem with this is that all of it is public. But there is a trick to solve that.

The first way to create a class is with a function.

function widget(color){
    this.color = color;
    this.price = 3.95;
    this.name = "widget";
    this.whatIsThis = function(){
        return 'this is a " + this.name;
    }
}

This is obviously a function. But we can use it like a class to create multiple widgets by instantiating it.

var box - new widget("blue");
box.name = "box";
console.log(widget.whatIsThis());
console.log(box.whatIsThis());

As you can see this doesn’t actually affect the widget. It is still the same. By instantiating it we can use it like a class to duplicate it into individual objects with all of the same properties and methods of the original function.

One of the problems should be obvious. I was able to change the name. Nothing is private using this version.  Another problem is that class is completely recreated when instantiated.  You may not want to waste the overhead recreating every method and property, especially in larger applications. whatIsThis() is a perfect example. It is always the same and it doesn’t store any values. There is a way to optimize this class using prototype.

function widget(color){
    this.color = color;
    this.price = 3.95;
    this.name = "widget";
}

widget.prototype.whatIsThis = function(){
    return 'this is a " + this.name;
}

By adding whatIsThis() using prototype it uses less overhead.  The method only exists on the original class, in this case widget. But all the objects created from it can still call whatIsThis() since it is inherited through prototype. Otherwise it is used the same as the previous version.

You can also add multiple properties using prototype with curly brackets.

widget.prototype = {
    whatIsThis: function(){
        return "this is a " + this.name;
    },
    weight: "1 unit",
    size: "1 Square meter"
}

 

var box - new widget("red");
box.name = "box";
console.log(widget.whatIsThis());
console.log(box.whatIsThis());

The second way to make a class is to use an object literal.

var widget = {
    color:"red",
    price: 3.95,
    name: "widget',
    whatIsThis: function(){
        return "This is a " + this.name;
    }
}

An object literal unlike a function cannot be instantiated since it effectively builds the object at the instance.

Now I had mentioned being able to make the methods and properties of a object private. To do that we have to use another design pattern, called a Module.

var widget = (function(){
  var price = 3.95;
  var name = 'widget';
  var color = 'blue';
  return {
      name: name,
      color: color,
      whatIsThis: function () {
        return 'This is a ' + this.name;
      }
   };
})();

This uses what is called a closure. The parenthesis enclosing the function cause it to be evaluated as an expression. That is it runs the function and looks for the result. Usually once it runs all the properties and methods inside of it would be lost instead it is passed on to the following parenthesis. This keeps the variables alive but they are  unreachable. The properties and methods returned get attached to the variable name and can be called normally. This means that I can call whatIsThis() or change the color. The name property, since it wasn’t returned, is unreachable since it is out of scope.

There is also ways to create empty objects that you can then attach properties and methods to.

These are collectively known as Constructor Patterns.

var widget = {};

This is the first one. We used this before to create a object literal. Since it is built into a variable it is instantiated at the time of creation.

 

var widget = Object.create(Object.prototype);

var widget = new Object();

These are new but work the same way as the pervious way. All three of these work like singletons since they are all instantiated at creation.

To add properties and methods you can use dot syntax or square bracket syntax.

widget.color = "yellow";

This will create a property color in widget and assign it the color  yellow.

 

widget[name] = "widget";

This works the same as the previous one and will assign a value to the property name.

 

widget.whatIsThis = function(){
    return "I am a " + this.name;
}

The method created this way works the same as the standard function.

This is the first of many articles on classes and design patterns. If you are interested in learning more about object literals check out Rebecca Murphey’s article. It is a great read. If you want to learn some more on Singletons check out this IBM article on their usage here.