Click here to Skip to main content
15,885,546 members
Articles / Programming Languages / Javascript

JavaScript Objects

Rate me:
Please Sign up or sign in to vote.
4.67/5 (7 votes)
16 Aug 2013CPOL6 min read 20K   13   5
Creating Objects in JavaScript

There are so many ways to create objects in Java Script, it be so flexible after all. So what is the right way to create an object. Constructor pattern, Prototype pattern, Object literal?
What is it? 

Before going there, let us try to get some basics cleared about JavaScript.
Is Object Oriented programming even possible in JavaScript?
Well it has objects! The object can contain data and can have methods acting on that data and can even have other objects. It does not have classes but have constructors, it does not have class oriented inheritance but does have prototype based inheritance.

It kind of looks like we have all the ingredients necessary to create object and object oriented programming in JavaScript.

We all know JavaScript has private variables. A variable defined inside a function using the "var" keyword lives within the scope of the function and is not accessible outside the function.
What happens when we do not use "var" keyword to declare the variable? We might talk a little about it, might cross through “this”, but can be a different story some other day.

So back to the question. What is the right way to create an Object/Classes in JavaScript?
Let us try with what we know and lets us try to create an object called Person

JavaScript
var Person = {
   firstName : 'John',
   lastName : 'Cody',
   fullName : '',
   message : '',

    createFullName : function () {
        fullName = this.firstName + ' ' + this.lastName;
    },

    changeMessage : function (msg) {
       this.message = msg;
    },

    getMessage : function () {
        this.createFullName();
        return this.message + ' ' + fullName;
    }
}

Person.firstName = 'Eli';
Person.lastName = 'Flowers'
Person.changeMessage('welcome');
var message = Person.getMessage(); // welcome Eli Flowers
alert(message);

This object literal pattern. This is very close to how we are used to create classes.
If you do not care about private/encapsulation for that matter and you know you are not going to create the instance of this object. Then this might be a good choice for you. What is that private can do that public cannot do right? But this is not a class, it’s an object, cannot create instance on it and no encapsulation.

Let’s try something different. 

JavaScript
var Person = function() {
    this.firstName = 'John';
    this.lastName = 'Cody';
    var fullName = '';
    this.message = '';

    var _that = this;

    var createFullName = function () {
        fullName = _that.firstName + ' ' + _that.lastName;
    }

    this.changeMessage = function (msg) {
       this.message = msg;
    }

    this.getMessage = function () {
        createFullName();
        return this.message + ' ' + fullName;
    }

}

var person1 = new Person();
person1.firstName = 'Eli';
person1.lastName = 'Flowers'
person1.changeMessage('welcome');
var message = person1.getMessage(); // welcome Eli Flowers
alert(message);

This is a constructor pattern. So is it a Class or Object. Well both. We can make use of the object Person as is when required. It is a function after all. Or create a new instance of this function by the use of the “new” keyword.

There are few things that we need to keep in mind with this type of pattern.

  1. Whenever a function is called, it gets a special variable called “this” and refers to the global scope. What global scope is depends on the scope of the function itself.
  2. Whenever an instance of the function is created using the keyword “new”, “this” refers to the function itself and the “new” also causes the code inside the function to execute. Hence constructor pattern.
  3. Anything that is attached to “this” becomes public and anything that is declared with “var” is private.
  4. A function attached to “this” is called a privileged function and can access private variables and function and other variables and functions attached to “this”.
  5. Private Functions have access to other private variables and function. 
  6. Private functions does not have direct access to variables and functions attached to “this”. The way we achieve this by creating a private variable called “_that” and assigning it to “this”.
  7. Any Private variable or function is available to all the other private functions and all the other functions attached to “this”. How this is possible read about Scope in JavaScript.
  8. A variable or function that is not declared with “var” or not attached to “this” gets attached to the Global Scope, i.e. to the scope where the function itself is defined. Again read more about Scope and Closures. 

This achieves pretty much what we want, but sometimes the entire thing with “this” and “that” can become confusing. And for people who want to want to stick to true private.

Let as try something a little more different.

JavaScript
var Person = function () {

    //private 
    var firstName = 'John';
    var lastName = 'Cody';
    var fullName = '';
    var message = '';


    var createFullName = function () {
        fullName = firstName + ' ' + lastName;
    }

    //public setters 
    var setMessage = function (msg) {
        message = msg;
    }

    var setFirstName = function (fName) {
        firstName = fName;
    }

    var setLastName = function (lName) {
        lastName = lName;
    }

    var getMessage = function () {
        createFullName();
        return message + ' ' + fullName;
    }

    //functions exposed public
    return {
        setFirstName: setFirstName,
        setLastName: setLastName,
        setMessage: setMessage,
        getMessage: getMessage
    };

};


