0

I have a function object in javascript called BlinkyTextBox Inside of that I have 2 Shape objects that act as scroll buttons. I need a something very simple to happen which is just increment or decrement a variable called scrollY.

I tried it with an anonymous inner function, but the function couldn't recognize the member variables. Now I tried it with a member function, but it doesn't work with that either...

Here are both samples of what I am talking about.

function BlinkyTextBox(textdata, font, w, h)
{


    this.scrollY = -50;


    this.scrollBarYTop = new Button();

    this.scrollBarYTop.callFunction = this.scrollUp;

    this.scrollBarYBottom = new Button();
    this.scrollBarYBottom.callFunction = function()
    {
          this.scrollY -= 10;
    }

}
BlinkyTextBox.prototype.scrollUp = function()
{
    this.scrollY += 10;
}
Matthew
  • 3,886
  • 7
  • 47
  • 84
  • 1
    `this` refers to something else inside the function `.callFunction`, have a look at using `.call()` or `.apply()` to pass the scope into the function you're calling https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call – haxxxton Dec 01 '16 at 04:10

1 Answers1

1

The problem here is that once you assign a function to another object the this inside that function will refer to the new object instead of the object the function came from.

For example:

var a = {
    message : 'Hello!',
    say : function () { return this.message }
}

var b = {
    message : 'Goodbye'
}

b.say = a.say;

console.log(a.say()); // Hello!
console.log(b.say()); // Goodbye

Notice that we didn't do anything to the function say(). We just assigned it to b and it now print's the message from b instead of a.

Now, let's look at your code:

this.scrollBarYBottom.callFunction = function()
{
      this.scrollY -= 10; // refers to scrollBarYBottom.scrollY
                          // not BlinkyTextBox.scrollY
}

Same thing happens to the other method:

this.scrollBarYTop.callFunction = this.scrollUp;
// the this inside scrollUp will now refer to scrollBarYTop

Traditionally, to fix this you'd use an alias for this:

var myself = this;
this.scrollBarYBottom.callFunction = function()
{
      myself.scrollY -= 10;
}

But with ES5 you can use the .bind() method:

this.scrollBarYBottom.callFunction = (function()
{
      this.scrollY -= 10;
}).bind(this);

and:

this.scrollBarYTop.callFunction = this.scrollUp.bind(this);

Refer to this answer for a more detailed explanation of this: How does the "this" keyword in Javascript act within an object literal?

Community
  • 1
  • 1
slebetman
  • 109,858
  • 19
  • 140
  • 171
  • When I do `this.scrollBarYTop.callFunction = this.scrollUp.bind(this);` I get an error that says `Cannot read property 'bind' of undefined – Matthew Dec 01 '16 at 04:32
  • The other way with the `myself` works great! Thank you! – Matthew Dec 01 '16 at 04:33