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 Object-Oriented JavaScript (2015) Introduction to Methods Returning Values

When running dice.roll in jQuery event handler for button click, does the 'this' var in the dice.roll method = button?

I tried to accomplish what Andrew does in this video by taking a different route. I decided to add a script tag and link to the CDN for jQuery, then add an event listener for 'click' on the button. The function passed to the event handler is dice.roll. In dice.roll, I log the dice roll (randomNumber) to the conosole, but it logs 'NaN'. If I change 'this.sides' to 'dice.sides', it works. So I decided to try console.log(this) in the code and it logs the button element that triggered the function. Is there a way to circumvent this without hardcoding this.sides to dice.sides? Thanks in advance.

This code doesn't work (this = button, not dice):

var dice = {
  sides: 6,
  roll: function () {
  //var sides = 6;
  var randomNumber = Math.floor(Math.random() * this.sides) + 1;
  console.log(randomNumber);
  return randomNumber;
}
}

$('button').click(dice.roll);

and this code works fine:

var dice = {
  sides: 6,
  roll: function () {
  //var sides = 6;
  var randomNumber = Math.floor(Math.random() * dice.sides) + 1;
  console.log(randomNumber);
  console.log(this);
  return randomNumber;
}
}

$('button').click(dice.roll);

I'd like to try to see if there's a way to invoke dice roll in this file with the jquey listener on the button and also leave my dice.roll method more dynamic with 'this'.sides instead of 'dice'.sides.

2 Answers

Raphaël Seguin
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Raphaël Seguin
Full Stack JavaScript Techdegree Graduate 29,228 Points

the keyword "this" always refer to the object calling the function. So you'd use it in a constructor function to refer to the properties of the object you're instantiating. But in the case of a literal object, like the "dice" object you're creating, "this" refers to anything that calls the function. If you don't want to hard code the variable, use a constructor instead :

function Dice(sides) {
  this.sides = sides;
}

Dice.prototype.roll = function() {
  var randomNumber = Math.floor(Math.random() * this.sides) + 1;
  return randomNumber;
};

var dice = new Dice(6);
console.log(dice.roll());

Spectacular! Thanks for the great insight. I just got to Constructor Functions and Prototypes in the course so this makes perfect sense now.

Jeff Wong
Jeff Wong
10,166 Points

Hi egushi,

I think there are some issues with the code that you written with the jquery event listener, this line here:

$('button').click(dice.roll);

Since the argument for the click method is a callback function, I would do the following (using jquery):

let dice = {
  sides: 6,
  roll: function() {
    const randomNumber = Math.floor(Math.random() * this.sides) + 1;
    console.log(randomNumber);
    console.log(this);
    return randomNumber;
  }
}

function printNumber(number) {
  const $placeholder = $('#placeholder');
  $placeholder.html(number);
}

$('#button').click(function() {
  let result = dice.roll();
  printNumber(result);
});

In my console, number between 1 to 6 is logged and 'this' logged as the dice object. I would say that if you pass object method directly into the click event handler, the method became a function of the element object itself (the button in this case), thus 'this' will point to the button object.