Jaime
Jaime

Reputation: 1410

What JavaScript/JQuery syntax is this?

I have no idea how to search for this so I'm asking here.

I've inherited a project and no one that's here knows what this syntax trick is called.

There's a select drop down change event that will call a function if one or another specific value is selected from among the list.

$('#accordion select[name=x_range]').change(function(){
  $('#custom-time')[$(this).val() == 'custom' ? 'show' : 'hide']();
  $('#custom-time-to-now')[$(this).val() == 'custom_to_now' ? 'show' : 'hide']();
  updateTimeIntervalOptions();
}).triggerHandler('change');

In this the show or hide function is called on the #custom-time or #custom-time-to-now divs.

What is calling functions like this called?

EDIT:
I should have said that I understand ternary if/else, but not the $(selector)[function_name]() part.

Upvotes: 13

Views: 497

Answers (7)

vittore
vittore

Reputation: 17579

I would say that this is not a trick, but understanding of three features of javascript.

First, functions are first class objects, so you can assign them to variables etc

 var f = function () { ... }
 var b = [];
 b[1] = f; // assigning function to array element
 b[1]();   // calling function assigned to array element

Second, convenient ternary operator, which is effectively shorthand notation of combination of if and assignement:

 var a = (b >c ) ? b : c;

 // is the same as

 if (b > c ) {
     a = b;
 } else {
     a = c;
 }

And last but not least, is the fact that every object properties can be accessed as dictionary elements, ie

 a.b = 5
 a['b'] === 5 // true! 

So putting all this together you can have expression like this

$(selector)[condition?'show':'hide']();

Which is equal to

if (condition) {
   $(selector).show();
} else {
   $(selector).hide();
}

UPDATE: One note on this particular case. In most cases you don't need to do complicated stuff like that, as $().toggle() accepts boolean argument for toggling on and off, so

$(selector)[condition?'show':'hide']();

will work the same way as

$(selector).toggle(!!condition);

Note that I use !! in order to cast value to boolean, as toggle checks paramter using ===

Upvotes: 17

algi
algi

Reputation: 577

It's called "Array Notation". Look here: http://www.erichynds.com/jquery/accessing-jquery-methods-using-array-syntax/

Upvotes: 2

kevin628
kevin628

Reputation: 3526

What is calling functions like this called?

Poor coding practice.

It's a way to call the show() or hide() functions dynamically. It's bloody nasty lookin'.

Edit: apparently my answer is "controversial" to some people. Please let me clarify: if I can write if-else statements over a ternary operator-- especially for things like string comparisons-- I will definitely take clarity over shorter code.

It's not "bloody nasty lookin'" because of just ternary operators or just bracket access of methods. It's bloody nasty lookin' because the code took a shortcut over clarity, and took that shortcut when it was not needed.

Ternary operators are not bad. Bracket access is not bad. But they are volatile concepts that are easily abused.

Upvotes: 10

LetterEh
LetterEh

Reputation: 26696

Ternary operators set values to two or more options (can be nested).

Think of them like a switch or an if/else or an if/elseif/.../else operation, but only for setting ONE value.

So look at something like:

var name = X === Y ? "Bob" : "Doug";
sayHello(name);

It's a ternary condition which optionally sets the name, based on whether the condition is true or false.

In your jQuery, they're just skipping a step, by using bracket-notation with a ternary inside.

People[ (selected_person === "Bob") ? "Bob" : (selected_person === "Doug") ? "Doug" : "Jimmy" ].sayHi();

This will call sayHi() for People.Bob, People.Doug or People.Jimmy, based on the value of selected_person.

So it's a ternary condition used to select an object-property, nested inside of the bracket notation, rather than doing it in two steps:

 var person = // ternary from last step
 People[person].sayHi();

EDIT:

Based on your edit, it's bracket-notation.

MyObj = { myFunc : function () { doStuff(); } };

You can call myFunc in a few different ways.
Either by using dot-notation: var func = MyObj.myFunc; or through bracket-notation: var func = MyObj["myFunc"];
Either way, the value of func is now myFunc.

So what they're doing is setting a string to the name of the function that they want to call.

var string = "show";
MyObj[string] // = MyObj.show
MyObj[string]() // = MyObj.show()

In the case of your code, they're using ternary to determine the value of the string.

Upvotes: 3

Guffa
Guffa

Reputation: 700292

I don't think that this pattern has a specific name. There is a conditional operator that is used to select different method names, then the method is called dynamically using this string with the "bracket" or "array" syntax.

Upvotes: 0

jackwanders
jackwanders

Reputation: 16020

The author is using the ternary operator (? :) to call a member function of a jQuery object using array notation, el['show']() rather than el.show(). Broken down, it would look like:

var fnName;
if($(this).val() == 'custom') {
  fnName = 'show';
} else {
  fnName = 'hide';
}

$('#custom-time')[fnName]();  // an alternative to $('#custom-time').show() or .hide()

Upvotes: 2

Brandon
Brandon

Reputation: 69973

Apparently it's called Bracket Notation

Upvotes: 6

Related Questions