Sorry for being stupid, but how is this:
Demo.prototype.foo = function () { } ;
different from this:
Demo.foo = function () { } ;
In both cases Demo ends up with a method called foo, yes?
No.
Demo is a function, used as a constructor function, and therefore
an object (all functions are objects and can have properties).
In the latter case, Demo itself has a method (a function property)
called "foo".
In the former, Demo has no property called foo, but the object
referenced by Demo.prototype does. That means that all objects created
by "new Demo()" will have an method called "foo", inherited from its
prototype.
I guess I don't understand the language but this line:
Demo.prototype = new Ancestor();
Looks like it's saying "Demo's prototype is Ancestor."
It reads like that, but it's not exactly what it means.
You are confusing the function "Ancestor" and the (non-function)
objects created from it using "new Ancestor()".
Constructor functions, like Demo and Ancestor here, are merely a
way to perform prototype inheritance between objects.
Each object in Javascript has another object as its prototype [1], and
it inherits all properties of that prototype object that isn't hidden
by a property on the object itself. Since the prototype itself is an
object and has a prototype, we talk about the prototype *chain* of an
object.
When writing "new SomeFunction()", what happens is that a new object
is created, and its prototype object is set to the object referenced
by SomeFunction.prototype at that time. After that, the body of
SomeFunction is executed with "this" referring to the new object.
After this, SomeFunction has nothing more to do with the new object,
it is just used for initialization.
So "Demo.prototype = new Ancestor()" really means:
Create a new object inheriting from Ancestor.prototype and
initialized by running Ancestor (and then we can forget about
Ancestor).
Then set that object as the prototype of objects created using "new
Demo()".
And this line:
Demo.prototype.foo = function () { } ;
looks like its saying "We will now assign a function foo to the the
prototype of Demo, which is Ancestor."
We will now assign a function to the prototype of objects created from
Demo (by "new Demo()"), which was originally created using Ancestor.
Now for the fun. Try running this and understand the results
---
function Foo(){};
function Bar(){};
var foo = new Foo();
var bar = new Bar();
Foo.prototype.baz = 42;
alert(foo.baz); // alerts 42! the prototype link is live
Bar.prototype = Foo.prototype;
alert(bar.baz); // alerts undefined. Inheritance is between objects,
// the function is not important afterwards.
alert(foo instanceof Bar); // alerts true - really tests if
// Bar.prototype is in foo's prototype chain.
// Again, the function itself is not important