Why Object-Oriented JavaScript is so confusing

December 21, 2007 – 2:52 am Tags:

Any of you who has used OOP in any “traditional” language, such as C++, Java or PHP and then tried to apply the stuff you know in JavaScript probably know that… things just don’t work like you’re used to.

But what are the things that actually are causing the confusion and how to avoid the problems?

No obvious way of making a class

JavaScript has no class statement and there is more than one way you can create new objects. For example…

function MyClass()
{
  //private stuff
  var privateVar = 'foo';
 
  function privateFunction()
  {
  }
 
  //public stuff
  this.methodName = function(param)
  {
    alert(param);
  }
 
  this.variableName = 'hello';
}
 
//or this, also known as "Module pattern" [1]
 
var MyOtherClass = function()
{
  //private stuff
  var privateVar = 'foo';
  function privateFunction()
  {
  }  
 
  return {
    //public stuff
    methodName: function(param)
    {
      alert(param);
    },
    variableName: 'hello'
  };
}();

[1] YUI Blog JS module pattern

This is just two ways, and I’m sure there are more. Personally I’m using the module pattern method, which is very good as you can have both private and public members with ease.

There’s one thing to note here: Although JS doesn’t actually do anything if you do “class something { }”, the word “class” is still a reserved word in some browsers (such as IE), and therefore you should not use class as a name for a function or a variable.

Member scope

A problem introduced by how JavaScript handles the private member scope. As JavaScript does not really support private object members, the way to make things private is to wrap them inside a block which effectively wraps them inside its own scope.

Now, if you were to use the above methods to create a new class and then try to extend it, for example by doing…

MyOtherClass.newMethod = function()
{
  alert(privateVar); //no worky
}

I personally think that the fact that you can “append” new functionality to an object like this is very nice, but it has its problems.

The this keyword

This really confused me back in the day. Why would it sometimes not point at the object itself?

The usual case is events: If you assign a class member function as an event handler, the this keyword will not point to the object itself, but to something else, depending on the browser!

But how to access the object then?

var MyClass = function()
{
  var self = this;
 
  return {
    eventHandler: function(event)
    {
      self.beep();
    },
 
    otherFunction: function()
    {
      alert('beep');
    }
  };
};

Assign “this” to a variable in the scope of the function. Why didn’t I think of that?

No “extend”

How do you extend an object in JavaScript? Answer: You don’t… or not with a keyword, at least!

You can extend an object in JavaScript in the way you’d expect it to work in a class-based language, but it isn’t immediately obvious. You basically have to copy the prototype of the base-object to the child-object and add your new functionality to the child-object.

Luckily this is very simple these days, as most JS libraries provide an extension mechanism.

Due to the reasons mentioned in “member scope”, you will not be able to access private members in your child classes.

In closing

These are the four big things which confuse people in JavaScript OOP. At least they confused me a lot, and I admit they still do a bit. A lot of my JavaScript code is completely or almost completely procedural, but I’m working on learning the proper ways of OOP JS :D

What confuses you in JS?

Share this:

RSS feed Subscribe to my RSS feed

About the author

Jani is a 15 year veteran of the software industry. He's currently available for consulting

  1. 5 Responses to “Why Object-Oriented JavaScript is so confusing”

  2. Excellent forum! Added to my favorites.

    By Mikko on Dec 21, 2007

  3. The designer of JavaScript made a prototype object language, not a class-instance inheritance language.

    JavaScript resembles Self and Newtonscript.

    The words you express suggest you do not know the data memory and access model of JavaScript.

    Perhaps this is why you are struggling with Javascript.

    By Pier Johnson on Jan 11, 2008

  4. I have no idea what you are talking about =)
    What exactly are the data memory and access models of JavaScript, then?

    I can’t say I have ever seen anyone talk about the advantages of prototype-based inheritance or such compared to traditional class-based languages, so it’s kind of difficult to see the point of using prototypes.

    By Jani Hartikainen on Jan 11, 2008

  5. Prototype Inheritance. Uhg. Why Java is here to stay.

    By Anonymous on May 14, 2012

  6. Good post. After reading it I decided to elaborate bit more about the topic at JavaScript confusing bits.

    By Marek on Aug 12, 2012

Post a Comment

You can use some HTML (a, em, strong, etc.). If you want to post code, use <pre lang="PHP">code here</pre> (you can replace PHP with the language you are posting)