So, Javascript objects work A LOT differently than in other programming languages. Well, most mainstream ones anyway.
Here's the deal - a Javascript object is really just a dictionary (aka map). For example:
var x = {}; // creates a new blank object
x.something = 42; // creates a property on the object and assigns value to it
x['something'] = 15; // Alternate syntax. Assigns to the same property we just created.
x['yo, this is valid too!'] = true; // Yes, this is valid too.
See what I mean? It's just a dictionary, you can set whatever you want. And unset too - that's what the delete operator does.
So what about those constructors and prototypes? Well, any function can be used as a constructor. When you go like
var x = new foo();
What really happens is that Javascript creates a new blank object and then calls the foo() while putting the newly created object in this. And lo and behold, it kinda looks like a constructor.
There's actually a little quirk that needs to be mentioned. If the constructor function returns a value, then Javascript uses that instead of the newly created object. So if you do this:
function foo() {
this.meaning = 42;
}
var a = new foo();
Then a will contain the blank object that Javascript created for you. But if you do this:
function foo() {
this.meaning = 42;
return {nope: 3};
}
var a = new foo();
Then a will contain the {nope : 3} object instead. OK, but that's rarely used.
Anyway, where were we? Ah, yes, prototypes. Oh, wait, first another thing needs to be explained. In Javascript EVERYTHING is an object. So, like, these things are completely valid:
var a = 42;
var b = "hello, world";
a.foo = "yay";
b.bar = 10;
And, just to really blow your mind there, functions are objects too. First class citizens, so to speak. This is all valid:
function foo() {
}
foo.bar = "baz";
var x = foo;
Yup, you can treat functions just like any other object. You can put them in variables, pass them to other functions in parameters, assign and delete arbitrary properties to them, you name it. This is a feature rarely found in other languages, so it's probably the hardest thing to wrap your mind around. I know my mind was blown when I first understood this.
Now we can talk about prototypes. You see, every function in Javascript also has a special magical property called prototype. By default, it's set to a blank object. But you can set it to another object. Or you can add/delete properties to the existing blank object. It's just another object, nothing fancy about it.
Furthermore, every object in Javascript has a special magical property called __proto__. Remember that when you call new foo() a new object is created and passed to foo() as this? Well, that new object has its __proto__ set to whatever foo.prototype was at the time.
Now suppose you do this:
function foo() {
this.a = 42;
}
foo.prototype.b = 15;
var x = new foo();
If you then type x.a then x has such a property and all is well. But if you type x.b then x doesn't have such a property, and that's where the magic happens. Javascript automatically checks if there is a x.__proto__.b and if there is, returns that! And if there isn't, it checks x.__proto__.__proto__.b, etc, until it hits an object with __proto__ == null and then it gives up and just returns undefined since there is no such property.
On the other hand, when you now do this:
x.b = "foobarbaz";
Then the b property is created directly on the x object. The prototype remains unchanged.
So this is how you create "inheritance" in Javascript. With the prototypes. It's different than in your typical class-based language, but no less powerful.
There are some other nuances and tricks that could be mentioned, as well copious amounts of examples to help you grok all this, but... I've run out of juice for today. :) This should answer the question as well as hopefully make more sense of whatever other tutorial you are reading.