6. What Are JavaScript Custom Objects
In both JavaScript and general programming, an object is a package encapsultating properties (attributes and values) and methods (functions)
Objects provide both an efficient set of structures for storing, retrieving and manipulating complex data structures, as well as a useful metaphor in structuring programs and applications.
JavaScript incorporates a number of Object Oriented (OO) features. These include the built-in objects and methods covered in the next two sections: Part 7: Built-in Objects and Part 8: Built-in Methods
In addition JavaScript allows users to define and manipulate custom objects which is one of its most powerful (though frequently deprecated) features.
While all of this may sound complicated, custom JavaScript objects are in fact painfully simple to define (prototype) and provide a terse, kicky .dot notated syntax for retrieval and manipulation.
Ain't Got No Class:
Developer's already versed in other OO languages should note that object oriented programming in JavaScript is a little different than the paradigm common to the familiar class based OO languages (C++, Java, et al.)
This reflects both language design differences (prototyping) as well as genuine limitations (single generation inheritance).
For folks already familiar with OO programming, the most important difference is that JavaScript is a prototyped language. This means that JavaScript omits the class structure commonly used in other languages to group related objects, properties and methods.
In place of static class definitions, and as more thoroughly set forth below, a JavaScript object is initially declared (prototyped) by a bare constructor function -- typically defining and/or initializing at least a core set of child properties.
6.1 Prototyping Objects
An object's prototype is an empty pattern defining the object and its properties before any instances have been created.
The basic elements of the object's prototype are typically declared in the form of an otherwise ordinary function (called a constructor) using something like the following general syntax:
function object-name ([param_1][,param_n]){
[this.property_1 = param_1]
[this.property_n = param_n]
}
Note that the keyword this in the examples above is a bit of shorthand in this case referring to the instance of the object being initialized by the constructor.
function Example (param_1, param_2) {
this.property_1 = param_1;
this.property_2 = param_2;
}
Also note that the properties have been declared as required, named parameters -- which will be passed to the constructor at the time an instance object is created (see, below 6.1).
However, a contructor may include no required parameters and/or declare additional properties initially set to a null value (""), an Array, or even the results of an operation (including the return value of another function):
function Example (property_1, property_2) {
this.property_1 = property_1;
this.property_2 = property_2;
this.property_3 = "";
this.property_4 = new Array();
this.property_5 = '<p>'+this.property_1+'<p>'+this.property_2;
this.property_6 = format(this.property_1, this.property_2);
}
Here is a somewhat more practical example of a constructor that declares the prototype of an object named Employee (encapsulating, it's worth noting, many of the values used in the associative array, control structures and function examples found in Part 2, Part 4, and Part 5):
Listing 6.1
function Employee(lname,fname,phone,office,title) {
this.lname=lname;
this.fname=fname;
this.phone=phone;
this.office=office;
this.title=title;
}
6.2 Initializing An Instance
And, here is how a new instance of the Employee object would be declared passing values for the named properties to the object's constructor function using the key word new
Listing 6.2
var employee_1=new Employee("Glenn","Gould","537","A111","Manager");
6.3 Referencing Instance Properties
And here is how the .fname and .lname properties would be referenced by another script:
Listing 6.3
document.write(employee_1.fname + " " + employee_1.lname);
6.4 Creating Multiple Instances
Like everything else in programming, objects become more useful through repitition. So here is an array employees which we will use to hold multiple instances of the Employee object:
var employee=new Array();
And Listing 6.4 shows how a list of Employee objects might be created and (selectively) printed:
Listing 6.4
var employees=new Array();
employees[0]=new Employee("Glenn","Gould","537","A111","Manager");
employees[1]=new Employee("Allan","Marx","542","B101","Staff");
employees[2]=new Employee("Janet","Maxwell","547","B109","Staff");
employees[3]=new Employee("Mary","Peters","534","A112","Manager");
employees[4]=new Employee("Karen","Simms","548","B107","Staff");
employees[5]=new Employee("Carl","Wilson","541","B105","Staff");
for(i in employees) {
if(employees[i].title == 'Manager') {
document.write( "<p>" );
document.write( employees[i].fname + " " );
document.write( employees[i].lname + "<br />" );
document.write( employees[i].title + "<br />" );
document.write( "x " + employees[i].phone + "<br />" );
document.write( "Room " + employees[i].office );
document.write( "<\/p>" );
}
}
To this point in the discussion objects have provided a useful (and highly compact) data structure. However, they have also probably seemed something like a fancy version of the associative array examples reviewed in Part 2.
And in fact -- as will be further discussed (see below, 6.6) -- to the JavaScript parser, the properties of a custom object look very much like the key value pairs of associative array indeed.
However, a formally prototyped object holds at least one advantage over a generic array, and that is its ability to support custom, object-specific methods.
6.5 Adding Methods
A method is assigned as a generic function to a named property of the object. This is done via the object's prototype property using something like the following generic syntax:
object-name.prototype.method-name = function () {
[statements]
}
Here is a method .record() which will be assigned to the Employee() object.
This method, much like the function record() found at the end of Part 5, returns a formatted string in this case encapsulating the properties of the Employee object calling the method.
Listing 6.5.1
Employee.prototype.record = function () {
itemrecord = "<p>";
itemrecord += this.fname + " ";
itemrecord += this.lname + "<br />";
itemrecord += this.title + "<br />";
itemrecord += "x " + this.phone + "<br />";
itemrecord += "Room " + this.office;
itemrecord += "<\/p>";
return itemrecord;
}
Note that like the Employee() constructor the .record() method makes generous use of the keyword this.
And again this serves as a short hand reference to the instance of the object, in this case, invoking the method.
Here, for example, is how an instance of the Employee object in the employees array above would call the .record() method:
employee[0].record();
Within the scope of the called method each of the following conditions would now be true:
this.fname == employee[0].fname;
this.lname == employee[0].lname;
this.title == employee[0].title;
And here is how each member object in the employees array would call the .record() method in turn:
Listing 6.5.2
for(i in employees){
document.write( employees[i].record() );
}
6.6 Objects & Associative Arrays
At least in regards to their properties, all JavaScript objects (both user-defined and built-in) are also associative arrays.
The following are all valid references to the .fname property of the first instance of the Employee object stored in the employees array:
employees[0].fname;
employees[0][fname]
employees[0]["fname"]
Listing 6.5.2
for(keys in employees[0]) {
document.write( keys+": "+employees[0][keys]+"<br />" );
}
Part 6 of 10 | Next Part 7: Built-in Objects >