Quick JavaScript OO (Object Orientation) Primer

by on December 20, 2012 11:23 am

Recently I’ve been working heavily with JavaScript to implement full-blown rich user interfaces for web-based applications. In the past, I’ve used JavaScript and supporting libraries, such as JQuery and Jquery UI to introduce cool UI widgets to enhance my server side Java web applications.

But, as I’ve been introducing the MVC pattern to the browser using supporting JavaScript libraries, I’ve had to learn how to write object oriented modular JavaScript. And yes, you can do object oriented programming with JavaScript. So, I’d like to introduce some basic object oriented JavaScript concepts.

Initializer Objects

JavaScript is dynamic, meaning that when you define things such as function, expressions, or variables — they are defined. There’s not a compilation process to check syntax or typing (as there is in typed languages such as Java or C#). Object definitions are also dynamic and are simply an unordered collection of key/value pairs.

Here’s an expression that defines a JavaScript object:

var object = {};    // object created

This is referred to as a Initializer object, and it has no state or methods to execute. Since JavaScript is dynamic, properties can be added at any time. Age and name properties are added with the expressions below:

object.age = 49;
object.name = “Clifford”;
alert(object.age +”:”+ object.name); // shows 49 : Clifford

Methods

Functions are also objects, and are used to create methods. Essentially, a function object is defined and assigned to an object property. The expressions below defines a print function, and assigns and executes the method:

// print() method
object.print =  function() {  return object.age +”:”+ object.name;    };
// execute method
console.log(object.print());  // shows 49: Clifford

Using JSON Type Syntax

A complete object can be defined using JSON type syntax. Here’s an example of how a “person” object can be created in a single expression:

var person  = { name: "david",
age: 40,
print: function() { return name + ":"+age}};
console.log(person.print());   // shows david:40

Personally, my object oriented programming background comes from Smalltalk — dating myself — with the last decade using Java and C#. I’ve come to find out that the JavaScript community refers to this as a classical way of OO thinking. In the next section, I’ll introduce another way to define JavaScript objects, commonly referred to as the “classical” object approach.

Constructor Objects

Objects may also be defined so that they are created using the classical “new” operator, along with specifying initialization parameters. Any function that is assigned to a variable can be issued the new command, and an object will be created.

The example below shows how a constructor function is defined, and how it accepts name and age values that are assigned to the “Person” variable:

var Person = new function(name,age) {
    this.name = name;
    this.age = age;
    this.print = function() {
        return his.age +”:”+ this.name;
    };
}

An object can be created and used, as long as the “person” variable is in scope with the expressions below:

var person = new Person(“Clifford”,49);
person.print();

Object Prototypes

As you can see, JavaScript does not have classes as with other classical OO languages such as Java or C#. Instances are created using prototypes, and as such, all constructor object references have a prototype property reference that can be used to extend object implementations.

Consider the String global object reference. Its prototype reference can be used to extend its functionality with a repeat method as in the expressions below:

String.prototype.repeat = function(x) {
    return count >  1 ?  '' : new Arrray(count + 1).join(this);
};

Once extended, it can be used as followed:

“Hello”.repeat(3);      // returns “HelloHelloHello”;

Emulating Inheritance

JavaScript does not have an inheritance mechanism, but by using prototypes you may emulate it.

The example below defines two objects: Person and User. The User constructor object defines two attributes but inherits properties and methods from the “Person” object by assigning its prototype. Here is JavaScript carrying this out:

// Person Object
var Person = function() {
    this.age;
    this.name;
    this.print = function() {
        return "Age:"+this.age+" - "+"Name: "+this.name;
    }
};
// User Object
var User = function() {
};
// Create User that extends/inherits from Person
function createUser() {
    // inherit
    User.prototype = new Person();
    // create instance
    var user = new User();
    // add user properties
    user.id;
    user.password;
    return user;
}

Usage of the user object is shown below:

var u = createUser();
// inherited print() method..
alert(u.print() + "id:"+u.id + "password:"+u.password);

Emulating inheritance using initializer objects can be implemented by defining a method on a base object that dynamically copies properties/methods to a supplied object. This technique is done in the backbone.js framework to allow the base view object to be extended with sub-objects.

Here’s how a extend() method can be implemented in the previous example:

// Function to extend Person object
function extend(object) {
    var base = new Person();
    for (var attr in base) {
        object[attr] = base[attr];
    }
    return object;
}

An object that extends a “Person” object definition can be done with this expression:

var user = extend({id:"abcd",password:"123"});
// Person print() method inherited
alert(user.print() + "id:"+user.id + "password:"+user.password);

Super is a reserved word in JavaScript, however it is not implemented. You’ll have to roll your own implementation for accessing parent objects in an inheritance chain.

I have shown you a very basic way to implement inheritance, but there are more nuances (such as overriding and super mechanism) that have to be considered. But hopefully this provides some context.

Getter/Setters?

Yes, JavaScript provides support for formal getter/setters. This was a late addition, but I am pretty sure all newer browsers support getter/setters. They mirror the C# implementation, as in Java you still have to implement them.

I really like the way the getter/setter code blocks are hidden. Here is how you would apply them to the name attribute of the example object that we’ve been working with:

// Person Object
var Person = function() {
    this.age;
    var name;
    this.print = function() {
        return "Age:"+this.age+" - "+"Name: "+this.name;
    };
    // getter/setters
    this.__defineGetter__("name", function(){
        return value;
    });
    this.__defineSetter__("name", function(val){
        value = val;
    });
};

Getter/Setter methods are invoked just like attributes. Here’s an example:

Person person = new Person();
// setter executed
person.name = “Chris”;
// getter exectued
person.name;   // shows “Chris”;

Conclusion

If you are new to applying JavaScript as a general purpose programming language, then these basic object constructs should help you as you progress in applying modularity frameworks (such as require.js or backbone.js) and writing general purpose applications with JavaScript. Good luck!

– David Pitt, asktheteam@keyholesoftware.com

  • Share:

7 Responses to “Quick JavaScript OO (Object Orientation) Primer”

  1. Lou Mauget says:

    David, I just happen to be working in this area. This blog is good enough to for me use as a cheat sheet for these concepts.

  2. David says:

    Thanks Lou, you’re a “classical” man :)

  3. Dawesi says:

    Great intro for nubes. Some notes:

    1) As best practice you should never extend base lang functions (string, function, array, etc) as they could cause collisions with other code. If you want to extend these you should create your own lang functions. (ie: String.prototype.repeat could be MyString.prototype.repeat)

    2) using new keyword for function is redundant (ie: var Person = new function(name,age) ) you should use var Person = function(name,age) and only use new on the new instance.

    3) Most MVC javascript apps have one ‘class’ per file. Sencha MVC is a great example of this, and other frameworks are now using this best practise also.

    4) javascript doesn’t emulate inheritance. It uses prototypal inheritance instead of classical inheritance

    5) __defineGetter__ and __defineSetter__ are depreciated. They don’t work cross browser anymore. In your example they are redudant anyway. Frameworks like ExtJS allow you getters and setters out of the box (run it through sencha cmd and it’s one of the lightest frameworks out there)

    Great article, with a couple of tweaks is a great intro. Well done!

  4. David says:

    Thanks for the info and clarifications and suggestions…David

  5. [...] these sorts of things can be done in JavaScript’s prototypical system (see David Pitt’s blog post on the subject), but it tends to be more verbose, a bit confusing and far from elegant. In fact, it [...]

  6. [...] these sorts of things can be done in JavaScript’s prototypical system (see David Pitt’s blog post on the subject), but it tends to be more verbose, a bit confusing and far from elegant. In fact, it [...]

  7. Howdy! I’m at work surfing around your blog from my new iphone 4! Just wanted to say I love reading through your blog and look forward to all your posts! Keep up the great work!

