First of all, I suggest you take a look at this playlist featuring the man himself (Crockford). It might be old, but it really explains JavaScript "logic" very well, and your question is particularly answered in the third video.
I'm going to begin answering this question by describing how objects are depicted in other traditional Object-Oriented Programming languages, because I want to also target the Crockford comment you have posted in the start of the question.
In order to understand Constructors, you first have to have a good understanding of Objects. In traditional OOP languages, an Object is a collection of variables (called properties or fields) that describe the object's state, as well as functions (called methods) that describe it's behaviour. In those (non-JavaScript) languages, the "blueprint" of those objects is called a Class.
So, if I create a Human class in Java, a very simplistic depiction would look like this:
class Human {
String name;
int weight; // kg
int height; // cm
void eat(int foodWeight) {
this.weight += foodWeight;
}
Human(int weight, int height, int name) {
this.weight = weight;
this.height = height;
this.name = name;
}
}
And then, I would create an Object using the above "blueprint" like so:
Human Joe = new Human(90, 180, "Joe");
And now, we say Joe
is an instance of Human
, whose weight is 90 kg and height is 180 cm.
In the class above, you noticed I had a function Human()
that was used to create the object and define it's state as it was created. This is essentially what a Constructor does.
So what's different about JavaScript?
In order to appeal to the masses at the time of it's creation (as you will hear in the video series I posted), JavaScript incorporated some Java-like syntax. What this has done, according to Crockford, is giving programmers the idea that, because they already know/learned some Java, then they can just learn a few new commands and then go ahead and program in JavaScript, while in reality, the differences between the two far outweigh their similarities.
In JavaScript, in order to create an object in a way that it looks like a Java class, you would use the function syntax like so:
var Human = function(name, height, weight) {
this.name = name;
this.height = height;
this.weight = weight;
this.eat = function(foodWeight) {
this.weight += foodWeight;
};
};
And then, if you want to define Joe
as we did above, you would do the following:
var Joe = new Human("Joe", 180, 90);
You can see the similarities between the Java and JavaScript syntaxes shown. So, to answer your first question: JavaScript Constructors are functions that, when called with new
, create and return an implicitly created object, pointed to by this
.
So where does the Prototype come in? Well, In JavaScript, functions are also JS objects themselves, and they have a property called prototype
. So, the Human()
constructor we created above has a property called prototype
, and this property refers to an object whose properties and methods are inherited by Joe
, as well as all other instances of Human
, and this object can be extended in order to create properties that will be inherited by all of those instances.
For example, one of the methods in Function.prototype
is the famous toString
method. You could define
Human.prototype.toString = function() {
return this.name + " is " + this.height + " cm tall and weighs " + this.weight + " kg";
}
then, if you call Joe.toString()
or when you do something like alert(Joe)
that automatically calls toString()
, the value returned would be "Joe is 190 cm tall and weighs 80 kg".
There are many more details about OOP and JavaScript that could be covered in the context of your question, but I think my answer is long enough! I hope this answers your question.