1

Given following code:

const letters = ['a', 'b', 'c'];
foo = ((list, letter) => {
    if (list.includes(letter)) {
        return true;
    }
    return false;
})(letters, 'c') ? 'letter in list' : 'letter not in list';
console.log(foo);

Output will be:

letter in list

How does ternary operator work in this example? Does it call foo with letters and c as parameters? How does it know to call this function?

VLAZ
  • 26,331
  • 9
  • 49
  • 67
vex
  • 33
  • 5
  • `(letters, 'c')` is actually the function call. The result is than used with ternary comparison. – Brain Foo Long Jul 23 '21 at 18:46
  • 1
    The result of the IIFE will return a boolean which the ternary will switch on. – Mr. Polywhirl Jul 23 '21 at 18:47
  • 1
    This is an _immediately invoked function expression_ (IIFE). – Alnitak Jul 23 '21 at 18:47
  • 1
    "*Does it call foo with letters and c as parameters?*" No, it calls the function defined as `(list, letter)` with `letters` and `c` as parameters. It's [an IIFE]([What is the (function() { } )() construct in JavaScript?](https://stackoverflow.com/q/8228281)) – VLAZ Jul 23 '21 at 18:47
  • @NiettheDarkAbsol I agree it's bad code. However, it might just be there to showcase an IIFE without making it very complex. It *is* quite obtuse, though. – VLAZ Jul 23 '21 at 18:50
  • @VLAZ I couldn't understand how (list, letter) calls a function. IIFE made it clear. Thank you! – vex Jul 24 '21 at 10:05

1 Answers1

2

You can split up the expression in several parts, and look at them individually:

foo = (
    (
        // Create an arrow function
        (list, letter) => {
            if (list.includes(letter)) {
                return true;
            }
            return false;
        }
    )
    // call the function
    (letters, 'c')
) /* ternary operator on call result */ ? 'letter in list' : 'letter not in list';

If you're unsure, you can usually replace expressions with variables to make it more clear:

const func = (list, letter) => {
    if (list.includes(letter)) {
        return true;
    }
    return false;
};
const callResult = func(letters, 'c');
const foo = callResult ? 'letter in list' : 'letter not in list';

Most people would even say it should've used several variables anyway for readability.

Kelvin Schoofs
  • 8,323
  • 1
  • 12
  • 31
  • You can shorten `const func` by removing the condition and just returning `return list.includes(letter)` – B001ᛦ Jul 23 '21 at 19:06
  • 1
    @B001ᛦ I noticed. I focused on splitting the existing code though, instead of simplifying it. After all, you don't even need a function call here, if you don't count `.includes` that is. – Kelvin Schoofs Jul 23 '21 at 19:07
  • Well my motto is optimize the code when you touch it again ;) – B001ᛦ Jul 23 '21 at 19:12
  • @B001ᛦ my preference is when explaining code to modify it as little as possible, because it helps when figuring out what the differences are. It's easy to track similarities. Explaining how `list.includes("c") ? 'letter in list' : 'letter not in list'` is quite different to the original code and it makes very little sense as an explanation. The code here seems like it's deliberately written to be *simple* in order to highlight a specific feature, that being nested expressions / IIFE in a conditional operator. So, it seems like training code. – VLAZ Jul 23 '21 at 19:57