andersch.dev

<2022-05-04 Wed>
[ web ]

JavaScript

JavaScript (JS), is an interpreted, weakly typed programming language, that grew to one of the core technologies of the World Wide Web, even though it did not exist as one of its original cornerstones.

JS has no support for (conventional) multithreading. Concurrency is instead achieved using Promises, async/await and callbacks, which are used for blocking tasks such as network requests, file I/O and timeouts.

For true parallelism, modern JS offers Web Workers (which operate in separate threads). They communicate with the main thread through message passing (instead of shared memory).

Package Manager

  • Examples: npm, yarn, bun
  • Keep track of dependencies in package.json
  • Differentiate between user and dev dependencies (npm install --save-dev pkg)
  • node_modules folder contains direct and indirect dependencies

Built-in functions

setTimeout(callback, delay)                     // schedule a function to run after a specified delay
clearTimeout(timerId)                           // clear a timer set with setTimeout.
setInterval(callbackFunction, interval)         // schedule a function to run repeatedly at specified intervals
clearInterval(intervalId)                       // clear a timer set with setInterval.

fetch(url, options = {})                        // perform an asynchronous HTTP request.
addEventListener(event, listener, options = {}) // attach an event listener to an HTML element.

Object.keys(obj)                                // return an array of an object's enumerable property names

Code Examples

Declaring a variable

Keywords for declaring a variable: var, const, let

var b = 1; // globally-scoped
function exampleVar() {
    var a = 0; // function-scoped (or globally-scoped)
    if (true) {
        var a = 1; // reassigns outer x because of hoisting
        var b = 3; // reassigns outer y (gets "hoisted" to the top of scope)
        c = 3;     // implicitly globally scoped
        let d = 7; // block-scoped
        console.log(a, b, c, d); // Output: 1, 3, 3, 7
    }
    console.log(a, b, c); // Output: 13, 3 (no access to z)
}

exampleVar()

Destructuring (Pulling member variables out of an object)

// defining an object literal
const person = {
        first_name: 'Max',
        last_name: 'Powers',
        age: 30,
        // embedded object
        address: {
                street: 'Main Street',
                city:   'London'
        }
}

// pull out first_name, age, city
const { first_name, age, address: { city } } = person

console.log(first_name) // outputs: Max

JS object <-> JSON string

  • Turn JS object into valid JSON string: JSON.stringify(person)
  • Turn JSON into JS object: JSON.parse(json)

for-each

for-each loop in JS:

  • for (let thing of things) { ... }
  • things.forEach(function(todo) { })

== vs ===

  • 10 == '10' equals true
  • === also matches datatypes

Promises, async, await

// Simulating an asynchronous task that resolves after a delay
function asyncTask() {
  // Promise is a built-in object that takes in an "executor function"
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve("Task completed!");
    }, 4000);
  });
}

// Using async/await to handle asynchronous code
async function runAsyncTask() {
  try {
    const promise = asyncTask(); // start the async task and keep track of the promise

    // do other stuff while the task is running
    console.log("Doing other stuff until the async task is done..");
    await new Promise(r => setTimeout(r, 1000));
    console.log(".");
    await new Promise(r => setTimeout(r, 1000));
    console.log("..");
    await new Promise(r => setTimeout(r, 1000));
    console.log("...");

    // wait for the async task to finish, now that we are done with everything else
    const result = await promise;
    console.log(result);
  } catch (error) {
    console.error(error);
  }
}
runAsyncTask();

fetch example

The fetch API is implemented using Javascript Promises.

async function testFetch()
{
    let response = {}
    let request  = fetch('https://google.com').then(data => { response = data; })
    console.log('Code execution continues while fetch request is in progress');
    console.log('.');
    console.log('..');
    console.log('...');
    await request
    console.log("Return status is: " + response.statusText)
}
testFetch()

Concurrency using callbacks

// Asynchronous function simulating I/O operation
function fetchData(callback) {
  setTimeout(() => {  // simulate fetching data from a database or external API
    const data = { id: 1, name: 'John' };
    callback(null, data);
  }, 1000);
}

// Callback function to handle the fetched data
function handleData(error, data) {
  if (error) {
    console.error('Error fetching data:', error);
  } else {
    console.log('Fetched data:', data);
  }
}

console.log('Start fetching data...');
fetchData(handleData); // Initiate the asynchronous operation and provide a callback function
console.log('Fetching data operation initiated.');