Short Circuiting

  • 3 properties of the && and || operators:
    1. they can use any data type
    2. they can return any data type (=> they are not only for booleans)
    3. short-circuit evaluation

||

  • if the first operand is truthy then the expression it true, so the first operand will be returned and the second operand will not even be evaluated --- meaning it is skipped/not looked at => the evaluation is short circuited
  • if the first operand is falsy then the second operand will be evaluated and returned as the default value
console.log(3 || 'Jonas')         //  3
console.log('' || 'Jonas')        // Jonas
console.log(true || 0)            // true
console.log(undefined || null)    // null

Generalized

  • not just for 2 operands
  • the first truthy operand will be returned --- any following operands will be short circuited
console.log(undefined || 0 || '' || 'Hello' || 23 || null)    // Hello

Using in Place of Ternary

const restaurant = {
  name: 'Classico Italiano',
  location: 'Via Angelo Tavanti 23, Firenze, Italy',
  categories: ['Italian', 'Pizzeria', 'Vegetarian', 'Organic'],
  starterMenu: ['Focaccia', 'Bruschetta', 'Garlic Bread', 'Caprese Salad'],
  mainMenu: ['Pizza', 'Pasta', 'Risotto'],
  operatingHours: {
    thu: {
      open: 12,
      close: 22,
    },
    fri: {
      open:11,
      close: 23,
    },
    sat: {
      open: 0,  // open 24 hours
      close:24
    },
  },
  order: function(starterIndex, mainIndex) {
    return [this.starterMenu[starterIndex], this.mainMenu[mainIndex]]
  },
  orderDelivery: function ({
                             starterIndex = 1,
                             mainIndex = 0,
                             time = '20:00',
                             address,
                           }) {
    console.log(`Order recieved! ${this.starterMenu[starterIndex]}  and ${this.mainMenu[mainIndex]} will be delivers to ${address} at ${time}`)
  },
  orderPasta: function (ing1, ing2, ing3) {
    console.log(`Here is your delicious pasta with ${ing1}, ${ing2}, and ${ing3}.`)
  },
  orderPizza: function (mainIngredient, ...additionalIngredients) {
    // just going to log them here, but really you'd do something with the ingredients
    console.log(mainIngredient)
    console.log(additionalIngredients)
  },
}
  • using ternary:
    const guests = restaurant.numGuests ? restaurant.numGuests : 10
    console.log(guests)    // 10
    • numGuests doesn't exist so it is undefined, which is falsy, so 10 is returned
    • if we set the numGuests property then that number will be returned
    restaurant.numGuests = 23
    const guests = restaurant.numGuests ? restaurant.numGuests : 10
    console.log(guests)    // 23
  • using short circuiting:
    const guests = restaurant.numGuests || 10
    console.log(guests)      // 10
    restaurant.numGuests = 23
    const guests = restaurant.numGuests || 10
    console.log(guests)      // 23
  • NOTE: neither of the 2 solutions just shown (ternary or short circuiting) will work if restaurant.numGuests = 0 --- 0 is a falsy value so they will both return 10 so make sure to be sure to account for this in real use cases

&&

  • works the opposite of the || operator
  • it short circuits at the first value is falsy and returns that operand without evaluating any following it
console.log(0 && 'Jonas')   // 0
console.log(7 && 'Jonas')   // Jonas
console.log('Hello' && 23 && null && 'Jonas')   // null

Using in Place of If Statement

  • using if statement:
    if (restaurant.orderPizza) {
      restaurant.orderPizza('mushrooms', 'spinach')   // mushrooms
                                                      // ▶ ["spinach']
    }
    • i.e. if the function exists then we call it
  • using short circuiting:
    restuarant.orderPizza && restuarant.orderPizza('mushrooms', 'spinach')
    • if the function doesn't exist it short circuits --- if it does exist then it evaluates the next operand which calls the function

NOTE: just because you can, doesn't mean you should replace an if or ternary with && or || --- they can often make code more confusing, so use with thoughtfulness

Copyright © 2022