Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / Javascript

Comparing JavaScript OOP to .NET

4.85/5 (26 votes)
8 May 2013CPOL6 min read 32.2K  
This article is intended to help conceptualize the area of JavaScript Object Oriented Programming by comparing it to the way .NET CLR works.

Introduction 

This article is intended to help conceptualize the area of JavaScript Object Oriented Programming by comparing it to the way .NET CLR works. My background is in .Net so I am used to simply defining a C# class but JavaScript uses such concepts as function constructors, the prototype, the constructor property of the prototype, _proto_ and so forth.  In order to learn these concepts I started to compare the way the CLR worked to how JavaScript works and when I understood the differences I then started to realize why you do things a certain way in JavaScript. I will assume you are familiar with the basics of OOP. I will be using C# code for the examples in .NET.

Reference Types 

So in c# when you want to create a reference type you use a class. Let's say we create a Person class that looks like this

C#
public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string GetFullName()
    {
        return FirstName + " " + LastName;
    }
} 

and then you would instantiate an instance like this

C#
var p = new Person { FirstName = "Jon", LastName = "Smith" };
Console.WriteLine(p.GetFullName()); 

Let's say you just started your program and this is the first time anything has used the Person object. What exactly is happening. For any reference type in  the CLR there are actually 2 objects that get created. The type object and then the actual instance of that object. So as soon as the code above runs we could say we have one Person object and then one p object that is of type Person. The instance of p will have a pointer that connects back to the Person object so that it knows what type of object it is. There will only ever be one Person type object but many instances of Person. Ok, so what is the point of this, why 2 objects? Well if we think about the responsibilities of the members of a type: fields and methods (FirstName, LastName, GetFullName) what is each one suppose to do.  Take FirstName/LastName. Each time you create a new instance of Person, it needs to have its own values for FirstName and LastName. Each time you create a Person p, p1, p2, p3... etc. you can't have them using the same instance of FirstName LastName. If you change the FirstName in p1 it should not change the FirstName in p2. Right? Ok, so what about methods. Does every instance of Person need its own copy of method GetFullName. All this method does it take the values from the instance and concat them together. It doesn't do anything specific to a certain person. And make sure to understand that each method that is used during runtime takes up memory. So its probably not a good idea for each instance of Person to have its own method GetFullName. Luckily they don't. This is what the Person type object is for. It holds the references to all the methods defined on it and because the instances have a pointer back to the Person type object they can find where those methods are when they need to use them. So now we have our basis for how types should be structured, each instance of an object has its own fields but they all share the same methods which exist on the type object. You might ask how all this is accomplished. Well, luckily for .net developers this is all done automatically by the CLR. You don't have to worry about creating a type object or pointing things back to this type object or making sure only one method gets created or anything of that nature. 

So what does this have to do with JavaScript? Well I have described the way things work in .NET and that is how they should work to ensure optimal performance. The point I'm trying to make here is when doing OOP in JavaScript this stuff doesn't happen for you automatically. You have to do it yourself.
So to define a Person type in the way JavaScript does it we would have code like this:

JavaScript
 function Person(fn,ln)
{
    this.FirstName = fn;
    this.LastName = ln;
    this.GetFullName = function()
    {
        return this.FirstName + ' ' + this.LastName;
    }
}
 
var p = new Person('jon','smith');
alert(p.GetFullName());  

Great, this looks pretty similar to C# and it does exactly what we want, so whats the problem? The issue here is one of our basis for how types should be structured is not being met. If you do it this way in JavaScript each instance of Person will have its own copy of the method GetFullName. This of course is a waste of memory. So how do we make all instances share this method. You might ask, well doesn't javascript create a type object like in .NET, nope, well kind of. This is where the prototype object comes in. The concept of this thing can get a little confusing. In my opinion its best not to think about it too much. Just picture it this way; when you create a function in JavaScript, a hidden property is put into it by the JS engine without you knowing. So when we created our Person function, it really looked like this:  

JavaScript
function Person(fn,ln)
{
    
    this.FirstName = fn;
    this.LastName = ln;
    this.GetFullName = function()
    {
        return this.FirstName + ' ' + this.LastName;
    }
} 
Person.prototype= {};  

You could consider the prototype object as being the same thing as a .NET type object. But the big difference is that the methods aren't automatically put into the prototype object by default. You have to do that yourself. Just remember this is where you want to put all your functions that should only be created one time and shared among all instances. So how do we put functions there. Just like this: 

JavaScript
function Person(fn,ln)
{
    this.FirstName = fn;
    this.LastName = ln;
}

Person.prototype.GetFullName = function()
{
    return this.FirstName + ' ' + this.LastName;
}
 
var p = new Person('jon','smith');
alert(p.GetFullName()); 

You might be wondering how when you call p.GetFullName() it somehow knows to look on the prototype object instead of the p object. JS just does this automatically, you don't need to worry about it. 

Ok so now what is the problem here. There's nothing technically wrong with this approach but it may be confusing to see a method on an object defined on the outside of the object definition. Can't we just put it inside? Why yes we can, just like so

JavaScript
function Person(fn,ln)
{

    this.FirstName = fn;
    this.LastName = ln;
    Person.prototype.GetFullName = function()
    {
        return this.FirstName + ' ' + this.LastName;
    }
}

var p = new Person('jon','smith');
alert(p.GetFullName());

This looks good but there is one little issue. You are now again recreating the GetFullName method every time an instance of an object is created.  Of course there is no reference to the previous one so it will get garbage collected anyways but its still a little bit of a waste. Again, if we compare this to .NET, the CLR automatically handles determining if a method has already been created and if it has it doesn't create it again. But since JS doesn't do that for us, we will have to do it ourselves. We do this by using the following: 

JavaScript
function Person(fn,ln)
{
    this.FirstName = fn;
    this.LastName = ln;
    if(typeof this.GetFullName != "function"){
        Person.prototype.GetFullName = function()
        {
            return this.FirstName + ' ' + this.LastName;
        }
    }
}
var p = new Person('jon','smith');
alert(p.GetFullName()); 

So we now have a check to see if the function already exists and if it doesn't we add it. And there we have it. A good implementation of mimicking a C# class in JavaScript. 

Ok that is it for now, I know is a short article but I will continue on in a Part II covering Inheritance. 

License

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