# Tutorial 15 - User-Defined Objects Tutorial 14 - Regular Expressions - Javascript Tutorial Appendices Larger projects require the use of many specialized objects of a similar type. In modern languages this is normally done with user-defined objects. This tutorial shows you how to create your own specialized user-defined objects and explains the issues of constructors, prototypes and inheritance. This tutorial also describes JSON, a cross language data interchange format. Note: This page assumes familiarity with basic Object Oriented Language principles! ## Object Constructors Object constructors can be thought of as templates for making objects. As a simple example, rectangles contain several basic properties (aka variables). A simple template is:
    // define a constructor with properties
    function Rectangle(w,h) {
       this.width = w;
       this.height = h;
       }
Note that Rectangle has its initial letter capitalized. This indicates that it is a constructor function (similar to a class in Java). The keyword this refers to the current object that called the constructor function. It identifies constructor objects and is not normally used otherwise. ## Defining Methods in Constructors Methods may also be added to constructors. However they must be defined first. The names used in this definition are not important but one convention is to prepend the method name with constructor name and an underscore. It is also good pratice to keep the defining methods and the constructor that uses them near each other (maybe using comments to help).
    // define some methods to be included in Rectangle object
    function Rectangle_area() {return this.width * this.height;}
    function Rectangle_perimeter() {return 2 * (this.width+this.height);}
    function Rectangle_enlarge() {this.width *= 2; this.height *= 2;}

    // define Rectangle's property display method
    function Rectangle_showObj() {
       document.writeln('Width is '+this.width+'<br>');
       document.writeln('Height is '+this.height+'<br>');
       document.writeln('Area is '+this.area()+'<br>');
       document.writeln('Perimeter is '+this.perimeter()+'<br>');
       }

    // define constructor with properties
    function Rectangle(w,h) {
       this.width = w;
       this.height = h;
       this.area = Rectangle_area; // Note: parameter brackets are not used
       this.perimeter = Rectangle_perimeter;
       this.enlarge = Rectangle_enlarge;
       this.showObj = Rectangle_showObj;
       }

    // test by creating and displaying an instance of the Rectangle object
    myRect = new Rectangle(5,6);
    myRect.showObj();
    myRect.enlarge();
    myRect.showObj();
This works but is very inefficient. Each instance of a new Rectangle object would contain all of the code for each method such as computing area and perimeter. The prototype based inheritance section illustrates a much better way of constructing objects. ## Function Constructor Methods & Literals Function constructor methods allow dynamic compilation of a function. An example for the area and perimeter functions used above is:
    Rectangle_area = new Function("return this.width * this.height;")
    Rectangle_perimeter = new Function("return 2 * (this.width+this.height);")
Note that Function is capitalized (ie. an object) and uses round (ie. method) brackets. Function literals can also be used to define a function such as:
    Rectangle_area = function{return this.width * this.height;};
    Rectangle_perimeter = function{return 2 * (this.width + this.height);};
Note that the function is unnamed on the right hand side. ## Prototype Based Inheritance Javascript is different from the more commonly used object oriented languages such as C++ and Java in that it uses prototypes instead of classes for inheritance. Prototypes are special template objects whose properties and methods are inherited (ie pointed at, not copied to by objects created by them. This allows method code to be reused rather than copied. It also can be used to set a property to a constant value. If many objects have the same default value for a specific property but with a few exceptions, the prototype can set the default and an individual instance override the setting. A sample of a prototype approach to the Rectangle object is:
    // define a couple of methods to be included in Rectangle object
    function Rectangle_area() {return this.width * this.height;}
    function Rectangle_perimeter() {return 2 * (this.width + this.height);}
    function Rectangle_enlarge() {this.width *= 2; this.height *= 2;}

    // define Rectangle's property display method
    function Rectangle_showObj() {
       document.writeln('Shape is '+this.shape+'<br>');
       document.writeln('Width is '+this.width+'<br>');
       document.writeln('Height is '+this.height+'<br>');
       document.writeln('Area is '+this.area()+'<br>');
       document.writeln('Perimeter is '+this.perimeter()+'<br>');
       }

    // define constructor with properties
    function Rectangle(w,h) {
       this.width = w;
       this.height = h;
       this.shape = "rectangle" // majority are !!
       }

    // create and throw away a prototype object
    new Rectangle (0,0);

    // define object methods for rectangles
    Rectangle.prototype.area = Rectangle_area;
    Rectangle.prototype.perimeter = Rectangle_perimeter;
    Rectangle.prototype.enlarge = Rectangle_enlarge;
    Rectangle.prototype.showObj = Rectangle_showObj;

    // test by creating and displaying an instance of the Rectangle object
    myRect = new Rectangle(5,6);
    myRect.showObj();
    myRect.enlarge();
    myRect.showObj();

    // and a special instance of the Rectangle object that is square
    mySquare = new Rectangle(3,3);
    mySquare.shape = "Square"
    mySquare.showObj();
    mySquare.enlarge();
    mySquare.showObj();
The prototype object may also be applied to any built-in class to add a new method to it. ## Subclasses Although not often needed subclasses (children) of user defined classes are able to be created by making their prototype objects instances of their superclass (parent). As an example we will extend a Complex object:
    //constructor for subclass
    function MoreComplex (real, imaginary) {
      this.x = real;
      this.y = imaginary;
    }
    /*force the prototype to be a Complex (superclass) object
      which has been defined previously in the script */
    MoreComplex.prototype = new Complex (0,0);
    //now add new method or features to MoreComplex
    MoreComplex.prototype.swap = function () {
      var tmp = this.x;
      this.x = this.y;
      this.y = tem;
    }
NOTE: This makes the MoreComplex constructor property the same as its superclass. To overcome this the constructor property must be reset explicitly such as:
    MoreComplex.prototype.constructor = MoreComplex;
## Objects as Associative Arrays In addition to the dot address method of identification such as object.property, object data can also be represented in array format such as object[property]. One advantage of the array representation is that the array index is a string and can thus itself be manipulated dynamically. For example to catenate all customer address data into a single string:
    var addr = "";
    for (i=0; i < 4; i++) { addr += customer["address" + i] }
The above example could have been hard coded with the dot address method but it would hve been longer and less elegant. And there are times when the dynamic capability is required. For example if a client query is made for entry of a database stock item and the quantity on hand is to be obtained from the database:
    var item_name = get_item_name(item); // dialog with user, dynamic answer
    var quantity = database[item];
    show_info(item, quantity); // display the results
And because objects can be expressed as associative arrays the powerful for/in construct can be used as illustrated in the browser explorer tool. For the above database we could quickly calculate the total inventory count without knowing the names or number of unique items in the database:
    var item=""; var names=""; total = 0; // variables initialized
    // define a constructor with properties
    function Database() {}
    // construct the database
    database = new Database();
    // now populate the database
    database.widgets = 6; database.gadgets = 7;
    for (item in database) {
        names += item + ": " + database[item] + "\n";
        total += database[item];}
    alert(names + "\n--------------\n" + "Total: " + total)
## Javascript Object Notation Javascript Object Notation (JSON) is a cross language data interchange format that has a much simpler syntax than XML. It is based on the constructs objects and arrays which are found in virtually all modern languages. JSON has been implemented on Java, C++, C#, Python and other languages. More details on the syntax and use of JSON can be found at json.org Tutorial 14 - Regular Expressions - Javascript Tutorial Appendices Copyright (c) 2005 by John W. M. Russell