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

Comparing JavaScript OOP to .NET

, 8 May 2013
Rate this:
Please Sign up or sign in to vote.
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

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

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:

 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:  

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: 

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

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: 

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)

About the Author

Jon Woo
Software Developer eLeadCrm
United States United States
No Biography provided

Comments and Discussions

 
SuggestionSuggestion - Need more on this topic PinmemberTridip Bhattacharjee9-Jul-14 21:33 
GeneralMy vote of 5 PinmemberPankaj Deharia24-Jul-13 1:27 
GeneralMy vote of 5 PinmemberChristopher Sommers4-Jun-13 4:15 
GeneralMy vote of 5 PinmemberAmitosh Swain18-May-13 15:30 
Questiongood lesson Pinmemberaaroncode15-May-13 8:56 
QuestionIsn't that what Typescript does ? PinmemberKlausObd15-May-13 6:03 
AnswerRe: Isn't that what Typescript does ? PinmemberJon Woo15-May-13 6:28 
AnswerRe: Isn't that what Typescript does ? PinmemberPaulo Zemek15-May-13 6:41 
Questiongood article, check this out too PinmemberRay_Cheng8-May-13 18:26 
Questioncould be helpful but... PinmemberTrajan McGill8-May-13 13:21 
AnswerRe: could be helpful but... PinmemberJon Woo8-May-13 14:42 
GeneralMy vote of 5 PinmemberDennis E White8-May-13 4:26 
GeneralMy vote of 4 PinmemberMohammed Hameed8-May-13 3:47 
QuestionMy vote of 5 PinmemberSarafian8-May-13 3:35 
GeneralMy vote of 5 PinprofessionalCarlos19077-May-13 16:06 

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
Web01 | 2.8.140721.1 | Last Updated 8 May 2013
Article Copyright 2013 by Jon Woo
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid