Web Developer and Author

code

Create a JavaScript Object

There are many ways to create an object in JavaScript. Lets take a look at a few methods.

Creating an Object Literal

var obj = {
  stringProperty: "string value",
  intProperty: -1,
  boolProperty: true,
  arrayProperty: ["index 0", "index 1", "index 2"],
  method: function(param1){console.log(param1)}
}

In the above JavaScript code we are creating an object literal, and storing that object in the obj variable. The object has 4 properties, and 1 method: I did this so that you can see how to instantiate these datatypes with this method of creating an object literal. Notice that each property name and method name are followed by a colon then by the value. String, Integer, and Boolean data types are straight forward. Notice, however, that the array property is assigned an array literal, and the method is assigned a function expression. Now of coarse I could assign an array object or a named function (or even a declared function) as well, but these can not be declared within the scope of the object literal.

//Instatiating the Array object and 
//then using push to append data into the array
//instead of creating an object literal
var globalArray = new Array();
globalArray.push("index 0");
globalArray.push("index 1");
globalArray.push("index 2");

var namedFunction = function(param1){console.log(param1)};

var obj = {
  stringProperty: "string value",
  intProperty: -1,
  boolProperty: true,
  arrayProperty: globalArray,
  method: namedFunction
}

The problem with this approach is that your methods and properties for this object exist on a scope outside of the object itself. This is considered bad practice, and especially in this case as they are on the global scope.

 

Creating an object with the Constructor function

function exampleConstructorFunction(){
    this.stringProperty = "string value";
    this.intProperty = -1;
    this.boolProperty = true;
    this.arrayProperty = ["index 0", "index 1", "index 2"];
    this.method = function(param1){console.log(param1)};
};

The constructor function uses the this keyword to declare public properties and methods, while private properties and methods are declared with the var keyword. Also notice that the constructor function does not return a value. When a function does not explicitly provide a return value it return the default, which happens to be the “this” keyword. The object returned from this constructor function would be identical to the object created with the object literal above. However, this method provides some flexibility with how we declare arrays, and functions within the scope of the constructor function.

function exampleConstructorFunction(){
    this.stringProperty = "string value";
    this.intProperty = -1;
    this.boolProperty = true;
  
    //Instatiating the Array object and 
    //then using push to append data into the array
    //instead of creating an object literal
    this.arrayProperty = new Array();
    this.arrayProperty.push("index 0");
    this.arrayProperty.push("index 1");
    this.arrayProperty.push("index 2");
  
    //assign a function declaration 
    //instead of a function expression
    function doSomething(param1){
      console.log(param1)
    };
    this.method = doSomething;
};

Again the object returned by this constructor function will be identical to the first object literal we discussed. We can also create private members that are not accessible outside of the constructors scope.

function exampleConstructorFunction(){
    this.stringProperty = "string value";
    this.intProperty = -1;
    this.boolProperty = true;
    
    //private members not accessible outside of the constructor's scope
    var stringValue = "index ";
    var index = -1;
    
    this.arrayProperty = new Array();
    this.arrayProperty.push(stringValue + (index++));
    this.arrayProperty.push(stringValue + (index++));
    this.arrayProperty.push(stringValue + (index++));
  
    this.method = doSomething(param1){
      console.log(param1)
    };
};

We can do even more once we start to use the object’s prototype chain.

function exampleConstructorFunction(){
    this.stringProperty = "string value";
    this.intProperty = -1;
    this.boolProperty = true;
    this.arrayProperty = ["index 0", "index 1", "index 2"];
};
exampleConstructorFunction.prototype.method = function(param1){
  console.log(param1);
}

Now our object’s method is stored in the object’s prototype chain. To understand this, you first need to understand that when you instantiate an object that is declared with a constructor function all of the methods inside the constructor are defined for that instance. If in the course of your code you end up instantiating hundreds of these objects, that same method is being redefined hundreds of times. This makes your collection of objects less performant, but there is an even bigger problem.

