JavaScript 7

Advanced JavaScript

JavaScript Type Coercion

true

false

+

1

What the heck is this?!

Topics for Today

Type Coercion

Hoisting

Event Loop

Promises

Async/Await

Try/Catch

Recursion

Memoization

Type Coercion

Type coercion is the process of converting a value from one datatype to another.

 

When we use ==, as opposed to ===, JavaScript attempts to coerce the types into the same datatype before evaluating the condition.

 

Coercion can occur with other operations.

Moral of the story? Use 3 equals instead of 2 unless you have a good reason not to.

JavaScript has internal rules for how datatypes are coerced:

https://dorey.github.io/JavaScript-Equality-Table/

Hoisting

Hoisting in computer terms refers to when variable declarations are "hoisted" to the top of the code file during the compiling phase.

 

In JavaScript, hoisting works a bit differently, because only variable declarations are hoisted, and not their initializations, or values.

 

Hoisting enables us to use variables before they are declared in our code, without breaking our program.

 

Event Loop

Promises

let myFirstPromise = new Promise((resolve, reject) => {
  // resolve(...) is called when what we were doing asynchronously was successful,
  // and reject(...) when it failed.
  // In this example, we use setTimeout(...) to simulate async code. 
  // In reality, you will probably be using something like XHR or an HTML5 API.
  setTimeout( function() {
    resolve({data: "success!"})// IRL, resolve fires when a non-error response is received. 
  }, 250) 
}) 

myFirstPromise.then((res) => {
  // res is whatever we passed in the resolve(...) function above.
  console.log("Great " + res.data) 
});

The Promise object represents the eventual completion (or failure) of an asynchronous operation, and its resulting value.

Promises have three possible states:

Pending, Fulfilled, or Rejected

Async/Await

function asyncTasks() {
  let a = asyncTaskA().then(res => res.data)
  let b = asyncTaskB().then(res => res.data)
  let c = asyncTaskC().then(res => res.data)
}
async function asyncTasks() {
  let a = await asyncTaskA()
  let b = await asyncTaskB()
  let c = await asyncTaskC()
}

Without async/await:

With async/await:

But what about error handling?

With .then( ) we have .catch( )

 

One potential problem with async/await is that it doesn't have built in error handling...

Try/Catch

async function asyncTasks() {
  try {
    let a = await asyncTaskA()
    let b = await asyncTaskB()
    let c = await asyncTaskC()
    let d = await asyncTaskD(c)
    }
  catch(err) {
    console.log(err)
  }
}
function asyncTasks() {
  let a = asyncTaskA().then(res => res.data)
  .catch(err => console.log(err))
  let b = asyncTaskB().then(res => res.data)
  .catch(err => console.log(err))
  let d = asyncTaskC().then(res => 
  asyncTaskD(res.data).then(res => res.data)
  .catch(err => console.log(err)))
  .catch(err => console.log(err))
}

Without async/await:

With async/await:

async function asyncTasks() {
  try {
    let a = await asyncTaskA()
    let b = await asyncTaskB()
    let c = await asyncTaskC()
    }
  catch(err) {
    console.log(err)
  }
  finally {
    console.log('do this thing')
  }
}

Optional — finally

Note: Try/Catch blocks are not just for asynchronous code. They can be used for any kind of error handling, and it is good practice to use them.

Recursion

function factorial(num) {
  if(num === 1) { return 1 };
  return num * factorial(num - 1);
}

The process in which a function calls itself directly or indirectly is called recursion

The above function enables us to calculate factorial values, by calling itself recursively.


Ex: 5! is 5 * 4 * 3 * 2 * 1

Memoization

Memoization is an optimization technique that is meant to increase a functions performance by caching its previously computed results.

function memoize(func) {
  var cache = {};
  return function() {
    var key = JSON.stringify(arguments);
    if(cache[key]) {
      return cache[key];
    }
    else {
      var val = func(...arguments);
      cache[key] = val;
      return val;
    }
  };
}

Continued on next slide...

Memoization

var factorial = memoize(function(num) {
  console.log('loading factorial(' + num + ')');
  if(num === 1) { return 1 };
  return num * factorial(num - 1);
});

// first call
console.log(factorial(3));
//=> loading factorial(3)
//=> loading factorial(2)
//=> loading factorial(1)
//=> 6

// successive calls
console.log(factorial(3)); //=> 6
console.log(factorial(3)); //=> 6

// short circuit higher factorial calls
console.log(factorial(4));
//=> loading factorial(4)
//=> 24

JavaScript 7

By matias_perez

JavaScript 7

Advanced JavaScript Topics

  • 397