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
asaf omri
Courses Plus Student 2,784 PointsJavascript 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
Marcus Parsons
15,719 PointsHere 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;
Hugo Paz
15,622 PointsHi 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
asaf omri
Courses Plus Student 2,784 PointsHey hugo, can you explain me what extacly is happening? why do i need to cover it again with an annonymous function?
Hugo Paz
15,622 PointsBasically 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.
asaf omri
Courses Plus Student 2,784 PointsHey 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
asaf omri
Courses Plus Student 2,784 Pointsasaf omri
Courses Plus Student 2,784 PointsGreat 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); }
Jeff Jacobson-Swartfager
15,419 PointsJeff Jacobson-Swartfager
15,419 PointsGreat answer, Marcus!
Marcus Parsons
15,719 PointsMarcus Parsons
15,719 PointsAsaf, 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
thiskeyword works;thisin the outer function ofPersonworks just fine and can attach those properties to an object it is called upon. But, when you usethisinside another function (even if it is a nested function),thisrefers to that nested function, not the outer function. That might be a tad confusing, but once you get a handle on thethiskeyword, it's a powerful tool.Thank you, Jeff!
asaf omri
Courses Plus Student 2,784 Pointsasaf omri
Courses Plus Student 2,784 PointsSo 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?
Marcus Parsons
15,719 PointsMarcus Parsons
15,719 PointsIf you want to use methods like
showNumberwith 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.asaf omri
Courses Plus Student 2,784 Pointsasaf omri
Courses Plus Student 2,784 PointsKinda weird lol, i had really hard time understanding it, Thank you Marcus
Marcus Parsons
15,719 PointsMarcus Parsons
15,719 PointsThink about it
thisway (no pun intended lol): thethiskeyword, when used in an event, almost always refers to the thing that called it. So, with that in mind, sinceshowNumberwas the function that called the event,thisrefers toshowNumberand notmyList. Like I said, it is a pretty tricky concept to wrap your head around but once you do, you'll be a JS monster! :)