Adding property and methods to the function constructor or to the prototyp?

I can create a function constructor called Bird like this and add all it’s property and methods to it:

function Bird(name, numLegs) {
  this.name = name;
  this.numLegs = numLegs;

  this.eat = function() {
    console.log("nom nom nom");
  }
  this.describe = function() {
    console.log("My name is " + this.name); 
  }
}

let duck = new Bird("Donald", 2);
let canary = new Bird("Tweety", 2);

Is there any reason why instead of the above code, I should create my function constructor like the following code by adding the shared properties and methods to the Bird.prototype?

function Bird(name, numLegs) {
  this.name = name;
}

Bird.prototype = {
  constructor: Bird, // define the constructor property
  numLegs: 2,
  eat: function() {
    console.log("nom nom nom");
  },
  describe: function() {
    console.log("My name is " + this.name); 
  }
}

let duck = new Bird("Donald", 2);
let canary = new Bird("Tweety", 2);

Thanks

Multiple reasons are given in the challenge descriptions of OOP here at FCC. The ones I can remember from the top of my head:

  1. In your first code snippet, methods for eating and describing are created for every instance. If you would have one million instances (for example users), your app would have to load 1 million eat functions. Using the prototype, all your instances have access to that one function. So with one million instances you would still have only one function, giving better performance.

  2. You can add new properties and functions to the prototype which will immediately give these to all your instances as well. That won’t work in your first code snippet. That is:

Bird.tail = 1;

Will not work if you try to give a tail to your birds. However:

Bird.prototype.tail = 1;

Will give one tail to both your duck and canary, which you can call with either duck.tail or canary.tail.

But if I want to give a tail to my birds, I can do this:

function Bird(name, tail) {
  this.name = name;
  this.tail = 1;
}

And then I could access it with duck.tail and canary.tail.

What is the advantage of adding the tail to Bird.protoype ??

Well the advantages are that you can share one property with multiple instances (see my first advantage listed). Second advantage is that you can add properties or methods AFTER constructing your class.

Sorry, but I still don’t get it.
If I want to share new properties or methods with all instances of Bird, I just can add them to the constructor function Bird. Isn’t it?

Yes you can, maybe the best way to understand is to see it:

snip%201

snip%202

Do you see the difference between the outputs of the snips?

In the first snip duck has a function “eat” AND canary has a function “eat”. This means that your application has to remember TWO functions with each three lines of code that are actually just the same.

In the second snip, duck and canary do NOT have a “eat” function of theirselves. However they do have access to the prototype eat function. Because of this, they have can also use this function but it is only defined once in the system and just three lines of code for the application.

Now in our example it concerns two instances (duck and canary) and one simple function so it does not really matter. If there were millions of instances with multiple complex functions, we would be talking millions of lines of excessive code for your application to process.

2 Likes