0

I need an if statement, where the condition depends on a try-catch succeeding. Defining a new function just to call it once is wasted space, and I'd much rather figure out a one-liner.

I can't use if (try{return true;}catch{return false;}) as it results in a SyntaxError. So take "return false" as a 'failed try-catch attempt'.

This is as short as I could make it where it still works.

// [WORKING] False as expected
if ((() => {return false})()){
    console.log("Condition is true");   
}
else{console.log("Condition is false");}

This makes sense to me, but I don't think it's the most "official" way of doing this. Is this way a good solution? Is there a better way?

Reason this makes sense to me is because I'm checking if the variable exists, is of type number and is bigger than 0.

if ((() => {try{return price > 0}catch{return false}})())

TechNobo
  • 13
  • 1
  • 7
  • 5
    Why? Why not just perform the contents of the function? I'm not understanding the need to construct the function **at the point** of `if` execution. – Taplar Feb 04 '20 at 21:27
  • 2
    (1) functions are *truthy*. (2) you have an implicit global variable in your second version. (3) this is an xy problem. What are you actually trying to do? – Jonas Wilms Feb 04 '20 at 21:28
  • I can't just use "if (try{return true;}catch{return false;})" as it returns uncaught SyntaxError: Unexpected token 'try'. – TechNobo Feb 04 '20 at 21:29
  • 3
    `if ( (function(){ return true; }()) )` will work. It just doesn't make sense to actually do it. – Taplar Feb 04 '20 at 21:29
  • Then put that logic in a function definition **before** you try to do the if, and call the function for the if. The confusing part here is you're trying to combine the function construction and execution **inside the if statement** – Taplar Feb 04 '20 at 21:30
  • The function is only going to be called once in this single if-statement, so I'd just rather do it inline. – TechNobo Feb 04 '20 at 21:32
  • You're checking the truthiness of an arrow function handle. You're trying to evaluate the truthiness of what that function handle resolves to. In order to figure out what that function handle resolves to, you have to call it. Taplar's comment is trying to demonstrate how to call it. You have to wrap it in parentheses and then append parentheses to that. i.e. `( ... )()`. That's how Taplar gets `((function(){ return true; })())` (although I think that comment has a typo). – Joseph Marikle Feb 04 '20 at 21:38
  • The last code block of my question has it in parentheses already and works as expected... It just doesn't feel like the best way of doing this. It should be fine, but I don't know if it's production-ready. Is there a better way of accomplishing this? – TechNobo Feb 04 '20 at 21:41
  • 3
    An IIFE would be, in general, a reasonable way to do something this short and contrived. There are very few occasions in which this would make any sense--create your function elsewhere and make it actually possible to reason about the code. This still smells of an XY problem because as presented it makes no sense. – Dave Newton Feb 04 '20 at 21:41
  • Yes, you can use an IIFE for this. But please assign its result to a well-named `const` and then test for that in the condition, instead of writing the IIFE inside the `if` statement. – Bergi Feb 04 '20 at 21:50
  • 1
    Make your JS readable you will thank yourself later... – Daniel Tate Feb 04 '20 at 22:05
  • Code is write one time, read many times. Write it clearly, for the sake of everyone who follows. Resist the temptation to force non-trivial code into a single line. Be a professional. – jarmod Feb 04 '20 at 22:07

1 Answers1

2

The problem with if (try {return true;} catch {return false;}) is that you're trying to use return outside a function; it makes no sense there.

As all the comments pointed out, you can do what your second block suggests, and that's probably the only reasonable way to get this behavior. But, again as the comments note, this makes very little sense. If it's small enough to fit in a one-liner inside a typical if-condition, then it's probably just a single expression, in which case you might as well just use that expression as your condition.

That is, instead of

if ((() => doSomething('with', 'my data'))()) {
  //...
} else 
  // ...
}

you might as well just write

if (doSomething('with', 'my data')) {
  // ...
} else 
  // ...
}

If it's not a single expression, then it makes much more sense to place it in a named function and call it in your if-condition.

This imposes no additional penalty. That function, whether in your condition or just outside it, is going to take the same amount of memory; it will be eligible for garbage collection when the current scope ends. (I guess the one inside the condition might be eligible sooner; but I wouldn't count on it; it's certainly not enough to be worth adding complexity to code.)

In other words, this:

const myFunc = (some, args) => {
  const step1 = doSomething('with' args);
  const step2 = doAnotherThing('with', step1, 'and', some, args);
  return doAThirdThing('with', step2)
}

if (myFunc('my', 'data')) {
  //...
} else {
  // ...
}

is cleaner and much more readable than

if (((some, args) => {
  const step1 = doSomething('with' args);
  const step2 = doAnotherThing('with', step1, 'and', some, args);
  return doAThirdThing('with', step2)
})('my', 'data')) {
  //...
} else {
  // ...
}

You will thank yourself later for not doing the latter, I promise you.

Scott Sauyet
  • 49,207
  • 4
  • 49
  • 103