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 trialLeon Segal
14,754 Pointsthat...or this? **Spoiler Alert** (Solution is discussed here)
Here is the solution
var Dice = function (sides) {
this.sides = sides
this.roll = function () {
var randomNumber = Math.floor(Math.random() * this.sides) + 1
return randomNumber
} // roll fn
} // Dice Constr fn
var dice = new Dice(6)
But - I thought* that nested functions did not have access to the outer functions 'this' or 'arguments', so a 'that' had to be declared, like so:
var Dice = function (sides) {
var that = this
this.sides = sides
this.roll = function () {
var randomNumber = Math.floor(Math.random() * that.sides) + 1 // that
return randomNumber
} // roll fn
} // Dice Constr fn
var dice = new Dice(6)
* I may be imagining this, as I am at an awkward phase of my progression where I have looked at a lot of things now, but mastered little! Have I just put in an unnecessary bit of code??
Leon Segal
14,754 PointsYes, I understand that an inner function can look 'up' or 'out' to see an outer function's properties (but not vice-versa), but the inner function cannot access the outer function's 'this', hence my confusion, because in my example, the inner function is accessing the outer functions 'this' with no problems.
3 Answers
Leon Segal
14,754 PointsRight, so the TL:DR is:
Constructors create a new object with 'this' bound to that object, so you can ignore the function in a constructor for nesting intents/purposes.
Thanks
Thomas Nilsen
14,957 PointsThis can be confusing:
Here is a tiny example that shows a case where 'this' points to the wrong thing, and what can be done about it:
var obj = {
prop: 'hello',
func: function() {
console.log(this.prop); //This works
function sayHello() {
console.log(this.prop); //In here - 'this' refers to the global object (ie. the window), and not our object.
}
sayHello(); //prints undefined
var sayHello2 = function() {
console.log(this.prop);
}.bind(this);
sayHello2(); //Since we used bind, this also works.
}
};
obj.func();
Leon Segal
14,754 PointsNo I totally get it - if a function is inside a function, it loses access to the outer function's 'this'...
...but that is exactly why I am confused, because if you look at my example, that is what is happening; Dice is a function and inside that function is an anonymous function stored in dice.roll.
Unless the answer is something to do with Constructor functions not being treated as functions per se maybe?
Thomas Nilsen
14,957 PointsYes - but you create a new instance using the new keyword. There is a couple of things that happens when you do.
This is taken from the mozilla-pages:
When the code new Foo(...) is executed, the following things happen:
A new object is created, inheriting from Foo.prototype.
The constructor function Foo is called with the specified arguments, and with this bound to the newly created object. new Foo is equivalent to new Foo(), i.e. if no argument list is specified, Foo is called without arguments.
The object returned by the constructor function becomes the result of the whole new expression. If the constructor function doesn't explicitly return an object, the object created in step 1 is used instead. (Normally constructors don't return a value, but they can choose to do so if they want to override the normal object creation process.)
Karolin Rafalski
11,368 PointsKarolin Rafalski
11,368 PointsInner functions can look 'up', outer functions cannot look 'down'.
In this case,
this
will work fine.There are times where you may want to pass a different
this
to a function, to which you can create a variable 'that' (like you have) or use .bind() https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind