3

Given jQuery's philosophy of write less, do more, I'm always surprised when I see this:

$(this).prop('checked')

… instead of this:

this.checked

Looking at the latest jQuery source, prop() provides convenience for these two gotchas:

  1. $(elem).prop('for') is equivalent to elem.htmlFor.
  2. $(elem).prop('class') is equivalent to elem.className.

It also normalizes tabIndex to:

  • 0 for tabbable elements without a tab index.
  • -1 for non-tabbable elements.

prop() is certainly useful for setting properties for multiple elements at once, and for chaining properties on a single element.

But is there any advantage (other than idiomatic) to use prop() to set or retrieve a single property on a single element except when normalizing tabIndex – specifically when you have a reference to the element (such as this in a callback)?

Rick Hitchcock
  • 35,202
  • 5
  • 48
  • 79
  • 11
    No, there's no advantage. It's convenient when the *only* thing you've got is already a jQuery object, but making a new jQuery object just so that `.prop()` can be called is silly. – Pointy Apr 10 '15 at 13:54
  • You can chain jq methods by using .prop() – px5x2 Apr 10 '15 at 13:55
  • 2
    @px5x2 — Not when reading a value from it as per this example. – Quentin Apr 10 '15 at 13:57
  • Thanks, @Pointy. I know this risks being an "opinionated" question, but I often see code like `$(this).prop('checked')` from posters with high rep, so I wondered if I was missing something. – Rick Hitchcock Apr 10 '15 at 13:59
  • @Quentin y sure in this case prop would be terminating op. – px5x2 Apr 10 '15 at 13:59
  • 1
    I like this thread - not sure it requires an answer, but you illustrate one of the many reasons I only use 5% as much of the jQuery lib as I did 5 years ago. The vanilla approach even makes total sense with basic js types, e.g. the checked property on `document.querySelector('input[type=checkbox]')` will give me a boolean since it's finding a checkbox, but `document.querySelector('div')` will be undefined. – Josh from Qaribou Apr 10 '15 at 14:01
  • 1
    @RickHitchcock: Sometimes that form is used for consistency with the rest of the code, or to not confuse newbies, or simply wasn't edited when copying code from a question to an answer. Despite better knowledge. – Bergi Apr 10 '15 at 14:02
  • 1
    jQuery does some corrections for certain properties, e.g. `src` and `href` in IE, `tabIndex` , ... – t.niese Apr 10 '15 at 14:05
  • @t.niese, the only correction I see in the source code for `prop()` is for normalizing `tabIndex`. – Rick Hitchcock Apr 10 '15 at 14:06
  • @RickHitchcock —jQuery 2 dropped support for old-IE. Maybe those normalisations are in jQuery 1 and you are looking at 2? – Quentin Apr 10 '15 at 14:08
  • @Quentin, I see the same code in https://code.jquery.com/jquery-1.11.2.js. Search for "propFix:". – Rick Hitchcock Apr 10 '15 at 14:09
  • 1
    related: [`this.id` vs. `$(this).attr('id')`](http://stackoverflow.com/q/5597317/1048572) and [`this.href` vs `$(this).attr('href')`](http://stackoverflow.com/q/6977049/1048572) – Bergi Apr 10 '15 at 14:13
  • @t.niese, I consider `for` and `class` to be conveniences rather than normalizations. I don't see anything in the source that normalizes `selected`, `scrollTop`, or `scrollLeft` as far as the `prop()` method is concerned. – Rick Hitchcock Apr 10 '15 at 14:22
  • 1
    @RickHitchcock yes sorry should have taken more time to look at it. But anyway, the last point is still true. jQuery was started when there where many differences between the browsers. The idea ist to have an abstraction layer to run code in an _uncontrolled_ environment like a browser, that allows to fix bugs a central point. – t.niese Apr 10 '15 at 14:33

1 Answers1

7

.prop as a getter has no real advantage, in fact, it is less performant than directly accessing the property.

The real utility of .prop is when used as a setter.

If you read the DOC, there is 3 way of setting something with .prop.


.prop(prop, value)

The first way has no advantage for a single element(except maybe if there is compatibility issue).

In fact this.check = true; is the same as $(this).prop('checked', true), but faster.

If you have a set of element though, there is an advantage. You don't have to manually loop all elements, jQuery does it for you.


.prop({prop : value[, prop : value, ...]});

The second way is useful when you have multiple properties to change. Instead of listing every properties you want to change like that :

this.prop1=true;
this.prop2=true;
this.prop3=true;
this.prop4=true;

You can pass an object like that :

$(this).prop({
    prop1 : true,
    prop2 : true,
    prop3 : true,
    prop4 : true
});

.prop(prop, callback)

The third way is in my opinion my favorite one. Using a callback function allow you to set every element individually on a set of condition. The callback receive 2 arguments: the index and the old value.

A good example of the use of a function is to reverse the state of every checkbox:

$('checkbox').prop('checked', function(_, old){
    return !old;
});
Community
  • 1
  • 1
Karl-André Gagnon
  • 33,662
  • 5
  • 50
  • 75
  • 1
    `prop` as a getter has the advantage of working on every jQuery collection, especially empty and dynamically selected ones. Of course it's pointless on `$(this)` :-) – Bergi Apr 10 '15 at 14:15
  • @Bergi Ahah yeah, I didn't think it was a *real* advantage, but you're right. – Karl-André Gagnon Apr 10 '15 at 14:20
  • 1
    This seems definitive, and the `callback` method absolutely provides an advantage in some situations. Accepted, thanks. – Rick Hitchcock Apr 10 '15 at 14:24