Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript Object-Oriented JavaScript (2015) Constructor Functions and Prototypes Methods with Prototypes

What is the prototype in javascript?

I'm trying to wrap my head around the prototype property in JS.

So, in the video, Andrew says that you use the prototype property to add methods/properties to the constructor function. You do this in order to save RAM and prevent duplicating your code.

So, each new instance of the function also means that your eating up more RAM because each new instance calls the same methods/properties over and over. Yet, if you create a method using the prototype property, you only call the method once?

function Car(color, sound) {
  this.color = color;
  this.sound = sound;
}

Car.prototype.honk = function() {
  alert(this.sound);
}

var honda = new Car('black', 'beep');

The reason for this, is to create a function and link it to the Car constructor function. This way, the method is only used in memory once. Yet, can be used over and over for different instances?

But I didn't fully understand Andrews reasoning for not creating a function like below. It still links to the constructor function. Is the reason because if you have lots of code, the function honk(), for example, could become ambiguous? so its best practice to be more explicit. Thus the reason for using the above example when adding methods/properties?

function honk() {
 alert(this.sound);
}

function Car(color, sound) {
  this.color = color;
  this.sound = sound;
  this.honk = honk();
}

var honda = new Car('black', 'beep');

Thanks in advance

Also, wouldn't the prototype get called every time too?

I don't understand how the constructor will get called each time, but the constructor prototype only gets called once

the prototype property accesses the blank object contained within the constructor function. There, new methods and properties can be added.

function Car(color, sound) {
    this.color = color;
    this.sound = sound;
 }

Car.prototype.honk = function() { 
    console.log(this.sound);
 }

//this adds the function “honk” to the constructors prototype. 


var honda = new Car('black', 'beep');

/*inside the constructor function, ’this’ refers to the new object created 
i.e. ‘honda’ - so really, its saying

honda.color = ‘black’;
honda.sound = ‘beep’;

honda.honk();
*/

because the method isn’t inside the constructor function, Javascript will then go one level up, and check the constructor’s prototype - if the function is found, it will then apply the method to the newly created instance i.e. 'honda'

5 Answers

Brodey Newman
Brodey Newman
10,962 Points

Each time you bind a new method to the prototype object, you allow each instance to utilize that method due to inheritance.

One benefit to this is the fact that if you were to update your honk method, it will be updated for each instance of that Car constructor. If you use a public method for this, each instance of that Car object would have to be reassigned.

Another downfall to using a public method is the fact that each time a new instance is created, that public method also has to be created.

This stackoverflow post explains it pretty well.

https://stackoverflow.com/questions/4508313/advantages-of-using-prototype-vs-defining-methods-straight-in-the-constructor

I hope this helps!

I think the main reason why

function honk() {
 alert(this.sound);
}

function Car(color, sound) {
  this.color = color;
  this.sound = sound;
  this.honk = honk;
}

is not the desired is because function honk is now an external function not belonging to Car function. It only keeps reference to it. As the application gets bigger we now need to always keep track of function honk so things may get messy if we are not careful. But by making function honk a method on Car's prototype object, we can now ensure that function honk belongs to Car so now it is easier to track and also more organized as well.

function Car(color, sound) {
    this.color = color;
    this.sound = sound;
}

Car.prototype.honk = function() { 
    console.log(this.sound);
}
Ana Luiza Barreto Marinho
Ana Luiza Barreto Marinho
2,210 Points

Think of Prototype as if it were the human genes, a healthy human will have two working eyes, two working hands, skin, etc, etc... Thing is as we are different somethings will change like the color of our eyes or the shade of our skin, but we all have eyes, skin, hair (ok, not all of us have hair... loool), etc, etc. We all have the same prototype, the same base for construction (a.k.a blueprint). We all inherit those from a long lost prototype. There's not way there's need to genetically engineer a whole human being every time someone wants to have a baby, right? There're already genes that say everything a healthy human being has to have.

