2

With this

example 1

$("#my_div").on("click", function () {
    alert( $(this).attr("id") )
});

we obtain correct result, but if I use this:

example 2

function thisId () {
    alert( $(this).attr("id") )
}

$("#my_div").on("click", function () {
    thisId();
});

Now the result is undefined. Please tell me how I should be using this, when the selector and function using this are written as different expressions, as in example 2?

Junuxx
  • 14,011
  • 5
  • 41
  • 71
Oto Shavadze
  • 40,603
  • 55
  • 152
  • 236

2 Answers2

8

For jQuery to pass the element reference to the function you must provide the function as a reference. Try this:

$("#my_div").on("click", thisId);

Update for @bot

function thisId (event) {
    alert( $(this).attr("id") )
    alert(event.type);
}

$("#my_div").on("click", thisId);
Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
  • Could you also give an example of passing in the event? – Bot Nov 08 '12 at 17:31
  • @Bot the event would be passed in the exact same way as you define your anonymous function. See my update for the example. – Rory McCrossan Nov 08 '12 at 17:33
  • Thanks, just trying to think ahead if anyone comes across this question and is looking for that specific answer. – Bot Nov 08 '12 at 17:34
2

@RoryMcCrossan's answer is the correct one, here's why: JS determines what this references ad hoc, that is: when the function is called, it looks at the call-context:

myObject.property = function(){console.log(this)}
myObject.property();
  /\          ||
  ||who called |
  |_____________

If the function wasn't called as a method of an obeject, like you did with thisId, JS -like it always does- falls back to the global object, and this will point to window.
You can determine the calling context programmatically, with functionName.call(context) and functionName.apply(context,[arguments]);, which is what jQuery does behind the scenes:

$.fn.on(evt,callback)//simplified
{//jQ sets up its own event handler that looks like this:
    //here, this point to $("#my_div") in your case, so:
    var jQhandler = function(e)
    {
        callback.apply(this,[e]);//passes the event as an argument
    };
    this.addEventListener(evt,jQhandler,false);//<-- passes its handler by reference
}

So you can do either this use apply, which -in your case- requires yet another anon. function object to be created, or pass the function directly to jQuery as being the callback. The latter being far more efficient: less verbose and less function objects required.

This is, in short, why @RoryMcCrossan is correct, and why some consider JS to be the worlds most misunderstood language: the bulk of ppl using it don't really know about how JS determines the context.


Just as a side-note: ECMA5 allows you to bind a function to a context, using the .bind method, but that would take us to far off-topic...

Elias Van Ootegem
  • 74,482
  • 9
  • 111
  • 149