function exampleConstructorFunction(){
    this.stringProperty = "string value";
    this.intProperty = -1;
    this.boolProperty = true;
    this.arrayProperty = ["index 0", "index 1", "index 2"];
    this.method = function(param1){console.log(param1)};
};
//create 500 instances of our exampleConstructorFunction object
var objCollection = new Array();
for (var i = 0; i < 500; i++){
  objCollection.push(new exampleConstructorFunction());
  objCollection[i].method = function(){console.log(i)};
  objCollection[i].method();
}

A serious problem occurs when resigning a new function to the object’s method. In this case we have created 500 instance of our object, and each time assigned a different function expression to that object’s method. This means that we have 500 hundred unique methods, instead of 1 method that each object has access to. If we were to assign the method to the prototype chain, things would be different. Every time we create an instance of our object it would not create a new instance of the object’s method, but the object would have access to the methods in the prototype chain. This means that we can change the method 1 time, and all instances of that object would be affected.

function exampleConstructorFunction(){
    this.stringProperty = "string value";
    this.intProperty = -1;
    this.boolProperty = true;
    this.arrayProperty = ["index 0", "index 1", "index 2"];
};
exampleConstructorFunction.prototype.method = function(param1){
  console.log(param1)
}
//create 500 instances of our exampleConstructorFunction object
var objCollection = new Array();
for (var i = 0; i < 500; i++){
  objCollection.push(new exampleConstructorFunction());
}
exampleConstructorFunction.prototype.method = function(param1){
  console.log("a single edit" + param1)
};
for (var i = 0; i < 500; i++){
  objCollection[i].method();
}
 

Creating an object with the constructor function expression

This method is similar to to the constructor function, but allows us to create an immediately-invoked function expression (IIFE), which can be useful when following certain design patters. Lets take a look at the constructor function expression

var exampleConstructorFunctionExpression = function(){
    this.stringProperty = "string value";
    this.intProperty = -1;
    this.boolProperty = true;
    this.arrayProperty = ["index 0", "index 1", "index 2"];
    this.method = function(param1){console.log(param1)};
};

You will notice that we are assigning a function expression to a variable just like normal. The main difference is that we are not explicitly returning a value, so like usual, the default “this” keyword is returned. Thus making it a constructor function. Lets make this an IIFE.

var exampleAlmostSingleton = (function(){
    this.stringProperty = "string value";
    this.intProperty = -1;
    this.boolProperty = true;
    this.arrayProperty = ["index 0", "index 1", "index 2"];
    this.method = function(param1){console.log(param1)};
}());

Notice the IIFE pattern var obj = (function(){}()), instead of the standard function expression var obj = function(){}. You might be surprised to find that an object instance is returned instead of constructor function. You are declaring and instantiating the instance of an object with this method. Some people consider this a singleton, but it is not a true singleton as there are ways to create additional instances of this object. This does provide a quick and dirty solution that would work in most cases that a singleton is needed.

This method is also the preferred method when creating the module design pattern. Let’s take a look at the revealing module design pattern.

var exampleRevealingModule = function(){
    var stringProperty = "string value";
    var intProperty = -1;
    var boolProperty = true;
    var arrayProperty = ["index 0", "index 1", "index 2"];
    var method = function(param1){console.log(param1)};
    
    return {
        stringProperty: stringProperty,
        intProperty: intProperty,
        boolProperty: boolProperty,
        arrayProperty: arrayProperty,
        method: method
    }
};

The big difference between the revealing module design pattern and a constructor function expression is that in the case of the revealing module we explicitly return an object literal instead of the “this” keyword. The object literal that is returned is comprised of private methods and properties, allowing the developer to pick and choose what is returned. We can do this same thing in the constructor function with the use of the “this” keyword (public) and the “var” keyword (private). So in essence they do the same exact thing, but the revealing module tends to be a bit easier to pass off to other developers. All of the code they would have access to is explicitly listed in the returned object literal near the bottom of the function. It provides a list of methods and properties other developers can then leverage as they use the module apposed to having to read every line of a constructor function just to get a high level grasp of what is available to them.

javascriptBLC