Based on Javascript: the good parts by Douglas Crockford from Oreilly and his presentation.
I felt it’s hard to fully understand his point on prototypal inheritance, so I tried to explain it in my way with code.
// * Classical way of object creation // // Constructor: var Quo = function() { } // Method: Quo.prototype.breathe = function() { return "Quo"; } // Don't forget new. That's a terrible disaster and won't raise any error. q = new Quo(); alert(q.breathe()); // Quo // Question is.. do we need that prototype hassele? Quo.bark = function() { return "Bark"; } // Yes. Without prototype, this is an error: // alert(q.bark()); // // The thing is, bark is Quo's function and not that of q. Why? Because // when 'new' is called, a new instance is created and it derives from // the prototype of Quo. (It doesn't derive Quo directly.) // As I said, Quo has bark. alert(Quo.bark()); // Bark // Inheritance via prototype var QuoChild = function() { } QuoChild.prototype = new Quo(); var quoChild = new QuoChild(); alert(quoChild.breathe()); // Quo alert(quoChild.bark()); // Bark // prototype must be an instance. This is an error: // QuoChild.prototype = Quo; // * Prototypal way // // Object.create will be added in the next version of javascript, // but we can create one now. if (typeof Object.create != 'function') { Object.create = function(o) { function F() { } F.prototype = o; return new F(); } } // This is an object literal. It's not a class. It's an instance itself. var Mammal = { name: 'Mammal', breathe: function() { return "I'm breathing"; } }; var cat = Object.create(Mammal); // This is a property of the cat instance. cat.breathe = function() { return "I'm meow"; } // cat is an instance who does not have prototype of it. So, this is an error: // cat.prototype.breathe = function() { // return "I'm barking." // } // // As an example, this is an error, too: // // var o = new Object(); // o.prototype.breathe = function() { // return "ooo"; // } // // So, it's simple that cat should have a function as the property of itself, // if it wants to. alert(cat.breathe()); // I'm meow var dog = Object.create(Mammal); alert(dog.breathe()); // I'm breathing. // Prototyping from smallCat is okay. An object created by new F()'s prototype // is cat. var smallCat = Object.create(cat); alert(smallCat.breathe()); // It is not still obvious why Prototypal way is worth trying. It's because // of private members. var parent = function() { var F = function () { } function F() { } function private_func() { return "private"; } F.prototype.public_func = function() { return private_func() + " called by public"; } return new F(); }(); alert(parent.public_func()); // private called by public // This is a private function. So, error: // alert(parent.private_func()); // private var child = Object.create(parent); alert(child.public_func()); // private called by public // There's no way to add a function to call private_func like this: // child.child_public_func = function() { // // No.. private_func is not here. // return private_func(); // }
So, here’s the status of inheritance in javascript that I feel:
1) It’s bad that there’s no warning when there’s no new.
2) Writing ‘prototype’ keyword again and again in classical way is terrible.
3) Prototypal way is pretty neat, but
4) Grammar becomes terribly complex when I try to add a private member. If a language is going to be that much complex, not everyone will use it, and the feature will be forgotten.