Confused with prototypes

Prototypes confuse me so much, doooh!

In the following example:

function Animal() { }
Animal.prototype.eat = function() {
return “nom nom nom”;
};
function Bird() { }

// Inherit all methods from Animal
Bird.prototype = Object.create(Animal.prototype);

// Bird.eat() overrides Animal.eat()
Bird.prototype.eat = function() {
return “peck peck peck”;
};

why do we always use the .prototype notation? Would it be different to just have it like that? :

function Animal() { }
Animal.eat = function() {
return “nom nom nom”;
};
function Bird() { }

// Inherit all methods from Animal
Bird= Object.create(Animal);

// Bird.eat() overrides Animal.eat()
Bird.eat = function() {
return “peck peck peck”;
};

Isn’t it the same thing?

Thank you in advance!

In the following example, the Bird constructor defines two properties: name and numLegs:

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

A better way is to use Bird’s prototype . The prototype is an object that is shared among ALL instances of Bird . Here’s how to add numLegs to the Bird prototype:

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

Bird.prototype.numLegs = 2;

Now all instances of Bird have the numLegs property:

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

console.log(duck.numLegs); // prints 2
console.log(canary.numLegs); // prints 2

since all instances automatically have the properties on the prototype , think of a prototype as a “recipe” for creating objects.

In the following example:

function Animal() { }
Animal.prototype.eat = function() {
  console.log("nom nom nom");
};

You already know one way to create an instance of Animal using the new operator:

let animal = new Animal();

here’s an alternative approach:

let animal = Object.create(Animal.prototype);

you can not use:

because Object.create(obj) creates a new object, and sets obj as the new object’s prototype .
the prototype is like the “recipe” for creating an object. By setting the prototype of animal to be Animal's prototype , you are effectively giving the animal instance the same “recipe” as any other instance of Animal:

animal.eat(); // prints "nom nom nom"