5. Control Flow, typeof, and Math

Follow along with code examples here!

Table of Contents

Slides

Overview

Key Terms

  • Comparison Operators - Operators that compare two values and return a boolean

  • Logical Operators - Operators used to combine conditions, such as && (AND), || (OR), and ! (NOT)

  • Type Coercion - The automatic conversion of a value from one data type to another

  • Guard Clause - A statement used to check if the remaining lines of code should be executed or not

  • Scope - Scope is the current context of execution in which values and expressions are "visible" or can be referenced

Control Flow Review

  • Programs usually change their behavior based on inputs.

  • Conditions and Booleans help decide if something is true or false.

  • Use if/else, switch, or ternary operators to decide what to do in a given situation.

  • They do this with Comparison Operators and Logical Operators which return a Boolean.

if/else statements

  • 3 parts: if, else if, else.

  • Starts checking at the top and stops checking when it hits a match.

  • Only 1 block is executed, so be specific first and get more general.

Example:

const isItHot = (temp) => {
  if (temp > 75) {
    return "it is hot!"
  } else if (temp > 90) {
    return "it is too hot!"
  } else {
    return "it is NOT!"
  }
}
console.log(isItHot(80)); // Prints "it is hot"
console.log(isItHot(95)); // Prints "it is too hot"
console.log(isItHot(60)); // Prints "it is NOT"
  • Conditions in an if statement must evaluate to true or false.

Comparison Operators:

  • Comparison Operators compare two values of the same type.

Operator
Name
Example
Result

===

Equal To

'Hi' === 'Hi'

true

!==

Not Equal To

6 !== 7

true

!=

Loose Equal To

"6" == 6

true

!=

Loose Not Equal To

6 != "6"

false

>

Greater Than

10 > 1

true

<

Less Than

30 < 5

false

>=

Greater or Equal

5 >= 5

true

<=

Less or Equal

2 <= 2

true

Logical Operators:

  • Logical Operators compare the outcomes of two conditions and let you be more expressive

Operator
Name
Example
Result

&&

AND

5 > 3 && 2 > 3

false

5 > 3 && 4 > 3

true

||

OR

5 > 3 || 2 > 3

true

!

NOT

!(5 > 3)

false

  • We can use () to group together each condition

const isItHot = (temp, isRaining) => {
  // if it is at least 90 or it is over 75 and isn't raining, its hot
  if (temp >= 90 || (temp > 75 && !isRaining)) {
    return "it is hot!"
  } else {
    return "it is NOT!"
  }
}
console.log(isItHot(90, true)); // Prints "it is hot"
console.log(isItHot(90, false)); // Prints "it is hot"
console.log(isItHot(80, false)); // Prints "it is hot"
console.log(isItHot(80, true)); // Prints "it is NOT"
console.log(isItHot(60, false)); // Prints "it is NOT"

Coercions and Truthiness

  • Type Coercion ("co-er-shun") — JavaScript will automatically convert (coerce) types when necessary. For example, '1' + 1 results in '11'.

  • Truthy/Falsy Values — any expression you use for an if statement's (condition) will be coerced into a Boolean.

    • "Falsy" values are coerced to be false and only these 5 values will behave this way: 0, "", null, undefined, and NaN

    • All other values are truthy

const isTruthy = (value) => {
  if (value) { // the value will be coerced to be a Boolean. If it is true, we will return true.
    return true;
  }
  else { // if not, we will return false.
    return false;
  }
}

console.log(isTruthy('')) // Prints false
console.log(isTruthy(0)) // Prints false
console.log(isTruthy(NaN)) // Prints false
console.log(isTruthy(null)) // Prints false
console.log(isTruthy(undefined)) // Prints false
console.log(isTruthy('hello')) // Prints true
console.log(isTruthy(' ')) // Prints true
console.log(isTruthy(5)) // Prints true
console.log(isTruthy([])) // Prints true
console.log(isTruthy({})) // Prints true

Simplify Your Logic