Well prototypes work the same way, there's something called prototypal inheritance (which I'm pretty sure Andrew has explained in on of his videos), which works pretty much like that human talk up there, we will always have the same functionality with one or two little differences which don't interfere on how it will work.

function Person (eyeColor, hairColor, skinShade) {
 this.eyeColor = eyeColor;
 this.hairColor = hairColor;
 this.skinShade = skinShade;
}

Person.prototype.catchPhrase = function (catchPhrase) {
 window.alert (catchPhrase)
}

angelica = new Person (green, black, brown);
angelica.catchPhrase('Things are getting too hot for the pepper');

bruno = new Person (brown, brown, white);
bruno.catchPhrase('And there we go...');

/* See? It's as I explained, these are two different people (but still people) with two different catch phrases, which are
still catch phrases, that do exactly the same thing (appear in an alert box as soon as you open a window) */

Hope this helps :). Here's a link: https://medium.com/@kevincennis/prototypal-inheritance-781bccc97edb (this might help) Here's a book: http://shop.oreilly.com/product/0636920027065.do (this might also help)

Jeff Wong
Jeff Wong
10,166 Points

I think I can answer your first question regarding how assigning method to the instances' prototype can save RAM memory compare to assigning method in the constructor.

Consider the example you have given, let's make 3 instances of Car when the method honk is define inside the constructor, and console log each of the instances: (by the way, there's a mistake in your code: the method defined inside the constructor should be written as this.honk = honk, instead of this.honk = honk(), because if you include the parentheses then the method will be called straight away, making it a self-invoke method)

function honk() {
 alert(this.sound);
}

function Car(color, sound) {
  this.color = color;
  this.sound = sound;
  this.honk = honk;
}

let honda = new Car('black', 'beep');
let toyota = new Car('white', 'beep2');
let suzuki = new Car('blue', 'beep3');

console.log(honda); // logs Car {color: "black", sound: "beep", honk: f}
console.log(toyota); // logs Car {color: "white", sound: "beep2", honk: f}
console.log(suzuki); // logs Car {color: "blue", sound: "beep3", honk: f}

See how it violates DRY principal? If you create 100 instances of Car, they would all have the same method - honk: f. This is what Andrew means when he said doing this would eat up the RAM and make the program slow.

This is where the concept of inheritance becomes useful. By assigning method to the prototype of the instances, it will only take up one space in the RAM (as honk: f will only show up in Car.prototype, but not all instances of Car), and all instances of Car can use the honk method due to inheritance. It will become clearer as I demonstrate the example below:

function Car(color, sound) {
  this.color = color;
  this.sound = sound;
}

Car.prototype.honk = function() {
  alert(this.sound);
}

let honda = new Car('black', 'beep'); 
let toyota = new Car('white', 'beep2'); 
let suzuki = new Car('blue', 'beep3'); 

console.log(honda); // logs Car {color: "black", sound: "beep"}
console.log(toyota); // logs Car {color: "white", sound: "beep2"}
console.log(suzuki); // logs Car {color: "blue", sound: "beep3"}
console.log(Car.prototype); // logs {honk: f, constructor: f}

Now, you don't see honk: f listed as properties of honda, toyota or suzuki when we console log them, but that doesn't mean that we can't call honk with them. It just means that honk is not their own method when they are created with the Car constructor, as oppose to color and sound, which are their own properties. Although honk is not their own method, they can still call it because they inherited the method from their prototype. And now if we create 100 instances of Car, we don't have to create the same 100 honk method for all of them. Another example of method that don't get created every time we create an object but are usable by all objects is the toString method which is defined on the root of all objects, the Object.prototype.

honda.honk(); // alert beep
toyota.honk(); // alert beep2
suzuki.honk(); // alert beep3
honda.toString(); // ["object Object"]
honda.hasOwnProperty('toString'); // false
Object.prototype.hasOwnProperty('toString'); // true

Hopefully this explanation gives you an idea of how assigning method to instances' prototype is better than assigning it in the constructor in terms of saving memory space.

I found this youtube video helpful.... https://www.youtube.com/watch?v=7oNWNlMrkpc