JavaScript as an Object-Oriented Language

Although JavaScript is sometimes described as a prototype based OOL, it is in fact a class-based language. Its syntax is similar to Java except that its variables are not typed. Like Java, assigning an object to a variable makes the variable reference the object rather than getting a copy of the object.

In JavaScript, everything (except literals1) is an object (or can be treated like an object2). For example, functions are objects.

JavaScript Functions

The following syntax defines an anonymous function object.

function(x, y) {
return x*y
}

Function objects can be defined anywhere, even inside another function. They can be used like any other object: they can be assigned to variables and passed as parameters. They can even have their own instance variables and methods! This allows a function to serve as the constructor method for a class of objects3.

The example below assigns the above function to a local variable named product.

var product = function(x, y) {
return x*y
};

This is equivalent to the more usual function definition below.

function product(x, y) {
return x*y
}

Local variables in a function can be declared with the keyword var:

var name = value;

The keyword var is not required here - JavaScript variables do not need to be declared. However, if the keyword var is omitted the variable is global! . This can produce errors that are very hard to debug.

JavaScript Messages

JavaScript messages have one of two forms.

If the receiver is omitted the the implied receiver is the window object. The window object is, in effect, global. There are no other implicit receivers, even inside code for a class!

In JavaScript, an object can be treated as an associative array, similar to hashes in Perl and Ruby and dictionaries in Python. This means that you can access an object's members with the following syntax.

receiver[memberName]

Here, memberName is the name of the member as a string, not as a JavaScript identifier. This string can either be a string variable or a string literal. You can treat the above expression like a variable. For example, you can assign a value to it even if the string does not describe an existing member of receiver. This gives you the capability of adding members to objects even when the member name is not known when the code is written.

Autoboxing

JavaScript, like C++ and Java, has values of primitive type. However, it only has two primitive types: numbers and strings. Like Java, JavaScript automatically performs the following conversions when needed:

In Java, this conversion is called autoboxing. In either language, it allows primitive values to be treated as if they are objects.

Literals

JavaScript has literal values for its primitive types. Their form is similar to C, C++, and Java with the following exceptions.

Literals are the exception to the rule that everything in JavaScript can be treated like an object: a literal cannot be the receiver of a message.

Constructing Single Objects

A single anonymous object can be created with a comma-separated list of member definitions enclosed in braces. Each member definition has the following form.

name: value

Both instance variables and methods can be defined in this way. For methods, the value is often an anonymous function definition, but can also refer to a previously defined function.

Thus the general form of an anonymous object is the following.

{
name1: value1,
.
.
.
namen: valuen
}

As with functions, an anonymous object can be defined anywhere. It is often assigned to a global variable. When this is done, the object is used like a Java class whose members are all static. The members are accessed by sending a message with the variable as a receiver. The Log class is an example of this kind of construction. The comments indicate the form of messages sent to the Log class object.

Defining a Class of Objects

A class of objects is defined by defining a variable whose value is the constructor function for the class, and following it with definitions for static and instance members. Static members have the following form.

ClassName.memberName = value;

Instance members have the following form.

ClassName.prototype.memberName = value;

As usual, the value can be an anonymous function for static or instance methods.

The Circle class is an example of this kind of construction. The comments indicate the form of messages sent to the Circle class object or one of its instances.

Note that if code in an instance method sends a message to the instance, the receiver is specified with the keyword this. JavaScript does not make this the default receiver. Omitting the keyword this results in sending the message to the global window object!