Object orientation is naturally suited for applications such as games and simulations. In order to effectively utilize JavaScript in OO context, it is useful to understand how JavaScript handles data and functions.
JavaScript data types
JavaScript data types include: string, number, boolean, and objectvar aString = "abc";
var aNumber = 123;
var aBool = true;
var anObject = { val1: "abc", val2 : true };
- An object in JavaScript contains name-value pairs.
- Objects can be nested inside other objects
someObject : { x: 1} };
We can create an array of any data type. In addition, an array can contain items of different data types. Internally, arrays are simply JavaScript objects whose members can be accessed using a numeric index.
var anArray = [aString, aBool, anObject];
Functions as first class citizens
In JavaScript, a function can be assigned to a variable. The function can be invoked through the variable.var aFunc = function() { console.log("hello") ;};
aFunc(); // invoke the function
First-pass: Building an object in JavaScript
Using the above information, we can build an object (not class) in JavaScript.Let's say we want to build a circle object that knows its radius and can calculate its area and circumference.
// Javascript object that contains name-value pairs
// "radius" contains a numeric value of 4
var circle = { radius : 4 };
// "area" and "circumference" point to functions
// a function inside an object can reference other
// name-value pairs in the same object using "this"
// keyword (this.radius, for example)
circle.area = function() {
return 22/7 * this.radius * this.radius ; };
circle.circumference = function () {
return 2 * 22/7 * this.radius; }
// print out the result
console.log("area = " + circle.area());
console.log("circumference = " + circle.circumference());
// change radius and print out results
circle.radius = 6;
console.log("area = " + circle.area());
console.log("circumference = " + circle.circumference());
In the above code, we have hand-built a custom instance of an object. But what we really need is a way to construct multiple instances of an object from a class definition.
Second-pass: Defining a class and creating class instances
What if we wanted to create and retain many circle objects simultaneously? Or in other words, how do we automatically create area and circumference methods for all future instances of a circle class. JavaScript provides some syntactic sugar to accomplish this via prototype.In JavaScript, we also employ closures to mimic OO classes. Simply stated, in a function closure, nested functions have access to vars and parameters of parent function even after parent function is executed/returned. In the following example, radius is variable defined for the parent function Circle that is accessible to child functions area and circumference.
// JavaScript Constructor function is used to create a
// boilerplate (class) for an object type
// Constructor initializes properties of an object
// when the Constructor is called preceded by "new"
var Circle = function (radius){
this.radius = radius; // create and assign data member
};
// Through "prototype", functions (methods in OO terms)
// can be added to every new instance of the object
Circle.prototype.area =
function() { return 22/7 * this.radius * this.radius; };
function() { return 22/7 * this.radius * this.radius; };
Circle.prototype.circumference =
function() { return 2 * 22/7 * this.radius; };
function() { return 2 * 22/7 * this.radius; };
// Create and use multiple objects of Circle class type
var circle1 = new Circle(4);
var circle2 = new Circle(6);
// object properties can be accessed using the dot notation
console.log("circle 1 radius = " + circle1.radius);
console.log("circle 1 area = " + circle1.area());
console.log("circle 1 circumference = " + circle1.circumference());
// object properties can also be accessed using the indexer ["radius"]
console.log("circle 2 radius = " + circle2["radius"]);
console.log("circle 2 area = " + circle2.area());
console.log("circle 2 circumference = " + circle2.circumference());
A class defined using the constructor and prototype is still a plain old JavaScript object. Consider the following code:
circle1.anewproperty = 404;
console.log(circle1.anewproperty);
This code just defined a new property (a name-value pair) on a Circle object even though we never created such a property in the Constructor function.
var obj = {
valueOf: function () {return 1; }
}
var total = 4 + obj;
console.log(total);
Output:
5
A class defined using the constructor and prototype is still a plain old JavaScript object. Consider the following code:
circle1.anewproperty = 404;
console.log(circle1.anewproperty);
This code just defined a new property (a name-value pair) on a Circle object even though we never created such a property in the Constructor function.
valueOf member
Special member of object. Returns the numeric value of the object.var obj = {
valueOf: function () {return 1; }
}
var total = 4 + obj;
console.log(total);
Output:
5