Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

JavaScript Object-Oriented JavaScript (2015) Practice Project Quiz Prototype

faraz
PLUS
faraz
Courses Plus Student 21,474 Points

Why so much "this"?

Not sure why "this" is needed in the last block of code:

Quiz.prototype.hasEnded = function() {
  return this.currentQuestionIndex >= this.questions.length;
}

if we just need to check whether the currentQuestionIndex is greater than or equal to questions.length shouldn't it work without the "this"?

jrabello
jrabello
17,916 Points

"this" keyword tells javascript parser that you want to change the variable name from the CURRENT instance of the object, and this is VERY important, because when your code/project becomes bigger it will become to a point where you will look at the code and spend half an hour trying to understand what it does, and where modifications were made, so being sure that you change only the current instance from an object adds a HUGE semantic value and you know that an instance of this object was modified

faraz
faraz
Courses Plus Student 21,474 Points

@jrabello thanks for the response but I don't quite understand what you mean when you say that "this" tells the javascript parser to "change the variable name from the CURRENT instance of the object"? Do you mean it tells the parser to change the variable name TO the current instance of the object? Also what does it mean to "change the variable name" and why do we need to do that? Please clarify..! Thanks

1 Answer

Hey Faraz,

So I feel like to understand the nature of this, you need to understand what is happening when you use the new keyword to instantiate an object. Take the example below:

//Obviously, this is a constructor function named Person
function Person(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
}

//This creates a brand new object called "james"... that uses Person like a blueprint for building itself
//It's firstName property is "James" and its lastName property is "Cameron"
var james = new Person("James", "Cameron");

//This creates a brand new object called "dwayne"... that also uses Person like a blueprint for building itself
//It's firstName property is "Dwayne" and its lastName property is "Johnson"
var dwayne = new Person("Dwayne", "Johnson");

So normally, (like if you console.log(this) and look at the result) this will return the window object. But when you call Person() and prepend the keyword new before it, the keyword new does the following:

  1. it creates an empty object
  2. it changes the meaning of this so that it refers to the newly created object ... as opposed to the window object
  3. and then of course the constructor function is called... with its given parameters

So in your question:

Quiz.prototype.hasEnded = function() {
  return this.currentQuestionIndex >= this.questions.length;
}

this can't be replaced by anything else. Why? Because that hasEnded method has to be available, to every object, that will, eventually, be instantiated based on the Quiz constructor.

See in other languages (like Java and C++ et al.) they use something called classes as their "constructor functions"... and every new object is then derived/instantiated from a given class. JavaScript is different, in this sense, as it has no classes. Instead everything is an object. And every object inherits from another object. And if you want to create new objects... you use another object as your blueprint/class. The formal name for this behavior is Prototypal Inheritance.

Anyways, hope that clears some things up... and answered your question :)

faraz
faraz
Courses Plus Student 21,474 Points

Ah ok, so if I understand "this" correctly: it refers to the object that will be created using the constructor? So in my original question, each object created with the Quiz constructor will have a method called hasEnded which will return true or false depending on if the currentQuestionIndex >= questions.length?

Yup, you're correct... but with one caveat... one minor detail. It has to do with this concept of "prototypes," which basically means objects inheriting properties from other objects.

I really don't want to confuse you but, it's not so much that "each object created with the Quiz constructor will have a method called hasEnded..." as it is that "each object created with the Quiz constructor will have access to a method called hasEnded...".

This is the reason why you did this (using the prototype property):

Quiz.prototype.hasEnded = function() {
  return this.currentQuestionIndex >= this.questions.length;
}

instead of this (without using the prototype property):

Quiz.hasEnded = function() {
  return this.currentQuestionIndex >= this.questions.length;
}

What that last example (the one without the prototype property) is doing is making it so that every new object instantiated with that Quiz constructor contains the hasEnded method. This is inefficient ... imagine if you used that constructor to create 10,000 or 100,000 objects... each of those objects would have to contain that entire hasEnded method ... as well as execute it.

Whereas the first example (the one that used the prototype property) makes it so that the Quiz constructor function itself contains the hasEnded method. Where does it contain it? In its prototype property (all functions have this prototype property).

See, this way, if you created 1,000,000 objects from the Quiz constructor, all would have access to the method... but none would need to actually contain them as their own property. It's just more efficient and DRY (Don't Repeat Yourself).

I hope that didn't confuse you. I use the word contain for lack of a better word... and I'm pretty sure there's a better word.

faraz
faraz
Courses Plus Student 21,474 Points

Ok I think I got it now. Also makes sense that you wouldn't want the method to be recreated for each object if it can only exist once in the prototype and then all objects instantiated from that will have access to it. Efficient! -- Thanks!