Difference between revisions of "JavaScript Classes"

From Exterior Memory
Jump to: navigation, search
(Created page with "Javascript 1 (Ecma-262, editions 3 or 5) is an object-oriented language that does '''not''' support classes. Instead, Javascript is ''prototype'' based, which gives many of th...")
 
(Design Pattern)
Line 190: Line 190:
 
===Design Pattern===
 
===Design Pattern===
  
A small overview of  
+
A small overview of the different variables and methods.
  
 
  // constructor function
 
  // constructor function

Revision as of 14:52, 19 September 2012

Javascript 1 (Ecma-262, editions 3 or 5) is an object-oriented language that does not support classes. Instead, Javascript is prototype based, which gives many of the benefits that classes also have, like objects and code-reuse. The distinction between a class and a prototype, is that a class behaves like a type, whereas a prototype behaves like a blueprint which you can instantiate and extend. (More experienced programmers may see an analogy here in the distinction between strict typed languages such as Java and dynamic typed languages such as Python and Ruby.)

Stoyan Stefanov wrote an excellent article: 3 ways to define a JavaScript class. Douglas Crockford (author of JavaScript)'s Private Members in JavaScript is also worth a read.

Objects and Arrays

Two ways to create an object:

var o = {};

var o = new Object();

o = {};

Three ways to create an array:

var a = [];

var a = new Array();

a = [];

Note: leaving out the var keyword performs an assignment. Only if the variable name wasn't created before, it will create a new object or array. It is recommended to always use the var keyword to prevent accidental assignments, and to prevent waste of time looking through the scope table.

Namespace

Create a namespace:

MyLibrary = {}
MyLibrary.Object1 = ...
MyLibrary.Object2 = ...

Function

Two ways to create a Function:

function myadd1(first, second) {
  return first + second;
}
var myadd2 = function (first, second) {
  return first + second;
}

To call a function:

myadd1(1, 2);
myadd2(1, 2);

Scope

To create a scope (for local variables) use an anonymous function (it's a hack, but it works):

( function() {
    // local variable
    var myvar = 3;
    
    // ....
}());

Classes

To create a prototype (create a class), use a function:

// constructor function
function MyClass () {
  this.variable = 0;
}

To add methods to the class, use the prototype property:

MyClass.prototype.setVariable = function (value) {
  this.variable = value;
};

MyClass.prototype.getVariable = function () {
  return this.variable;
};

An alternative, which is somewhat more readable is:

// constructor function
MyClass = function () {
  this.variable = 0;
}

// methods
MyClass.prototype = {
  setVariable: function (value) {
    this.variable = value;
  },
  getVariable: function () {
    return this.variable;
  }
}

Note that the following code gives the same result, but consumes more memory, since the methods would be recreated each time the class is instantiated. We'll see these again later (these are actually privileged methods)

// constructor function
function MyClass () {
  this.variable = 0;
  this.setVariable = function (value) {
    this.variable = value;
  };
  
  this.getVariable = function () {
    return this.variable;
  };
}

Class Instances

To instantiate a prototype (create an object):

// new object instance
var myObj = new MyClass();

myObj.setVariable(8);
alert(myObj.getVariable());

In the above example, variable is publicly accessible, so you can directly access it:

myObj.variable = 8;
alert(myObj.variable);

Static Methods

The static method is just a regular function. It uses the MyClass namespace, but has no relation with any MyClass object instance.

To create a static method (observe the difference with MyClass.prototype.method):

MyClass.staticMethod = function () {
    // ...
};

To call a static method:

MyClass.staticMethod();

Private and Privileged Methods

Variables declared within scope of a function are private, and can only be accessed from other private functions:

// constructor function
function MyClass () {
  var privateVariable; // private member only available within the constructor.
  
  var initData = function () {
    // ..
  };
};

The variable privateVariable and method initData() are both private: they can not be accessed from public methods. That makes them less useful.

A privileged method is a method that can be accessed by public methods and the outside, and can also access private variables.

// constructor function
function MyClass () {
  var variable = 0; // private variable
  this.setVariable = function (value) {
    variable = value;
  };
  
  this.getVariable = function () {
    return variable;
  };
}

setVariable() and getVariable() can be accessed from the outside, and manipulate the private variable. The disadvantage of protected methods (and of private methods) is that they are redefined every time the constructor function is called (thus they are redefined for every instance). This may take a bit of memory.

Some authors opt to make all variables and methods public, but use an underscore for low level methods that generally should not be accessed from outside.


// constructor function
MyClass = function () {
  this._variable = 0;
}

// methods
MyClass.prototype = {
  setVariable: function (value) {
    this._variable = value;
  },
  getVariable: function () {
    return this._variable;
  }
}

Design Pattern

A small overview of the different variables and methods.

// constructor function
function MyClass () {
  this.publicVariable; // can be accessed within constructor and from the outside
  var privateVariable; // can be accessed within constructor but not from the outside
  
  var privateMethod = function () {
    // it can access private members, and can not be accessed outside the constructor
    //..
  };
  this.privilegedMethod = function () {
    // it can access private members, and can be accessed outside the constructor
    //..
  };
};
MyClass.prototype.publicMethod = function () {
  // it can not access private members, and can be accessed outside the constructor
  //..
};