New object of Prototype not adding property in instantiated objects

Hi,

I’ve been learning the Object Oriented Programming section and just got heavily confused.

One of the lessons in that section says that we can add properties in all instantiated objects using “ConstructorName.prototype.NewProperty = desired value” but later, another lesson came in by saying that it would become tedious to continuously use that same code and then introduced a new code:

ConstructorName.prototype = {
NewProperty: desired value
}

If I understood it correct, they wanted to say that short way to add new properties is by declaring an object of prototype.

I followed both methods and did:

function Dog() {
this.name = “Tommy”;
}
Dog.prototype.newprop = “Value”;

let newObj = new Dog();
newObj.name // returns “Tommy”
newObj.newprop // returns “Value” THIS WORKED

but when I used this approach:

function Dog() {
this.name = “Tommy”;
}
Dog.prototype = {
newprop: “Value”
};
let newObj = new Dog();
newObj.name // returns “Tommy”
newObj.newprop // DOESN’T RETURN ANYTHING

I would be very thankful if any of you could explain what’s happening here.

Any help so I could move forward? Thanks a lot!

It does work, are you sure you didn’t just have a typo or something? Where are you running the code?

function Dog() {
  this.name = "Tommy"
}

Dog.prototype = {
  newProp: "Value"
}

let newObj = new Dog();

newObj.name;
"Tommy"

newObj.newProp;
"Value"

Boom! It worked. Thanks a lot. Must be a typo or something. I am using freeCodeCamp editor and console.log() to see the returning value.

Can you help some more? :slight_smile: I tried to run the following code and it is not running:

function Dog() {
  this.name = "Tommy"
}

Dog.prototype = {
  newProp: this.name + " Value",
  newValue: 50
};

let newObj = new Dog();

let ownProp = [];
let arr = [];

for (let prop in newObj) {
  if (newObj.hasOwnProperty(prop)) {
    ownProp.push(prop);
  } else {
    arr.push(prop);
  }
}

console.log(arr);
console.log(ownProp);
console.log(newObj.newProp);
console.log(newObj.newValue);

The problem is in this part:

Dog.prototype = {
newProp: this.name + " Value",
newValue: 50
};

“this” keyword is causing the issue. Without it, it is working fine but I want it to return the name property of the object being called, that’s why I used “this” keyword.

this inside the prototype object is not the Dog but the global (window in the browser).

If you run this in the browser console it should log out the this (you can’t call it after, it will be undefined)

function Dog() {
  this.name = "Tommy"
}

Dog.prototype = {
  logthis: console.log(this),
  newProp: this.name + " Value",
  newValue: 50
};

let newObj = new Dog();
VM5720:6 Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
{logthis: undefined, newProp: " Value", newValue: 50}

There is actuall a name property on the window object, if we use a diffrent property name you can see the output change (“undefined Value”).

function Dog() {
  this.name = "Tommy"
}

Dog.prototype = {
  logthis: console.log(this),
  newProp: this.notOnWindow + " Value",
  newValue: 50
};

let newObj = new Dog();
VM5792:6 Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
{logthis: undefined, newProp: "undefined Value", newValue: 50}
1 Like

But I don’t understand why freeCodeCamp used “this” keyword in prototype.

Now this code is not running which is actually from freeCodeCamp (I made a few additions though):

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

let newBird = new Bird("chirp");

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

console.log(newBird.numLegs); //not returning anything, don't know why. I had this issue that's why I thought prototype object is not adding property

This is the original link of challenge: https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/object-oriented-programming/change-the-prototype-to-a-new-object/

Same issue again, not adding properties to instantiated object for some reasons as console failed to return numLegs.

The prototype methods are on the object.

function Dog() {
  this.name = "Tommy"
}

Dog.prototype = {
  logthis: function () {
    console.log(this)
  },
};

const dog = new Dog()

dog.logthis()
Dog {name: "Tommy"}

For your example, you need to move the constructor call after the prototypes.

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

Bird.prototype = {
  numLegs: 2, 
  eat: function() {
    console.log("nom nom nom");
  },
  describe: function() {
    console.log("My name is " + this.name);
  }
};
let newBird = new Bird("chirp");
console.log(newBird.numLegs);
2
1 Like

Wow, thanks a lot. I didn’t try using that technique.

So the conclusion is that if we are individually accessing prototype, we can have it in ANY order because I tried this and it worked:

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

let newBird = new Bird("chirp");

Bird.prototype.describe = function () {
  console.log(this.name);
}

console.log(newBird.describe());

But using the new object on prototype, I had to take care of the order of lines.

In short, I need to take care of order when using prototype as a new object and no need to take care when individually accessing prototype. And as for “this” keyword, I can’t have it outside the function in property. Am I correct?

Well, the methods are on the object so when called the this context will be the object.

As for the order, I’m not really sure I know enough about JS OOP as to give you a good explanation. Or I need to think about it some more. I’m guessing it has to do with the prototype property being an object and also how the instance is created seems to matter (new vs Object.create).

Here are some examples, that may or may not be of any use. It is basically just me playing around in the browser.

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

var newBird = new Bird('test');

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

var newBird = Object.create(Bird);

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

newBird.prototype.eat()
nom nom nom
function Bird(name) {
  this.name = name; 
}

var newBird = new Bird('test');

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

Object.setPrototypeOf(newBird, Bird.prototype)
newBird.eat()
nom nom nom

Maybe someone more knowledgeable than me can give you a good explanation.