javascript prototypes

Javascript prototypes are pretty much essential when dealing with objects in js and my friend was recently asked to explain them in a job interview, which he was fine doing. But it occurred to me that, even if I use them, I’m not sure I can clearly explain how they work. So that’s the goal on this post. See ya on the other side…

So a prototype is an empty object to start off. In Javascript, every object has the __proto__ property when it’s defined. It’s that property that makes the whole prototype chain accessible by the object. So, for instance, if you create a new function object, not setting any properties, you can still call .length on it, even though we never created a length property. When object.length tries to locate a length property, it won’t find one in the function, but will then go up the chain (which it can do because of the __proto__ property) and locate the length property.

var newObject = function {
return this;
};
console.log(typeof newObject); => function
console.log(newObject.length); => 1

When an instance is created, that property is updated to reference the constructor’s prototype.

console.log(newObject.__proto__ == Function.prototype); => true

Then, if you create a new instance using the keyword ‘new’ then this will happen:

var newInstance = new newObject;
console.log(newInstance.__proto__ == newObject.prototype); => true

So, the __proto__ property of the newObject object (which is of type function) accesses the prototype of the Function object. Then, if a new instance is created with ‘new’, its __proto__ property points to newObject.prototype because newObject is the constructor of the instance. So, not only does this new instance has access to all Function.prototype’s native methods, but also any methods we give newObject.

why use prototypes?

Let’s say we want to make a litter of puppies, each with the same age and breed. We could go ahead and create each one individually, but this would be inefficient and, depending on how many we make, could take up too much memory. So, if we want to create dogs that have a breed and an age (which is converted into dog years), it makes more sense to create a ‘master’ dog object (my terminology, not code’s) that all dog instances can then reference. That way, we don’t have to rewrite the methods every time we create a dog object.

var DogObject = function(name, breed, age) {
this.name = name;
this.breed = breed;
this.age = age * 7;
}
//this creates a dog object from which instances can be created
DogObject.prototype = {
breed = "golden retriever",
age = "1"
}

So now every instance of dog has this prototype. We can also add methods to the prototype. Let’s say we want to make each dog be able to bark. The prototype could look something like this:

DogObject.prototype = {
breed = "golden retriever",
age = "1",
bark: function(){
console.log("woof");
}

Here’s a visualization that might be useful, although it’s still a little confusing:

This super straightforward example of quora is also good:

function Person(name) {
this.name = name;
}
var jen = new Person("Jen");

^This creates an instance of Person using a function.

function Person(name) {
this.name = name;
}
Person.prototype.sayHi = function() {
alert("Hi. I'm" + this.name);
}
var jen = new Person("Jen");
jennifer.sayHi();

So, Jen doesn’t have a method called sayHi, but if you call that method on her (her? it? the jen object?), the interpreter will look to find it and won’t. Then it’ll check to see if it’s implemented in a prototype object that Jen is linked to. In this case, that would be Person. And when that function is called on Jen, the keyword “this” (in this.name = name) will refer to the object using the prototype at the time. So this.name = “Jen”.

That’s what I have so far. To sum it up, all objects have a property __proto__ when they are defined or instantiated, which gives them access up to chain to already-written properties. I read somewhere (and now I can’t find where) something that helped me visualize the difference between prototypical inheritance and classical inheritance: With classical inheritance you start with a cookie cutter and can make cookies using it. With prototypical inheritance, if you want to make more cookies you make copies of the first cookie.