JavaScript is a funny language. For a few weeks I have been reading the book "JavaScript : The Good Parts" by Douglas Crockford. This is the first time I've tried to look at javascript as more than a language just for browser. Syntactically javascript is pretty much like C, but it has much more in common with Lisp than with C. For someone familiar with languages like C and Java, it can be pretty weird at first reading.
One of those weird/funny things is that JavaScript has Class-free objects. There is no class hierarchy, objects inherit from objects. JavaScript provides prototypical inheritance. Every function object in javascript has prototype property whose value is an object containing a constructor property whose value is the function object.
The language attempts to provide pseudoclassical inheritance so that programmers used to the classical style don't feel bad. But in that attempt, the language has become even more complex and messy. Here is an example from the book :
So as we can see this code looks quite arbit and weird. So, instead of using this pseudoclassical complicated approach, we can try to use Prototypical inheritance as it should be used. The author has provided some good ways to get rid of this mess. One way is to define a method like following :
Now we can just write :
In all these techniques, there is something quite important that we haven't yet paid attention to. That is the idea of encapsulation. Here we use closures fundaes. Let's revisit the cat and mammal example :
I've given brief description here. If someone wants more details, they can visit
http://www.crockford.com/javascript/inheritance.html
http://javascript.crockford.com/prototypal.html
One of those weird/funny things is that JavaScript has Class-free objects. There is no class hierarchy, objects inherit from objects. JavaScript provides prototypical inheritance. Every function object in javascript has prototype property whose value is an object containing a constructor property whose value is the function object.
this.prototype = {constructor : this};The language attempts to provide pseudoclassical inheritance so that programmers used to the classical style don't feel bad. But in that attempt, the language has become even more complex and messy. Here is an example from the book :
//define constructor for the pseudoclass
var Mammal = function (name) {
this.name = name;
};
//augment its prototype
Mammal.prototype.get_name = function ( ) {
return this.name;
};
Mammal.prototype.says = function ( ) {
return this.saying || '';
};
//we can make an instance:
var myMammal = new Mammal('Herb the Mammal');
var name = myMammal.get_name( ); // 'Herb the Mammal'
//make another pseudoclass that inherits from Mammal var Cat = function (name) { this.name = name; this.saying = 'meow'; }; // Replace Cat.prototype with a new instance of Mammal Cat.prototype = new Mammal( );
// Augment the new prototype with get_name method. Cat.prototype.get_name = function ( ) { return this.says( ) + ' ' + this.name + ' ' + this.says( ); };
var myCat = new Cat('Henrietta'); var says = myCat.says( ); // 'meow' var purr = myCat.purr(5); // 'r-r-r-r-r' var name = myCat.get_name( ); //'meow Henrietta meow'So as we can see this code looks quite arbit and weird. So, instead of using this pseudoclassical complicated approach, we can try to use Prototypical inheritance as it should be used. The author has provided some good ways to get rid of this mess. One way is to define a method like following :
Object.beget = function(o) {
var F = function () {};
F.prototype = o;
return new F();
};
Now we can just write :
new_object = Object.beget(old_object);
And then we can make changes to the new object without affecting the old one. This is called differential inheritance.
In all these techniques, there is something quite important that we haven't yet paid attention to. That is the idea of encapsulation. Here we use closures fundaes. Let's revisit the cat and mammal example :
var mammal = function (spec) {
var that = {};
that.get_name = function ( ) {
return spec.name;
};
that.says = function ( ) { return spec.saying || ''; }; return that; }; var myMammal = mammal({name: 'Herb'});
var cat = function (spec) { spec.saying = spec.saying || 'meow'; var that = mammal(spec); that.purr = function (n) { var i, s = ''; for (i = 0; i < n; i += 1) { if (s) { s += '-'; } s += 'r'; } return s; }; that.get_name = function ( ) { return that.says( ) + ' ' + spec.name + ' ' + that.says( ); } return that; }; var myCat = cat({name: 'Henrietta'});
I've given brief description here. If someone wants more details, they can visit
http://www.crockford.com/javascript/inheritance.html
http://javascript.crockford.com/prototypal.html