Skip to main content
Engineering LibreTexts

5.6: A Simple JavaScript OOP Model

  • Page ID
    27564
  • This section will combine all the material covered in this chapter up to this point to create an OOP model to be used throughout the rest of this text. Two object models will be given. The first is the one normally used in JavaScript, so it will be the one used through the rest of the book. It does not enforce encapsulation or information hiding, but languages like TypeScript have been introduced since ECMA6 to provide encapsulation and information hiding, and they generally compile to JavaScript that follows the basic pattern of an object presented in this first object model.

    A second model of OOP will be presented to show how JavaScript closure can be used to enforce encapsulation and information hiding in basic JavaScript. This would be a good implementation of OOP in JavaScript if encapsulation and information hiding are needed, but it has been overtaken by events, and most programmers using these features will be using languages such as TypeScript. It is presented because it highlights and explains a lot of features of JavaScript programming.

    5.6.1 A first JavaScript Object Model

    In Chapter 5.3.4 a method to combine prototypes and constructor functions into an object was shown, though it was not given as an object model at the time. The idea is that objects are constructed in a Constructor Function, and the functions that operate on that object are stored in the Constructor Function prototype object. The strategy for creating this type of object is as follows:

    1. The Constructor Function is defined, and it will take one argument, which is an options object of properties to be included and set in this object.
    2. The __cfName variable is assigned to the name of the Constructor Function in the this object. This is so that object can later be reconstructed if it loses its constructor (e.g. it is written and then read from a JSON data source).
    3. The property default values are defined in the Constructor Function for the this object.
    4. All properties passed into the Constructor Function will be moved to properties in the newly constructed this object. The properties will include all properties in the options object, including those that do not have default values. The reason for this will be explained in the section on Unstructured Data later in this chapter.
    5. All methods that will act on this object will be included in the prototype object for this Constructor Function. These prototype functions will be defined after the Constructor Function has finished executing. The prototype function will be called with an object, so the this variable can be used to access the appropriate object.

    An example of implementing and using this definition for a Map object is presented below.

    Program 104 - Map object definition
    
    <script>
    function Map(options) {
        // Set Defaults
            __cfName = “Map”;
            this.title = "Please change the title";
            this.recenter = true;
            this.center = [-77, 32];
    
        // Get properties from parameter
        outerloop:
        for (i in options) {
            for (j in this) {
                if (i == j) {
                    this[i]= options[j];
                    continue outerloop;
                }
            }
            console.log("Property " + i + " is not a default Map property");
            this[i] = options[i];
        }        
    
    // Set accessor function
    Map.prototype.setTitle = function (title) {
        this.title = title;
    }
    Map.prototype.getTitle = function () {
        return this.title;    
    }
    
    Map.prototype.setRecenter = function (recenter) {
        this.recenter = recenter;
    }
    Map.prototype.getRecenter = function () {
        return this.recenter;
    }
    Map.prototype.setCenter = function (center) {
        this.center = center;
    }
    Map.prototype.getCenter = function () {
        return this.center;
    }
    
    // Set toString function
    Map.prototype.toString = function() {
        return ("title: "    + this.title
            + " recenter: "  + this.recenter
                + " center: "   + this.center);  
    }
    
    var m1 = new Map({title: "newMap"})
    console.log(m1.getTitle());
    
    m1.title = "This breaks encapsulation";
    console.log(m1.getTitle());
    
    </script>                
    

    The only issue with this definition of an object is that encapsulation and information hiding is broken. As is shown in the example above, where the programmer directly sets the value of m1 by saying m1.title = "This breaks encapsulation";, the programmer can directly access the title property without using the setTitle and getTitle methods.

    The following object model adds encapsulation using function variables and closures. It is included to show how closures could be used in JavaScript, but is not a standard object model, and should not be used for production programs.