JavaScript Constructor Functions

This tutorial is part of a web programming course for people who have no programming experience.


In the previous lessons you learned about two slightly different ways of creating objects in JavaScript. In this example, the entire object is defined in a single statement:

var employee = {firstName: "Bob", lastName: "Smith"};

The following example creates an empty object in the first statement, and then goes on to add properties (and their values) in subsequent statements:

var employee = {};
employee.firstName = "Bob";
employee.lastName = "Smith";

In other programming languages, such as Java and C#, you must define all of the properties and methods of an object before you can create it (the definition is known as a 'class'). So you must create the class definition first, and then you can use it to create objects. Once you have defined the class, it's very easy create objects with it. All the hard work is done up front when the class is defined. A class serves as a blueprint, and by using it you are insured that every object created from it it will have the exact same properties and methods.

The approach to creating objects in the previous lessons was both tedious and error prone. For example, if we are tasked to create a program for the Human Society so that it can keep track of 100 dogs, our code might look like this:

var dog1 = {
    name: "Bruno",
    breed: "Poodle",
    vaccinated: true,
    print: function(){
        console.log(this.name);
        console.log(this.breed);
        console.log(this.vaccinated);
    }
};

// we would have a bunch of code here to create all the other dogs, before finally creating the last dog...

var dog100 = {
    namez: "Lassie",
    breed: "Border Collie",
    vaccinated: false,
    print: function(){
        console.log(this.name);
        console.log(this.breed);
        console.log(this.vaccinated);
    }
};

The example above shows the code for the first dog (dog1) and the last dog (dog100), but just imagine that all the code for all the other dogs was in between.

First notice that we are repeating ourselves quite a bit, every time we need to create another dog object we have to re-write all the property names and values, and we are duplicating the definition of the print method over and over. This is not ideal, and programmers should work to reduce code duplication whenever they can. Second, note that with all the repition, there is a greater chance of an error. Can you spot the error in dog100?

We need a consistent way to create dog objects. The approach that we've been using so far is called object literal notation. JavaScript has an alternative approach to creating objects known as contructor notation. Constructor notation involves creating a special function, known as a constructor, whose sole purpose is to create a specific type of objects. Let's now create a constructor function that will allow us to create dog objects in a more concise and consitent manner:


function Dog(name, breed, vaccinated){
    
    this.name = name;
    this.breed = breed;
    this.vaccinated = vaccinated;

    this.print = function(){
        console.log(this.name);
        console.log(this.breed);
        console.log(this.vaccinated);
    }

}

This is very much like a class in Java and C#. And I must tell you now, that the most recent version of JavaScript gives you the ability to define classes much like in Java or C#. But for many years, JavaScript developers would simulate classes by using constructor functions like the one above. This constructor function now serves as our template, or blueprint, for creating dog objects. It will gaurantee that each dog we create with it will have the same property names and the same methods.

After we have defined the constructor function for creating dog objects, we can use it like this:

// use the constructor function to create two dog objects:
var dog1 = new Dog("Bruno", "Poodle", true);
var dog2 = new Dog("Lassie", "Border Collie", false);

// invoke the print method so the we can see the details of each dog in the console log:
dog1.print();
dog2.print();

Here we have created two dog objects, and the properties of each one are set by passing parameters into the function call. We could then go on to create the rest of the dogs in the system by invoking the constructor function in this manner.

Guidelines for Creating Constructor Functions

Here are some things to keep in mind when creating and using constructor functions:

  • Constructor function names should start with an uppercase letter (rather than using camelCase). This helps to distinguish them from regular functions.
  • The name of the constructor function should describe the object that it creates (Dog).
  • To set the properties of the object being created, pass in parameters when invoking the constructor function. Note that the parameter names are the same as the property names, which can cause confusion. So when referring to a property inside a constructor function, prefix it with the this keyword (we'll talk more about this in just a moment).
  • The constructor function does not have a return statement even though it does actually return an object (it is implied that constructor functions return the object that they are design to create).
  • When you invoke the constructor function, you must use the new keyword.
  • When defining methods inside a constructor function, prefix the method name with this. Note that some JavaScript afficionados would argue that there are better ways to add methods to objects than to put them in the constructor function. And this may be true, but for now it makes good sense to take this approach when you are learning about object-oriented programming.

Also note that you could change the parameter names if you wanted to avoid some ambiguity, but it's common for programmers to use parameter names that match the properties of the object. For example, we could have written the Dog constructor like so:

function Dog(param1, param2, param3){
    
    this.name = param1;
    this.breed = param2;
    this.vaccinated = param3;

    this.print = function(){
        console.log(this.name);
        console.log(this.breed);
        console.log(this.vaccinated);
    }
}

As usualy, I have to go on a little rant about formatting your code. Please notice that all the lines of code within the body of the constructor are indented, and that all the lines inside the body of the print method are also indented. Proper indentation will help reduce bugs, and find bugs, and keep your code easy to read, and keep your fellow programmers happy.

Built-in Constructor Functions

The JavaScript languages has some built-in constructor functions that you can use to create objects. For example, you use the Array constructor to assign an array to a variable like this:

var numberArray = new Array(1,3,5,7);
// this is the same as... 
var numberArray = [1,3,5,7];

In the next lesson we'll explore another built-in constructor function that you can use to create 'date' objects.

NEXT LESSON: Working with Date and Times in JavaScript