var person1 = new Person();
person1.setFirstName('Eli');
person1.setLastName('Flowers');
person1.setMessage('welcome');
var message = person1.getMessage(); // welcome Eli Flowers
alert(message);

This is Revealing Pattern. Thanks to Christian Heilmann. The thing with this type of pattern is that it requires "getters" and "setters" for properties. Most of us coming from the traditional Java programming can appreciate this and don’t find it complex. It is also kind of like as if the class implements an Interface.

All this good but there is one slight problem. Every time an instance of the class is created the newly created object gets the copy of variables and functions. Now, copy of variables is fine, we want the data specific to the object, but functions? they are simply going to act on the data. Why need copies of them.

Here is where Prototype comes handy. Anything that is created on a prototype is shared among all the instances. All we have to do is create public functions on the prototype.

JavaScript
var Person = function () {

    //private 
    var welcomeMessage = 'welcome';
    var fullName = '';
    var firstName = '';
    var lastName = "";
    var createFullName = function () {
	Person.prototype.setFirstName('asdsad'); 
        fullName = firstName + ' ' + lastName;
    };

    //constructor
    var Person = function () { }; //will be created evrytime

    //public 
    Person.prototype = {
        getFullName: function () {
            createFullName();
            return welcomeMessage + ' ' + fullName;
        },
        setFirstName: function (fName) {
            firstName = fName;
        },
        setLastName: function (lName) {
            lastName = lName;
        },
        ChangeMessage: function (mesg) {
            welcomeMessage = mesg;
        }
    }

    return new Person(); // Person; //new Person();
};


var person1 = new Person();
person1.setFirstName ('Eli');
person1.setLastName('Flowers');
person1.ChangeMessage('welcome');
var message = person1.getFullName(); // welcome asdsad Flowers
alert(message);

One of the problem with prototype is that it cannot access private variables and functions, and for that reason we have introduced closures and also to keep the code organized for those of us who worry how class are created and it also does not clutter the global scope. Everything is still inside the scope of Person.

The other problem is that every time an instance is created the entire code is executed, including the binding of the prototype. For some of us this is performance problem. The way to take care of this problem is to bind the prototype only if an expected public function is not already available.

This will result in binding the prototype only once when the first instance is created and after that for all the other instances the check will kick in. Unfortunately this fix will not work in our example above as we are creating the function all over again to generate a closure to achieve the class affect. Hey at least we saved some memory.

Yet another problem is that private functions cannot access prototype functions directly.

Why do you need private functions and variables anyways? I understand encapsulation is on your mind, want to make sure that properties or internal data does not get changed accidentally or intentionally by other programmer whatever… whatever.

Remember you cannot compile the code into binary, you are screwed anyways, the code is always available, so if anyone want to mess it up they will mess it up weather you implement true private or not, weather you give it to other team members or sell it. Will minify help, probably.

One of the other techniques programmers use is naming conventions, use and underscore “_” for anything that you intend to make private.

JavaScript
(function () {
    var Person = function () {
        this._fullName = '';
        this.welcomeMessage = '';
        this.firstName = '';
        this.lastName = "";
_that = this;


        this._createFullName = function () {
            this.ChangeMessage('Namaste');
            this._fullName = this.firstName + ' ' + this.lastName;
        };
    }

    //Shared Functions for Code optimization
    Person.prototype = {
        constructor: Person,
        getFullName: function () {
            this._createFullName();
            return this.welcomeMessage + ' ' + this._fullName;
        },
        ChangeMessage: function (mesg) {
            this.welcomeMessage = mesg;
        }
    }

    this.Person = Person;
})();

var person1 = new Person();
person1.firstName = 'Eli';
person1.lastName = 'Flowers';
person1.ChangeMessage('Welcome');
var message = person1.getFullName(); // Namaste Eli  Flowers
alert(message);

I am not saying you should not consider “private” and stuff. You are the designer of the code and you will know how to engineer and what works best for you. Depending on your need you can use any one or combination of the patterns.

Whatever you decide to do few things to keep in mind, do not clutter the Global Scope, worry about memory leaks, and code optimization, and keep code organized. So read more about Scope, Closures and how “this” behaves.

Happy Programming.

License

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


Written By
Web Developer
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionUse recommendation Pin
Sinisa Hajnal10-Dec-14 2:16
professionalSinisa Hajnal10-Dec-14 2:16 
QuestionToo much missing Pin
Florian Rappl15-Aug-13 21:20
professionalFlorian Rappl15-Aug-13 21:20 
AnswerRe: Too much missing Pin
Rakesh Krishna Bhatt16-Aug-13 1:55
Rakesh Krishna Bhatt16-Aug-13 1:55 
GeneralRe: Too much missing Pin
Florian Rappl16-Aug-13 7:06
professionalFlorian Rappl16-Aug-13 7:06 

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

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