lizlux
lizlux

Reputation: 636

jQuery $(this) vs. variable

Given:

var element = $('#element');

I'm wondering which is faster:

element.click(function(){
    element.dosomething()
)}

Or:

element.click(function(){
    $(this).dosomething()
)}

Or does it matter?

Upvotes: 11

Views: 7253

Answers (7)

Meligy
Meligy

Reputation: 36594

Use element.

If element was a jQuery collection matching a single element, for example, $(someId), then just use it.

If the selector was meant to match more than one element, then element is actually elements, a collection of elements, so, in that case you use $(this) inside your click handler to catch the one actually clicked.

The difference is explained int he following examples:

1- Handler on single element

var table = $("#myTable");
table.click(function() {
    // Same as $(this), except $(this) creates another
    //  wrapper on the same object (which isn't too expensive anyway)
    table.doSomething();
});

2- Handler on multiple elements

var rows = $("#myTable > tbody > tr");
rows.click(function() {
    // Here we have to use $(this) to affect ONLY the clicked row
    $(this).doSomething();
});

3- Handler on single element, but called for multiple child elements

var table = $("#myTable");
// "on" and "live" call handler for only child elements matching selector
// (Even child elements that didn't exist when we added the handler, 
     as long as parent -table in this case- exists)
table.on("click", "tbody > tr", function() {
    // Here we have to use $(this) to affect ONLY the clicked row
    $(this).doSomething();
});

I find it assuring (and less work, a very tiny difference though) to just the existing wrapper, showing that I'm expecting a single element in this case and I'm just working with it. And use $(this) when I'm dealing with elements of a collection of matching elements.

Upvotes: 4

McHerbie
McHerbie

Reputation: 2995

This would be faster:

element.click(function(){
    element.dosomething();
)}

This would be fastest:

element.bind('click', element.dosomething);
  1. element is cached (and not changed, i assume)
  2. use bind('click') directly don't use .click() wrapper
  3. if element.dosomething is the function you want to call, pass it directly without extra call

I am assuming that element.dosomething() is correct and also element doesn't change.

Here is an example of working code: http://jsfiddle.net/xhS3b/

//<a href="#" id="element">click me</a>

var element = $('#element');
element.dosomething = function () {
    alert('did something');   
    return false;
}
element.bind('click', element.dosomething);

Upvotes: 0

Cu7l4ss
Cu7l4ss

Reputation: 566

Well jQuery has it's unique cache of dom elements(that already been touched once by jquery) so actually in most cases this won't make a real difference.

I do not really believe this is your case though, jquery will actually wrap the this which is the element, so you are not really running a query of any kind twice.

BTW, in some cases this does make a difference(when delegating for instance).

Upvotes: 1

Jamie Treworgy
Jamie Treworgy

Reputation: 24334

The first is faster. The second runs the same selector twice. That said, you will only use that code once using the first method, it's probably not what you want most of the time.

In practice, use a pattern like:

$('stuff').click(function(){
    var $$ = $(this); 
    $$.dosomething();
    $$.dosomethingelse();
)}

That is, unless you only use a selector once, assign it to a variable first.

Upvotes: 1

Decko
Decko

Reputation: 19385

As $(this) causes a function call, your first example is theoretically faster, but probably not by much.

Upvotes: 0

Marco
Marco

Reputation: 1346

I would prefer the second. If you ever wanted to refactor the function and reuse it for another button it would be more portable.

Upvotes: 0

Daniel Ahrnsbrak
Daniel Ahrnsbrak

Reputation: 1077

The speed would probably be the same, but using $(this) is much better because you don't have to worry about element being reassigned to something else (or the value of element being lost entirely).

Also, if you refactor and use a selector for a class instead of a specific element, the function will work for all matched elements, not just the one.

Upvotes: 2

Related Questions