0

I'm reading a great article on this in JavaScript. The author says that the following code is bad:

Cart = {
  items: [1,4,2],
  onClick: function () {
    // Do something with this.items.
  }
}
$("#mybutton").click(Cart.onClick);

He says that the click event doesn't know about the Cart object when calling onClick, therefore this.items won't be the [1,4,2] array that I expect it to be.

The author goes on to say that this code creates a closure and fixes it but I don't understand how the following code fixes the problem.

$("#mybutton").click(function () { Cart.onClick() });

1) In what context (if not Cart) does this thing we're in if we use the first example.

2) Why does the second example fix the problem?

inthenameofmusik
  • 617
  • 1
  • 4
  • 16
  • 2
    @JonathanLonowski: Why not make that an answer? :) – Felix Kling May 01 '16 at 01:37
  • 1
    I recommend to read the following sources: https://github.com/getify/You-Dont-Know-JS/blob/master/this%20&%20object%20prototypes/ch1.md, https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this . When you understand `this`, you will understand the examples. – Felix Kling May 01 '16 at 01:39

2 Answers2

0

Some good detail about this is given in "How does the “this” keyword work?"

But, the important part is that the value of this is determined when and by how the function is invoked.


  1. By passing the method itself as an argument, accessing it from an object and invoking it become separate acts. This separation is how it loses track of the object it came from – Cart.

    The invocation is performed by jQuery. And, for event handlers, it determines the value of this to be the referenced element (matched by $("#mybutton"), in this case):

When jQuery calls a handler, the this keyword is a reference to the element where the event is being delivered; [..]

  1. Rather than passing the method itself, this provides an alternate, wrapping function for jQuery to invoke instead. Within that function's body, accessing the method and invoking it are combined in a single statement.

    Having them combined, the language itself determines the value of this as the (last) Object before the function – Cart.

Community
  • 1
  • 1
Jonathan Lonowski
  • 121,453
  • 34
  • 200
  • 199
0

this is always context of the function call. This is why $("#mybutton").click(Cart.onClick); sends mybutton object to the function as this. In the second example you call Cart.onClick() in its own context; this is Cart.

You can fix first example like this: $("#mybutton").click(Cart.onClick.bind(Cart)); to force context to Cart object.

If you try <button onclick="Cart.onClick()... then this is windows object.

I hope my explanation helps you.

Alex Kudryashev
  • 9,120
  • 3
  • 27
  • 36