JavaScript Knowledge

Kip Landergren

(Updated: )

Contents

Overview

JavaScript is a dynamic, weakly-typed programming language with prototypical inheritance and first class function support. It conforms to the specification document “Standard ECMA-262”, which is written and maintained by Technical Committee 39 (TC39).

ECMAScript standards are referred to either by their “edition” or year, with “ECMAScript 2015” (also known as “ECMAScript 6th Edition” or just “ES6”) being the most recent JavaScript standard to contain major language changes. These changes included modules, classes, promises, and others.

Engines for executing JavaScript include:

It is important to note that JavaScript the language is separate from browser APIs (DOM, Canvas, WebRTC, etc).

Core Idea

Create a scripting language for the web.

Key Concepts

Prototypical Inheritance

An object’s [[Prototype]] is a property pointing to the object it inherits from. This forms a chain up to Object whose [[Prototype]] property points to null.

The chain is important for property access: when a property is not found on an object, the next object in the prototype chain is searched, repeating until the property is found or null is reached.

prototypical inheritance in JavaScript

Equality

Three options:

The MDN Equality comparisons and sameness article goes over this in depth.

Modules

Modules are files containing JavaScript code with the constraints:

Note: there is no Module keyword.

// ModuleA.js
export const greeting = "hello world";
export default {
  foo: "bar",
};
// ModuleB.js
import greeting from "./ModuleA.js"
console.log(greeting);
// ModuleC.js
import { default as lookup } from "./ModuleA.js"
console.log(lookup.foo); // "bar"
// ModuleD.js
import * as ModA from "./ModuleA.js"
console.log(ModA.greeting); // "hello world"

Event Loop

JavaScript engines are comprised of major components:

The JavaScript event loop:

Promises

A JavaScript Promise represents the execution of a JavaScript function object. This function object, called the Promise’s executor, is invoked with two arguments:

The executor’s return value is ignored and the function is expected to work via side effects from resolve and reject alone.

{ const rand = Math.floor(Math.random() * 10); if (rand < 5) { resolve(rand); } else { reject(\`$\{rand} is greater than 4!\`); } return "this return does nothing" });

p0.then((value) => { console.log(\`p0 fulfilled via $\{value}\`); }).catch((error) => { console.log(\`p0 rejected because: $\{error}\`); });`} /> The state of a Promise is determined by the execution of the executor and its respective calls to resolve or reject. It may be one of the following mutually exclusive states:

A Promise is considered “settled” when in either state:

A Promise is “resolved” when:

Additionally, I find it confusing that the resolve function is so named but the definition of “resolved” includes being in the state “rejected”. This I believe is due to the special case mentioned above of a Promise resolving to another Promise.

A Promise does not imply that the operation will be performed asynchronously. You cannot take a sychronous operation, wrap it in a Promise, and expect it to be executed concurrently. The wrapped operation will be executed synchronously unless and until properly invoked async marked functions containing await are used on asynchronous APIs. At that point execution will be suspended and the event loop is able to process the next task.

JavaScript Promise Terminology

executor
the function object wrapped by the Promise
fulfilled
the state of a Promise when a result value is available
pending
the state of a Promise when not “fulfilled” or “rejected”
rejected
the state of a Promise when a result value is not available but a reason (typically an Error) for rejection is available
resolved
a Promise that is either “settled” or has been “locked in” to match the state of another Promise
settled
a Promise that is either “fulfilled” or “rejected”

Async / Await

The async keyword is placed in front of function definition to indicate, and ensure, that the function returns a Promise. If the function definition does not return a Promise, async will wrap the result in one.

The await keyword, which can only be used inside async functions, will pause the execution of its successive expression if, at some depth, an asynchronous API like those for IO or timers is called. Execution will resume when the asynchronous API call completes.

Note: await does not imply that execution of the successive expression will be done asynchronously, even if that expression is a Promise.

Understanding Automatic Semi-Colon Insertion

Use parentheses to control. Example:

function foo(args) {
  return
    args
}

vs:

function foo(args) {
  return (
    args
  );
}

JavaScript Terminology

binding / bound
the association of a specific object to this
executor
the function object wrapped by the Promise
falsy
the quality of an object that evaluates to false
fulfilled
the state of a Promise when a result value is available
hoisting
term used to provide a conceptual understanding of how variable and function declarations are put into memory during the compile phase; they can be thought of as being “hoisted” to the top of the file
key
an enumerable property of an object
own property
a property belonging to an object and not a member of its prototype chain
pending
the state of a Promise when not “fulfilled” or “rejected”
rejected
the state of a Promise when a result value is not available but a reason (typically an Error) for rejection is available
resolved
a Promise that is either “settled” or has been “locked in” to match the state of another Promise
settled
a Promise that is either “fulfilled” or “rejected”
truthy
the quality of an object that evaluates to true