views:

80

answers:

5

I have only recently started programming significantly, and being completely self-taught, I unfortunately don't have the benefits of a detailed Computer science course. I've been reading a lot about JavaScript lately, and I'm trying to find the benefit in classes over the prototype nature of JavaScript. The question seems to be drawn down the middle of which one is better, and I want to see the classical side of it.

When I look at the prototype example:

var inst_a = {
  "X": 123,
  "Y": 321,
  add: function () {
    return this.X+this.Y;
  }
};
document.write(inst_a.add());

And then the classical version

function A(x,y){
  this.X = x;
  this.Y = y;
  this.add = function(){
    return this.X+this.Y;
  };
};
var inst_a = new A(123,321);
document.write(inst_a.add());

I begun thinking about this because I'm looking at the new ecmascript revision 5 and a lot of people seem up in arms that they didn't add a Class system.

+2  A: 

With the second method you can create instances of A, allowing you to have multiple at a time. For example:

var inst_one = new A(123,321);
var inst_two = new A(456,654);

// some meaningful code here...
document.write(inst_one.add());


// some more meaningful code here...
document.write(inst_two.add());

The example you provided is trivial, so let's make up a more intuitive example:

function Comment(user,text){
  this.user = user;
  this.text = text;
  this.toString = function(){
    return '<span class="comment">'+this.text+' - <a class="user">'+this.user+'</a></span>';
  };
};


var comments = someFunctionThatReturnsALotOfCommentObjects();
for(c=0;c<comments.length;c++)
  document.getElementById('comments_container').innerHTML += comments[c].toString();

This (hopefully) demonstrates the benefit of being able to create multiple instances of a class. This is not a fundamental JavaScript concept, it's a fundamental Object Oriented Programming concept, which may be why you are unfamiliar with it if you haven't had formal programming courses.

Josh
You can also make another inst_* with the prototype of inst_a and update the X and Y or add more properties. I personally would implement a Object.clone, that takes care of duplicating.
Rixius
@Rixius Oh yes. I could spend all day creating examples of how OOP is useful :-D
Josh
Thanks for the better example.
Rixius
+3  A: 

When you create an object via new, it will use it's prototype chain to look for properties not found in the instance.

So, for example, you could add the add method to A.prototype just once, instead of redefining a new copy of the same function every time you create a new instance of A.

function A(x,y){
  this.X = x;
  this.Y = y;

};
//define add once, instead of every time we create a new 'A'
A.prototype.add = function(){
    return this.X+this.Y;
  };
z5h
+1, that is better style
Josh
A: 

The classical version allows you to declare private variables scoped "inside" the object, whilst the prototype version does not.

Alessandro Baldoni
Not true. You can create closures in the prototype version.
Josh
+1  A: 

To be fair JavaScript does have classes. Well, maybe some would argue with that, but I consider it just semantic splitting of hairs. If a class is taken to be a blue print for creating objects than a JavaScript function can serve in that capacity. There's not much difference in function here, only form:

class someObj
{
    private int x;
    public int returnX()
    {
        return x;
    }
}
someObj temp = new someObj();

-

function someObj {
    var x;
    this.returnX = function() {
        return x;
    };
}
var temp = new someObj();

Under the hood they're different, but you can use either form to serve the same end.

Prototypical really differs in inheritance. In prototypical inheritance when you create a new object you're really copying an instance of the prototype object and then adding new fields or members to it. Classical inheritance, on the other hand, isn't dealing with an instance but just a "blue print". For instance, in JavaScript you'd say:

temp.prototype = new someOtherObj(); //Creating a new instance to serve as the prototype.

In a classical language you might say:

class someObj : someOtherObj //Copying the "blue print" over.

The implication is that data will be shared among derived objects in the prototype language. I once wrote a function and had another function derive from it through prototyping in JavaScript. This base object held a reference to a DOM object and when I would change it in one child object it would change it for all instances of that child object. This is because, again, in the prototype language you're deriving from an instance and not a "blue print".

Bob
+3  A: 

Inheritance is not really possible without using the psuedoclassical style. See what Douglas Crockford has to say about it. Even if you were to use a purely prototypal object structure, you'd have to create a constructor function for inheritance (which Crockford does, then abstracts it behind a create method then calls it purely prototypal)

Hooray Im Helping
Thanks for the link.
Rixius
+1 for Inheritance -- excellent point and one of my favorite parts about OOP.
Josh