2

Is there a (maybe undocumented) placeholder like $.noop for the use in jQuery concatenations?

To use in something like the following:

$('selector')[true ? 'method' : '<function that does nothing>']().doSomething();

I've tried a lot and ended up with this:

$.fn.noop = function(){ return this; };

But maybe there's already such a function in the jQuery core?

yckart
  • 32,460
  • 9
  • 122
  • 129
  • @OlafDietsche Refers to window and not the selector. – yckart Jan 21 '13 at 11:51
  • what about `.filter("*")`? – John Dvorak Jan 21 '13 at 11:51
  • 1
    @yckart I don't think there is a function like that – Arun P Johny Jan 21 '13 at 11:52
  • @JanDvorak A possible way, however unusable if no paramter can be passed. – yckart Jan 21 '13 at 11:53
  • And when I think that I'd be the only one using that level of premature optimization.. Well, I didn't get to the point of creating a noop solely for that though, I'd go with a conditional. Declaring a noop that returns the jQuery object itself as you've done is most concise way for your use-case though as calling other methods that would have no effect would add an unnecessary overhead and wouldn't make much sense to others reading your code. – Fabrício Matté Jan 21 '13 at 11:55
  • I think there's a plugin for that. Check out the Iff jQuery plugin. – John Dvorak Jan 21 '13 at 11:58
  • @FabrícioMatté - it does create some overhead, but if it's not something you itend to use a lot, and nothing is passed to the function, something like `addClass` that does nothing when it's not passed a parameter does seem a lot simpler than creating a function that just returns `this`. – adeneo Jan 21 '13 at 11:58
  • 2
    @adeneo what is wrong with creating a function that does exactly what you want? I find it much more semantic than as you've said, calling `addClass` to not add any class. Your call though. – Fabrício Matté Jan 21 '13 at 12:00
  • Stick with `$.fn.noop = function(){return this;}` – John Dvorak Jan 21 '13 at 12:01
  • @FabrícioMatté - nothing is wrong with creating a function, but I'm a bit lazy, and I'm the only one reading my code, and if it where just once, I would'nt bother, but that's just me. – adeneo Jan 21 '13 at 12:03
  • `$.fn.noop = Array.prototype.slice` – John Dvorak Jan 21 '13 at 12:03
  • @adeneo Yes, that's how I often write my code, but I don't recommend it to others for reasons. `:P` – Fabrício Matté Jan 21 '13 at 12:04
  • `$.fn.noop = $.fn.slice` (undocumented!) – John Dvorak Jan 21 '13 at 12:04
  • I think you can use [`addBack`](http://api.jquery.com/addBack/), though that's not really the intended use ;) – Yoshi Jan 21 '13 at 12:05
  • @JanDvorak - That's just a method that is exactly the same as `slice()` so it probably works, but why not just use `slice()` instead ? – adeneo Jan 21 '13 at 12:06
  • @adeneo is the empty `Array.prototype.slice()` documented? I'm afraid it's not. – John Dvorak Jan 21 '13 at 12:07
  • 1
    the `$.fn.slice` method requires at least a starting index, otherwise it will just return `this`, so without params it should work. – adeneo Jan 21 '13 at 12:12
  • @Yoshi `addBack` isn't an option in this way. Since it can't read the property `ownerDocument` of `null`. – yckart Jan 21 '13 at 12:12
  • @janDvorak Are there any dis/advantages by using `slice()` in place of `return this`? (except for the fact, that `return this` is faster) – yckart Jan 21 '13 at 12:14
  • @adeneo I still don't recommend its use in production code. – John Dvorak Jan 21 '13 at 12:14
  • @yckart it's undocumented, so it could change anytime. Also, it's unreadable. Also, it requires there be no arguments. – John Dvorak Jan 21 '13 at 12:15

1 Answers1

1

Option one:

Use $.fn.splice. It's there and it's always present, but it's also undocumented (so it may not be present in the future), unreadable, and requires there be no arguments.

Option two:

$.fn.noop = function(){return this}. Reliable, readable, predictable, fast. About the only reason to prefer #1 is development time.

Option three (preferred): Use a plugin for conditionals, which are about the only reason to desire a chainable no-op, such as the Iff plugin by Ben Alman (or write your own).

Pro: turns

 ... [condition?'method':'noop']() ...

into:

 ... .iff(condition).method().end() ...

That is, it's more readable than #2, AND you're not restricted to one call. You can even traverse within iff or nest your conditionals as long as you properly unwind the stack.

Cons: it's a plugin, and you'll need to fetch it; it requires the methods you call are no-ops when operating on the empty collection. All standard jQuery functions (except add) are.

John Dvorak
  • 26,799
  • 13
  • 69
  • 83