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

Javascript code, what's wrong with that?

<button id="next">Next</button>
<button id="before">Before</button>
<script>
function myList()
{
    this.count = 1;
    this.showNumber = function() {alert(this.count);}
}
var listit = new myList();
    document.getElementById("next").onclick = listit.showNumber
</script>

Getting undefined why is that?, it needs to show the number lol, I want it to be prototype, don't get mistaken

3 Answers

Here is the method I used to solve this problem. What was happening was that the this keyword was referring to the function inside of the prototyped object. So, when showNumber was called, there is no count defined inside of that showNumber function so it is undefined.

To solve this behavior, I use the this keyword in a different way. First, I cache the reference to this by setting a variable named self equal to this in the outer function. And then, inside showNumber, instead of alerting this.count, I alert self.count which grabs the count from the object.

You can use this method to create multiple objects as I show you below:

//added num argument to myList so that you can specify the count
function myList(num) {
    //cache reference to this so that it belongs to the object itself
    var self = this;
   //make count equal to num
    this.count = num;
    this.showNumber = function() {
     //show the count from the object prototyped
      alert(self.count);
    }
}
//made an extra object here and an extra click handler to show what you can do
//notice I'm passing in different values as well
var listit = new myList(2);
var listit2 = new myList(1);
document.getElementById("next").onclick = listit.showNumber;
document.getElementById("before").onclick = listit2.showNumber;

Great answer Marcus, here is another piece of code which actually does the same problem? , the self keyword in javascript reffers to the object itself and not a static method like all other oop languages? Here is the code: function Person(age,name,lastname) { this.age = age; this.name = name; this.lastname = lastname this.showDetails = function() { if(this.age == "") { throw "Empty age"; } if(this.age < 3) { throw "Too small"; } if(this.age == 10) { throw "Not good"; } } } var mike = new Person(2,"mike","sb"); try { mike.showDetails(); } catch(err){ alert(err.message); }

Asaf, self isn't a reserved keyword in JavaScript in the browser. It was just a variable I made up to signify that the variable was a reference to itself. Also, that piece of code alerts an undefined error message. It's the way the this keyword works; this in the outer function of Person works just fine and can attach those properties to an object it is called upon. But, when you use this inside another function (even if it is a nested function), this refers to that nested function, not the outer function. That might be a tad confusing, but once you get a handle on the this keyword, it's a powerful tool.

Thank you, Jeff!

So basically , i need to make a local variable which is like a global within the object so i can access it within methods inside object, am i right?

If you want to use methods like showNumber with more than one prototyped object and be able to modify those values from within the nested method then, yes, most certainly. It'll allow you to create as many prototyped objects as you wish and have all of them have the same functionality, which is awesomesauce.

Kinda weird lol, i had really hard time understanding it, Thank you Marcus

Think about it this way (no pun intended lol): the this keyword, when used in an event, almost always refers to the thing that called it. So, with that in mind, since showNumber was the function that called the event, this refers to showNumber and not myList. Like I said, it is a pretty tricky concept to wrap your head around but once you do, you'll be a JS monster! :)

Hugo Paz
Hugo Paz
15,622 Points

Hi Asaf,

To fix it you need to ensure that the call is made within the object context - "this", so you dont get an undefined message.

<script>
function myList()
{
    this.count = 1;
    this.showNumber = function() {alert(this.count);}
}
var listit = new myList();
document.getElementById("next").onclick = function(){listit.showNumber()};
</script>

by wrapping the object function within a anonymous function, you can preserve the object context, and the 'this' value will relate to that object

Hey hugo, can you explain me what extacly is happening? why do i need to cover it again with an annonymous function?

Hugo Paz
Hugo Paz
15,622 Points

Basically you are creating a new reference to that object while at the same time providing a closure.

A function defined in the closure 'remembers' the environment in which it was created which means that "this" is not lost so the context is preserved.

Hey Marcus, I am trying to prototype, but why extacly its alerting undefined?, I mean its defined. I think its something with javascript engine, que between functions