Guard Clauses and Ternary Operators

  • Code should be readable.

  • Avoid deeply nested if/else statements. Use guard clauses and ternary operators.

  • A guard clause is an if statement that returns before subsequent has a chance to be executed.

// Okay - if and else statements that each return something
const isTruthy = (value) => {
  if (value) {
    return true;
  }
  else {
    return false;
  }
}

// Better - Guard clause lets us skip the else statement by exiting early
const isTruthy = (role) => {
  if (value) {
    return true;
  }
  // if the guard clause above doesn't run, this line will!
  return false;
};
  • if and else statements let you choose between one of two code blocks to execute.

  • The ternary operator condition ? valA : valB is used to choose between one of two values.

// Okay - Use an If statement to choose which code block to execute
const isThisEven = (num) => {
  let message;
  if (num % 2 === 0) {
    message = 'it is even!';
  } else {
    message = 'it is odd!';
  }
  console.log(message);
}

// Better - Use a ternary to choose which value to assign to message
const isThisEven = (num) => {
  const message = num % 2 === 0 ? "it is even!" : "it is odd!";
  console.log(message);
}

Scope and Variables

  • If you want to get variables out of blocks, you have to define them in a higher scope.

  • Values in a higher scope are visible to lower scopes.

Example:

const getBioBest = (age, first, last) => {
  let dynamicBio = `Wow, ${first} ${last} is already ${age} years old. Getting up there!`;
  if (age < 18) {
    dynamicBio = `${first} ${last} is only ${age} years old. Still a child!`;
  } else if (age < 50) {
    dynamicBio = `${first} ${last} is ${age} years old. Still young at heart!`;
  }
  console.log(dynamicBio);
};

typeof Operator

  • typeof value returns the type of a given value as a string. It’s an operator, not a function.

  • Example usages:

console.log(typeof "hi"); // Prints "string"
console.log(typeof 4); // Prints "number"
console.log(typeof NaN); // Prints "number"
console.log(typeof true); // Prints "boolean"
console.log(typeof undefined); // Prints "undefined"
console.log(typeof console.log); // Prints "function"
console.log(typeof {}); // Prints "object"
console.log(typeof null); // Prints "object"
console.log(typeof []); // Prints "object"

Identifying null, Arrays, and NaN

  • Unfortunately, typeof tells us that arrays are objects (they are) so we have to use Array.isArray() to check if something is an array.

  • It also tells us that null is an Object so we have to check that manually

  • It also tells us that NaN is a number, which it is, but to know if something is NaN, we can use the isNaN() function

const arr = [];
console.log(Array.isArray(arr)); // Prints true

const nullVal = null
console.log(nullVal === null); // Prints true

const badNumber = NaN
console.log(isNaN(badNumber)); // Prints true

Math Operations

  • Use basic math operators: +, -, /, *.

  • The power operator x ** y raises x to the power of y.

  • % returns the remainder after division.

console.log(5 % 2); // 1 (5 divided by 2 is 2 with a remainder of 1)
console.log(10 % 3); // 1 (10 divided by 3 is 3 with a remainder of 1)
console.log(15 % 5); // 0 (15 divided by 5 is 3 with no remainder)

The Math Object

  • In JavaScript Math is a globally available object with methods and properties for doing more complex math.

console.log(Math.round(2.5))    // Prints 3
console.log(Math.floor(2.99))   // Prints 2
console.log(Math.ceil(2.01))    // Prints 3
console.log(Math.random())      // Prints a random decimal from 0 to 1 (exclusive)
console.log(Math.PI)            // Prints 3.141592653589793
console.log(Math.sqrt(25));     // Prints 5
console.log(Math.abs(-25));     // Prints 25
console.log(Math.max(2, 5, 3))  // Prints 5
console.log(Math.min(2, 5, 3))  // Prints 2
  • Here is an example of a function that makes use of Math.random() to flip a coin

const flipCoin = () => {
  return Math.random() > 0.5 ? "Heads" : "Tails"
}

Last updated