I know Javascript for some time, although I am not a heavy user, I know it the first from the time when Netscape was my browser. I pretty much understand the main things, but since JavaScript approach to OOP is prototypical I have some problem grasping it.
One problem to add to this it seems that things can be done in more than one way, and here is where books don’t help much because they put all the examples on the table making it hard to keep the pace.
What I need for start is only one way of doing it, if someone can help me with the simplest code possible an example where I can see how the prototypal OOP model works?
To be helpful the code should have an inherited object, to access a parent’s property and its inherited properties and a parent’s function, to overwrite a parent’s function and and have an instance of a multiple inheritance where an object inherits two other objects.
13
How can be inherited an object?
function inherit(o){ // inherit is called Object.create in modern implementations
var F= function(){};
F.prototype=o;
return new F();
}
var parent = {
name: "Josh",
print: function(){
console.log("Hello, "+this.name);
}
};
parent.print(); // Hello, Josh
var child = inherit(parent);
child.name = "Jeremy";
parent.print(); //Hello, Josh
child.print(); //Hello, Jeremy
How can I see a parent’s property?
console.log(child.__proto__.name); //won't work in IE; also see getPrototypeOf
How can I access a parent’s function?
Object.getPrototyepeOf(child).print(); // or
child.print.apply(parent) //functions are just objects, and 'this' pointer can point to wherever you want
How can I overwrite a parent’s function?
child.print = function(){
console.log("Hi ", this.name);
}
parent.print(); //Hello, Josh
child.print(); //Hi, Jeremy
How an object can inherit two objects?
//in chain?
grandchild = inherit(child);
//otherwise, there's no way.
grandchild.name = "Eddie";
grandchild.print();
Also see:
- Mozilla Developers Network Inheritance guide
- Object.getPrototypeOf on MDN
- Douglas Crockford’s second series of videos on JavaScript (the first one started the javascript revolution, the beginning is boring but full of surprises; the rest is full of surprises)
- Crockford’s Book (once I went into a team of 15 people who were working on one of the large JS apps out on the web made by a large, well-known company – I counted 5 of this on the desks)
- Current specification drafts as they include built-in classes
- Coffeescript, a JS-based language which is popular among JS-developers and supports classes
1
The hilarious expert @venkat_s shares an analogy to grasp prototypal inheritance.
Here is a sample of his humor, “The thing about JavaScript is, it doesn’t yell at you. It is your friend. It wont tell you when something is wrong, it will just stop working. Stop calling you”
For inheritance he continued, “The prototype is like a backpack – to the object. For everything in JavaScript that is an object – it has a backpack, and you can put stuff in it. And all your objects can access it.”
Hope that helps.
2
Forget code. The simplest explanation.
Function constructors build objects. In JS, functions are themselves objects which can have properties. Every function has a prototype property which can contain any object. You can set any constructors prototype easily on the fly. If you want to ruin arrays for instance,
Array.prototype = {
oneTrueMethodToRuleThemAll: function(){
alert('arrays are now hosed');
}
}
The prototype object is basically a fallback that gets checked by instances when you try to reference a property they don’t have. If the prototype object doesn’t have that method, its constructor’s prototype object gets checked for the method. That’s the chain that gets followed.
So it’s not really about inheritance. It’s about, “Oh, you don’t have that, well does your mother have it in her prototype bag? No? How about her grandmother? No? Then how about .. until we get to Eve, or the Object constructor’s prototype which is where the buck always stops.
So it’s not that your instances pick up or retain the stuff in the prototype. It’s just that when JavaScript calls a method of an object there is fallback process for checking the object->constructor.prototype chain to see if the unknown method can be found. And that’s why when you change a constructor prototype, all existing instances “get” that method. They don’t really get anything at all. It’s their fallback set of objects for lookup that gets the new method.