DEV Community

loading...
Cover image for Hidden power of || and &&

Hidden power of || and &&

Nikita Kozlov
Make things happen ✨ Webdev / websec / management / drawing
Updated on ・2 min read

TLDR: Logical operators actually return one of the operands, so you can refactor code using this feature.


Usually, you may see || and && logical operators in if cases.

if (case1 || case2) { 
  doSomething()
}
Enter fullscreen mode Exit fullscreen mode

So you may expect that || and && returns a boolean value, but it is only correct if values on both sides of these operators are boolean as well.

Actually, these operators return one of their arguments. E.g. if they were functions they would be implemented like this.

function or(a, b) {
  if (a) {
    return a
  }
  return b
}

function and(a, b) {
  if (a) {
    return b
  }
  return a
}
Enter fullscreen mode Exit fullscreen mode

It may sound and look a bit confusing, but let’s dive into examples.

let obj = { prop: 1 }

// boring part
true || false // -> true
false || true // -> true
true && false // -> false
false && true // -> false

// interesting part
obj || false // -> { prop: 1 }
false || obj  // -> { prop: 1 }

// more interesting part
true && obj // -> { prop: 1 }
obj && true // -> true 
true || obj  // -> true
obj || true // -> { prop: 1 }
Enter fullscreen mode Exit fullscreen mode

Ok, how do we use it?

Using the || operator you can set default values.

const title = props.customTitle || 'Default title'

// Same to

let title = 'Default title'
if (props.customTitle) {
  title = props.customTitle
}
Enter fullscreen mode Exit fullscreen mode

Using the && operator we can check for property presence in an object.

let name = response && response.data && response.data.name

// Same to

let name;
if (response) {
  if (response.data) {
    if (response.data.name) {
      name = response.data.name
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

So if response or response.data is undefined or null this assignment won’t throw any error.

Combining || and && we can get a nice construction, which checks for properties and can set a default value.

let name = response && response.data && response.data.name || 'UNKNOWN'
Enter fullscreen mode Exit fullscreen mode

Btw in newer versions of TypeScript, you can use a nullish coalescing, which simplifies && chains even more.

let name = response?.data?.name || 'UNKOWN'
Enter fullscreen mode Exit fullscreen mode

UPD: Needed to mention this can be confused with lazy evaluation, but actually it is short-circuit evaluation. Thanks to my friend Ray

UPD2: as @lukeshiru mentioned in the comments, it is better to use nullish coalescing instead of && and ||.

It's because values like 0 are treated like falsy, which can introduce bugs.

let beginnerCarDriver = {
  // ...
  yearsOfExperience: 0
}
let getDriveExperience = (driver) => 
  driver && driver.yearsOfExperience || "Not a driver"
console.log(getDriveExperience(beginnerCarDriver)) // Not a driver

let getDriveExperience1 = (driver) =>
  driver?.yearsOfExperience ?? "Not a driver"
console.log(getDriveExperience1(beginnerCarDriver)) // 0
Enter fullscreen mode Exit fullscreen mode

References
MDN/||
MDN/&&

Previous posts


Btw, I will post more fun stuff here and on Twitter. Let's be friends 👋

Discussion (4)

Collapse
lukeshiru profile image
LUKE知る

I love short and clean code, but I can't get behind short-circuiting, having solutions actually designed for this scenarios, like optional chaining (?.), nullish coalescing (??), and the good old ternary (condition ? ifTrue : ifFalse).
Also, short-circuiting can bite you quite easily due to falsy values like 0, "", and so on.
You mentioned this operators a little, buy your last example should be:

const name = response?.data?.name ?? "UNKOWN";
Enter fullscreen mode Exit fullscreen mode

And should be the preferred way. The code is still simple, but the result is more predictable.

Other than that, nice post covering this "loopholes" in JS logic!

Cheers!

Collapse
patarapolw profile image
Pacharapol Withayasakpunt

Elvis cuts out not only undefined, but also null.

Still, it is much safer than short circuiting.

Collapse
kozlovzxc profile image
Nikita Kozlov Author

Thanks! I've added a note to the post and mentioned you 🙏

Collapse
peterlunch profile image
Peter

Nice post, short circuit logic has the added benefit of also making your code a lot cleaner.