Leave a Reply

Things Twitter is Talking About
  • A huge welcome to John Holland who joined the Keyhole team today!
    July 28, 2014 at 4:56 PM
  • We think #JavaScript Promises are cool. Here's a good introduction from @mauget - http://t.co/6wCz9b7e4v
    July 28, 2014 at 2:19 PM
  • There's a new post on the Keyhole blog by @mauget: #JavaScript Promises Are Cool - http://t.co/6wCz9b7e4v
    July 28, 2014 at 9:52 AM
  • Thank your #Sysadmin - today is System Administrator Appreciation Day. http://t.co/LcvDNa9kPg
    July 25, 2014 at 8:05 AM
  • @rickincanada Thx for your tweet! Shoot us an email at asktheteam@keyholesoftware.com so we can set up a time to talk. Have a good day.
    July 24, 2014 at 3:33 PM
  • Never used JAXB? Check out a simple usage pattern that pairs #JAXB’s data binding capabilities with JPA - http://t.co/Ki9G04HV5e
    July 24, 2014 at 9:53 AM
  • Guess what today is? Tell An Old Joke Day - http://t.co/835ORWMX6N! So, why do programmers always confuse Halloween & Xmas? 31 Oct = 25 Dec
    July 24, 2014 at 8:45 AM
  • MT @midwestio: Posted another #midwestio talk recording to our YouTube channel: @MinaMarkham on modular CSS. Watch: http://t.co/aU3LpfUoi4
    July 24, 2014 at 8:25 AM
  • We just posted pictures from our National Hot Dog Day Lunch Cookout. Check them out - http://t.co/To06plaw1C
    July 23, 2014 at 4:14 PM
  • Good free cheat sheet - #Java Performance Optimization Refcard from @DZone: http://t.co/7vBgsmqy08
    July 23, 2014 at 10:48 AM
  • Did you know today is a holiday? It's National Hot Dog Day! We're gearing up for our team lunch hot dog cookout & can't wait to celebrate.
    July 23, 2014 at 9:43 AM
  • Check out our newest blog: #JAXB – A Newcomer’s Perspective, Part 1 http://t.co/Ki9G04HV5e
    July 22, 2014 at 1:22 PM
  • New post on the Keyhole blog by Mark Adelsberger: #JAXB – A Newcomer’s Perspective, Part 1 http://t.co/Ki9G04HV5e
    July 21, 2014 at 2:27 PM
  • If you're a Java dev, you're likely familiar with Annotations. But have you created your own #Java Annotations? Ex - http://t.co/BgCsYjxZKF
    July 18, 2014 at 12:10 PM
  • RT @gamasutra: Don't Miss: Unconventional Tips for Improving your Programming Skills http://t.co/6TFox7CKHU
    July 16, 2014 at 3:20 PM
  • We're about to send out our free monthly tech newsletter. Dev tips/articles via email. Not on the list yet? Sign up - http://t.co/F8h0NSiicZ
    July 15, 2014 at 11:57 AM
  • Have you ever tried creating your own #Java annotations? See a situation where it was beneficial - http://t.co/BgCsYjxZKF
    July 15, 2014 at 8:36 AM
  • There's a new post on the Keyhole blog by @jhackett01: Creating Your Own #Java Annotations - http://t.co/BgCsYjxZKF
    July 14, 2014 at 1:43 PM
  • We love development! Have you seen our weekly team blog? We show how to be successful with the tech we use. See it - http://t.co/nlRtb1XNQH
    July 12, 2014 at 2:35 PM
  • Rapid appdev has a bad rep, but there are ways to bring development time down the right way. Don't Fear the Rapid - http://t.co/aTPcAKOj0r
    July 11, 2014 at 3:10 PM
Keyhole Software
8900 State Line Road, Suite 455
Leawood, KS 66206
ph: 877-521-7769
© 2014 Keyhole Software, LLC. All rights reserved.