Click here to Skip to main content
Click here to Skip to main content

Tagged as

Go to top

JavaScript Objects in 15 Minutes

, 27 Nov 2013
Rate this:
Please Sign up or sign in to vote.
How to deal with objects creation in JavaScript, encapsulation and inheritance, different techniques, and examples.

Introduction

This article is a brief guide on how to create objects in different ways, implement inheritance and encapsulation, use the prototype property, and test my code by using the unit test framework for JavaScript QUnit (http://qunitjs.com/).

Background

Factory Pattern: The factory method pattern is an object-oriented creational design pattern to implement the concept of factories and deals with the problem of creating objects (products) without specifying the exact class of object that will be created. - From Wikipedia.

Basically, it is a specific way to create new object instances by using a method.

Everything is a Object

In JavaScript everything is an object, keep it present always.

JavaScript is a very flexible language which could be an advantage or a disadvantage, if you are a ordered developer then you will be fine. You can create objects but the relationship between them and object-oriented programming is not direct. For example, there is no class keyword in JavaScript but you can simulate similar functionality and OO concepts like encapsulation and inheritance.

JavaScript is called a prototype-based, object-oriented programming language, so you will use prototypes to create or clone objects before use them.

QUnit

I will use Qunit to create test methods and assert values:

Download QUnit .js and .css files from http://qunitjs.comAdd both to your project. Read getting started section. We will use the equal function which basically compares two values and evaluate them as a Boolean condition.

Object Literal Pattern

The easiest way to create an object, just need name, curly braces and specify the properties and/or methods you need:

var person = {
    name: 'steve',
    age: 25,
    getInfo: function () {
        return this.name + ' ' + this.age;
    }
};

Here I created a person object with two properties; name as string and age as number; also, a function with name getInfo that returns a string with the value of both properties.

Test method

On this test method I use the person object already created and invoke its getInfo() function.

test("Object literal test", function () {
    expect(1);

    var expected = 'steve 25';

    var actual = person.getInfo();

    equal(actual, expected, actual);
});

After running the page, the result is:

This indicates that the 'Object Literal Test' test passed without errors.

Factory Pattern

Every object in JavaScript has a prototype object which can be used to clone an object by using the new keyword.

function getEmployee(name, department) {
    var newEmployee = new Object();
    newEmployee.name = name;
    newEmployee.department = department;
    newEmployee.getInfo = function () {
        return this.name + ' ' + this.department;
    }
    return newEmployee;
};

First, I need to create a function which allows the factory pattern implementation, receiving by parameters the values of the properties are need to set, inside the function use the New Object() instruction to create an empty object, finally just specify the properties and methods needed.

Test method

In this test I create two object instances named employee1 and employee2, both with a name and department.

test("Factory Pattern test", function () {
    expect(2);
    var employee1 = getEmployee('David', 'financial');
    var employee2 = getEmployee('Mark', 'sales');

    equal(employee1.getInfo(), 'David financial', employee1.getInfo());
    equal(employee2.getInfo(), 'Mark sales', employee2.getInfo());
});

Result:

Class Simulation

As I said, there is no class keyword in JavaScript; instead, we can simulate it using a function and a default constructor.

function Computer(brand, is64, color) {
    var _brand = brand;
    var _is64 = is64;
    var _color = color;
    this.getInfo = function () {
        return _brand + ' ' + is64 + ' ' + _color;
    }
};

Here I created a function that works as a default constructor and at the same time allows me to implement encapsulation. Using the var keyword to declare each property (or variable) ensure that they cannot be modified by external code.

Test Method

Just create two objects of type computer and assign their internal values by using the default constructor.

test("Class simulation", function () {
    expect(2);
    var toshiba = new Computer('toshiba', true, 'black');
    var hp = new Computer('hp', false, 'red');

    equal(toshiba.getInfo(), 'toshiba true black', toshiba.getInfo());
    equal(hp.getInfo(), 'hp false red', hp.getInfo());
});

Result:

Prototype Property

Everything is an object in JavaScript, and everything has a prototype property which is an object itself that contains properties and methods that should be available to all instances of the type you are working with.

For this example, we will rewrite the getInfo method for the Computer class using its prototype property. I will name it Computer2 class.

function Computer2(brand, is64, color) {
    this.brand = brand;
    this.is64 = is64;
    this.color = color;
};
Computer2.prototype.getInfo = function () {
    return this.brand + ' ' + this.is64 + ' ' + this.color;
};

The difference is on getInfo implementation, it is made outside the definition of the class and using the prototype property so I’m affecting all the instances of the computer2 object that use the function getInfo.

Test Method

test("Instance test using prototype, overwrite original function shared across all instances", function () {
    expect(2);
    var toshiba = new Computer2('toshiba', true, 'black');
    var hp = new Computer2('hp', false, 'red');
    //overwrite the original implementation
    Computer2.prototype.getInfo = function () {
        return this.brand + ' is ' + this.is64 + ' and of color ' + this.color;
    };
    equal(toshiba.getInfo(), 'toshiba is true and of color black', toshiba.getInfo());
    equal(hp.getInfo(), 'hp is false and of color red', hp.getInfo());
});

After creating the two instances of Computer2, I overwrite the getInfo function with a new implementation which basically changes the return text. The interesting point here is that I’m changing the implementation for all the instances, for created ones and the new ones.

Result:

Inheritance

To implement inheritance in JavaScript we have to use something called IIFE (An immediately-invoked function expression (or IIFE, pronounced "iffy") is a JavaScript design pattern which produces a lexical scope using JavaScript's function scoping, - Wikipedia.org), basically, a block of code that is invoked immediately after the browser loads.

So let’s create three classes, a superclass and two subclasses, as follows:

Next is my superclass called USER, it has two properties and a method:

//superclass
var User = (function () {
    function User(name, isActive) {
        this.name = name;
        this.isActive = isActive;
    }
    User.prototype.getInfo = function () {
        return this.name + ' is active: ' + this.isActive;
    }
    return User;
})();

Next is the subclass Developer, there are several important parts:

In the inline function used to create the object I receive parent, which represents the superclass I’m inheriting. Use the prototype property to change the object type to User. Use parent.call to make a reference to the parent function (constructor) and send this to be assigned as a child. Write the new methods as needed, for example: Writecode(). At the end of the IIFE declaration, specify the parent class between parentheses, like this: (user).

var Developer = (function (parent) {
    Developer.prototype = new User();
    //intheritance is accomplished by changing the prototyp object for the child

    Developer.prototype.constructor = Developer;
    function Developer(name, isActive, languajes) {
        this.languajes = languajes;
        parent.call(this, name, isActive);
    }
    Developer.prototype.WriteCode = function () {
        return 'writing code!';
    };
    return Developer;
})(User);

var Dba = (function (parent) {
    Dba.prototype = new User();
    //intheritance is accomplished by changing the prototyp object for the child

    Dba.prototype.constructor = Dba;
    function Dba(name, isActive, isSqlDba, isOracleDba) {
        this.IsSqlDba = isSqlDba;
        this.IsOracleDba = isOracleDba;
        parent.call(this, name, isActive);
    }
    Dba.prototype.MakeBackup = function () {
        return 'backup done!';
    };
    return Dba;
})(User); 

Test method

Basically, create two different child objects instances; invoke the parent method (getInfo) as well as the children's new methods (WriteCode and MakeBackup):

test("Inheritance Test", function () {
    expect(4);
    var dev = new Developer('James', true, ' vb.net and c#');
    var dba = new Dba('John', true, true, false);
    
    equal(dev.getInfo(), 'James is active: true');
    equal(dba.getInfo(), 'John is active: true');
        
    equal(dev.WriteCode(), 'writing code!', dev.WriteCode());
    equal(dba.MakeBackup(), 'backup done!', dba.MakeBackup());
});

Using the code

Check the link below for a Visual Studio 2013 solution with all the code I used inside the article. Uncomment specific tests to see the results.

History

  • Version 1: 26/11/2013.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Rolando CC
Technical Lead
Costa Rica Costa Rica
Professional .Net Developer, I have used .Net Framework from version 2 until version 4.5.1, prefer MVC than Asp.Net, prefer JQuery than pure JavaScript (the most of the time). Enjoy my work.
Follow on   Twitter   Google+

Comments and Discussions

 
GeneralMy vote of 4 PingroupAkhil_Mittal15-Dec-13 22:25 
QuestionVery usefull post... Pinmemberasalgadoscr13-Dec-13 5:50 
AnswerRe: Very usefull post... PinprofessionalRolando CC15-Dec-13 14:46 
SuggestionWell written...but... PinmemberBraj Panda9-Dec-13 19:55 
GeneralRe: Well written...but... PinprofessionalRolando CC10-Dec-13 2:51 
GeneralRe: Well written...but... PinmemberBraj Panda21-Dec-13 1:18 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140926.1 | Last Updated 27 Nov 2013
Article Copyright 2013 by Rolando CC
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid