professional-programming/training/front-end/01-modern-javascript.md

755 lines
20 KiB
Markdown
Raw Normal View History

2020-07-21 09:37:15 +02:00
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
## Table of Contents
2020-07-21 11:59:24 +02:00
- [Modern JavaScript](#modern-javascript)
2020-07-24 15:01:11 +02:00
- [Objectives of this course](#objectives-of-this-course)
- [Prerequisites](#prerequisites)
- [Check your knowledge of JS](#check-your-knowledge-of-js)
2020-07-23 11:01:29 +02:00
- [Introduction](#introduction)
2020-07-21 09:37:15 +02:00
- [Quirks](#quirks)
2020-07-23 11:01:29 +02:00
- [Make sure your target browser supports the feature!](#make-sure-your-target-browser-supports-the-feature)
2020-07-21 12:34:19 +02:00
- [Undefined everywhere!](#undefined-everywhere)
2020-07-21 09:37:15 +02:00
- [Printing and interacting with the console](#printing-and-interacting-with-the-console)
2020-07-23 11:01:29 +02:00
- [Casting](#casting)
2020-07-21 09:37:15 +02:00
- [Always use triple comparators (`===`) instead of double (`==`)](#always-use-triple-comparators--instead-of-double-)
2020-07-23 11:01:29 +02:00
- [Primitive types vs. reference types](#primitive-types-vs-reference-types)
2020-07-24 14:06:54 +02:00
- [`Object` and `Array` methods](#object-and-array-methods)
2020-07-23 11:01:29 +02:00
- [Prototypes in JavaScript](#prototypes-in-javascript)
2020-07-21 09:37:15 +02:00
- [Object literals, assignment and destructuring](#object-literals-assignment-and-destructuring)
- [Objects](#objects)
- [Array](#array)
- [`let` and `const`](#let-and-const)
2020-07-21 12:34:19 +02:00
- [Hoisting](#hoisting)
2020-07-21 09:37:15 +02:00
- [Arrow functions](#arrow-functions)
- [How `this` works in arrow functions](#how-this-works-in-arrow-functions)
- [Best practices](#best-practices)
- [Classes](#classes)
- [Template literals](#template-literals)
- [Template tags](#template-tags)
- [Loops](#loops)
- [`for... of`](#for-of)
- [Promises](#promises)
- [Creating a promise](#creating-a-promise)
- [Consuming a promise](#consuming-a-promise)
- [Chaining promises](#chaining-promises)
- [Async functions](#async-functions)
- [Modules](#modules)
2020-07-23 11:01:29 +02:00
- [Imports](#imports)
- [Exports](#exports)
2020-07-21 12:16:54 +02:00
- [Other features](#other-features)
- [Optional chaining](#optional-chaining)
2020-07-27 12:43:02 +02:00
- [Ternary operator](#ternary-operator)
2020-07-23 11:01:29 +02:00
- [Self assessment](#self-assessment)
2020-07-27 12:43:02 +02:00
- [References](#references)
2020-07-21 09:37:15 +02:00
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
2020-07-21 11:59:24 +02:00
# Modern JavaScript
2020-07-20 17:49:56 +02:00
Note: run code quickly with https://codesandbox.io/s/
2020-07-22 18:11:56 +02:00
- JavaScript: https://codesandbox.io/s/front-end-training-014br
2020-07-24 15:01:11 +02:00
## Objectives of this course
- Review the syntax of modern JavaScript features
- Mention some JS best practices
## Prerequisites
2020-07-23 11:01:29 +02:00
This course assumes you already have experience with JavaScript. If you don't, start with this:
- [JavaScript First Steps](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps), MDN
- [Learn JavaScript](https://learnjavascript.online/)
2020-07-24 15:01:11 +02:00
### Check your knowledge of JS
2020-07-24 18:03:15 +02:00
- What are the main JS datatypes?
- `Number`, `String`, `Boolean`, `Object`, `Undefined`, `BigInt`
2020-07-24 15:01:11 +02:00
- What does `1 / "a"` evaluate to?
- `NaN`
2020-07-23 11:01:29 +02:00
## Introduction
JavaScript is a programming language evolving very rapidly that can run in different environments:
- Browser (the assumed target for this document).
- Computer and embedded systems (usually through node)
- Mobile and desktop apps with frameworks such as Electron, React Native, etc.
Key historical elements:
- September 1995: LiveScript is released in the Netscape Navigator Browser. It was developed by Brendan Eich.
2020-07-24 15:01:11 +02:00
- June 1997: Ecma International releases the first ECMAScript language _specification_. (note: the European Computer Manufacturers Association was founded in 1961 to standardize computer systems)
2020-07-23 11:01:29 +02:00
- December 2009: the ECMAScript 5 standard is released.
From 2016 to today, a new version of ECMAScript is released each year. The language has reached maturity and supports many modern constructs.
Key features of JavaScript:
2020-07-24 15:01:11 +02:00
- It is **imperative** & inspired by C
2020-07-23 11:01:29 +02:00
- `if`, `while`, `switch`, `while`, `do while`
2020-07-24 15:01:11 +02:00
- It is **weakly typed**: it has types (`String`, `Number`, etc.) but uses implicit cast (`"1" - "1" === 0`).
- It is **dynamically typed**: types are associated with values rather than expressions (a variable `x` can be associated with a `String`, then with a `Number`).
- It supports **runtime evaluation** with `eval`. `eval('1 === 1')` evaluates to `true`
- It supports **object orientation** with a very powerful prototype-based approach.
- While it is not necessarily considered a pure functional language, its **functions are first-class citizen**. It supports closures and anonymous functions. As a result, it can be used to go pretty far with functional programming patterns.
- It is very **concise**. Newer features such as arrow functions, object and array destructuring leads to very terse code with a very high signal to noise ration.
2020-07-23 11:01:29 +02:00
2020-07-20 17:49:56 +02:00
## Quirks
2020-07-23 11:01:29 +02:00
### Make sure your target browser supports the feature!
Use [caniuse](https://caniuse.com/) to check what browser support the feature you're using. For instance, for `[1, 2].includes(1)` requires `Array.prototype.includes`:
![caniuse](./img/caniuse.png)
2020-07-21 12:34:19 +02:00
2020-07-23 11:01:29 +02:00
You can then use "polyfills" (or "shims") to support older browser. There are some polyfills for each specific feature, and some other that includes lots of polyfills (e.g. [zloirock/core-js](https://github.com/zloirock/core-js#ecmascript-array)).
2020-07-27 10:51:39 +02:00
Polyfills are different from transpiling. Babel is a transpiler, you can see how it work online here:
2020-07-24 18:03:15 +02:00
2020-07-27 10:51:39 +02:00
For instance, it will transpile (notice the replacement of an arrow function):
2020-07-24 18:03:15 +02:00
```javascript
[1, 2, 3].map((n) => n + 1)
```
Into:
```javascript
"use strict";
[1, 2, 3].map(function (n) {
return n + 1;
});
```
2020-07-23 11:01:29 +02:00
### Undefined everywhere!
2020-07-21 12:34:19 +02:00
```javascript
2020-07-23 11:01:29 +02:00
var a;
2020-07-24 15:01:11 +02:00
// an uninitialized variable is undefined
2020-07-23 11:01:29 +02:00
console.assert(typeof a === "undefined");
// There are no required arguments in JavaScript
2020-07-21 12:34:19 +02:00
function hello(name) {
return name;
2020-07-21 12:56:39 +02:00
}
2020-07-21 12:34:19 +02:00
2020-07-21 12:56:39 +02:00
// No raise, will log "undefined"
2020-07-21 12:34:19 +02:00
console.log(hello());
// Here's how to compare to undefined
2020-07-21 12:56:39 +02:00
console.assert(typeof undefined === "undefined");
2020-07-23 11:01:29 +02:00
2020-07-24 15:01:11 +02:00
const anObject = { a: 1 };
2020-07-23 11:01:29 +02:00
// Accessing an absent object key also returns undefined
2020-07-24 15:01:11 +02:00
console.assert(typeof anObject.nonExistent === "undefined");
2020-07-21 12:34:19 +02:00
```
2020-07-20 18:12:51 +02:00
### Printing and interacting with the console
```javascript
2020-07-24 15:01:11 +02:00
// Do not leave console.log in your code!
// There are linters such as eslint that will check for their absence
2020-07-20 18:12:51 +02:00
console.log("hello");
2020-07-23 11:01:29 +02:00
// In this document, we use assert to show the actual value
2020-07-22 18:11:56 +02:00
console.assert(true === true);
2020-07-20 18:12:51 +02:00
```
2020-07-23 11:01:29 +02:00
### Casting
Rules for string conversion:
2020-07-24 15:01:11 +02:00
- `String` are left as is.
- `Number` are converted to their string representation.
- Elements of `Array` are converted to string, then joined with commas `,`.
- Objects are converted to `[object Object]` where `Object` is the constructor of the object.
2020-07-23 11:01:29 +02:00
Can you guess how those will be converted?
```javascript
[] + []
{} + {}
"1" + 1
"1" + "1"
"1" - 1
[1, 2] + 2
[1] + 1
function Dog {}
const dog = new Dog()
dog + 1 + "a"
dog - 1
```
2020-07-20 17:49:56 +02:00
2020-07-24 18:03:15 +02:00
Other gotchas:
```javascript
// NaN is fun!
console.assert(typeof NaN === "number");
Object.is(NaN, NaN) // true
NaN === NaN // false
```
A good talk on the topic: [Wat](https://www.destroyallsoftware.com/talks/wat)
2020-07-20 17:49:56 +02:00
#### Always use triple comparators (`===`) instead of double (`==`)
```javascript
2020-07-23 11:01:29 +02:00
// Double equals will coerce values to make them comparable!
console.assert("1" == 1);
2020-07-20 17:49:56 +02:00
// Better
2020-07-21 09:14:24 +02:00
console.assert(!("1" === 1));
console.assert("1" !== 1);
2020-07-20 17:49:56 +02:00
```
2020-07-23 11:01:29 +02:00
### Primitive types vs. reference types
2020-07-20 17:49:56 +02:00
Applied on arrays and objects, `==` and `===` will check for object identity, which is almost never what you want.
```javascript
2020-07-21 09:14:24 +02:00
console.assert({ a: 1 } != { a: 1 });
console.assert({ a: 1 } !== { a: 1 });
2020-07-20 17:49:56 +02:00
2020-07-21 09:14:24 +02:00
const obj = { a: 1 };
const obj2 = obj;
2020-07-22 18:11:56 +02:00
// This is true because obj and obj2 refer to the same object ("identity")
2020-07-21 09:14:24 +02:00
console.assert(obj == obj2);
console.assert(obj === obj2);
2020-07-20 17:49:56 +02:00
```
Use a library such as [lodash](https://lodash.com/) to properly compare objects and array
```javascript
2020-07-21 09:14:24 +02:00
import _ from "lodash";
2020-07-20 17:49:56 +02:00
2020-07-21 09:14:24 +02:00
console.assert(_.isEqual({ a: 1 }, { a: 1 }));
console.assert(_.isEqual([1, 2], [1, 2]));
2020-07-20 18:12:51 +02:00
```
2020-07-24 14:06:54 +02:00
### `Object` and `Array` methods
2020-07-20 18:12:51 +02:00
2020-07-24 14:06:54 +02:00
```javascript
// Use Object.assign (ES 2015) to copy objects
2020-07-24 15:01:11 +02:00
const target = { a: 1, b: 1};
const source = { b: 2};
const merged = Object.assign(target, source);
console.assert(_.isEqual(merged, {a: 1, b:2});
2020-07-20 18:12:51 +02:00
2020-07-24 18:03:15 +02:00
// Spread operator
const merge2 = {...target, ...source};
2020-07-24 14:06:54 +02:00
// Array.includes (ES7)
2020-07-24 15:01:11 +02:00
const theArray = [1, 2]
console.assert(theArray.includes(1))
2020-07-24 14:06:54 +02:00
```
2020-07-20 17:49:56 +02:00
2020-07-23 11:01:29 +02:00
## Prototypes in JavaScript
JavaScript has a very powerful prototypal inheritance system that is very interesting to study.
2020-07-24 14:06:54 +02:00
The truth is, it is much less used nowadays, and you don't really need to know it to develop with React. It also requires a bit of personal study to fully understand it. So we will leave it aside for now.
2020-07-23 11:01:29 +02:00
The book [JavaScript: The Good Parts](https://www.oreilly.com/library/view/javascript-the-good/9780596517748/) by Douglas Crockford (2008) is a great introduction to it. Here's a quote from the author:
> You make prototype objects, and then … make new instances. Objects are mutable in JavaScript, so we can augment the new instances, giving them new fields and methods. These can then act as prototypes for even newer objects. We don't need classes to make lots of similar objects… Objects inherit from objects. What could be more object oriented than that?
2020-07-24 18:03:15 +02:00
![JavaScript: the good parts](./img/js-the-good-parts.jpg)
2020-07-23 11:01:29 +02:00
Some good articles:
- [A Plain English Guide to JavaScript Prototypes](http://sporto.github.io/blog/2013/02/22/a-plain-english-guide-to-javascript-prototypes/)
2020-07-20 18:12:51 +02:00
## Object literals, assignment and destructuring
2020-07-20 17:49:56 +02:00
### Objects
```javascript
2020-07-21 09:14:24 +02:00
const toaster = { size: 2, color: "red", brand: "NoName" };
2020-07-20 17:49:56 +02:00
2020-07-21 12:56:39 +02:00
// Get ("destructure") one object key
2020-07-21 09:14:24 +02:00
const { size } = toaster;
console.assert(size === 2);
2020-07-20 17:49:56 +02:00
2020-07-21 12:56:39 +02:00
// Note: this also works with functions
function destructuredFunction({ color }) {
return color;
}
console.assert(destructuredFunction({ color: "red" }) === "red");
2020-07-20 17:49:56 +02:00
// Get the rest with ...rest
2020-07-21 09:14:24 +02:00
const { color, brand, ...rest } = toaster;
console.assert(_.isEqual(rest, { size: 2 }));
2020-07-20 18:12:51 +02:00
// Set default
2020-07-21 09:14:24 +02:00
const { size2 = 3 } = toaster;
console.assert(size2 === 3);
2020-07-20 18:12:51 +02:00
// Rename variables
2020-07-21 09:14:24 +02:00
const { size: size3 } = toaster;
console.assert(size3 === 2);
2020-07-21 12:56:39 +02:00
```
Enhanced object literals:
2020-07-20 18:12:51 +02:00
2020-07-21 12:56:39 +02:00
```javascript
2020-07-21 09:14:24 +02:00
const name = "Louis";
const person = { name };
console.assert(_.isEqual(person, { name: "Louis" }));
2020-07-20 18:12:51 +02:00
// Dynamic properties
2020-07-21 09:14:24 +02:00
const person2 = { ["first" + "Name"]: "Olympe" };
console.assert(_.isEqual(person2, { firstName: "Olympe" }));
2020-07-20 18:12:51 +02:00
// Btw, you can include quotes although nobody does this
2020-07-21 09:14:24 +02:00
console.assert(_.isEqual(person2, { firstName: "Olympe" }));
2020-07-21 12:08:28 +02:00
// Short form function
2020-07-24 15:01:11 +02:00
// Before:
2020-07-21 12:08:28 +02:00
const es5Object = {
say: function () {
console.log("hello");
},
};
2020-07-21 12:08:46 +02:00
es5Object.say();
2020-07-21 12:08:28 +02:00
2020-07-24 15:01:11 +02:00
// After: (short form function)
2020-07-21 12:08:28 +02:00
const es6Object = {
say() {
console.log("hello");
},
};
2020-07-21 12:08:46 +02:00
es6Object.say();
2020-07-24 15:01:11 +02:00
```
Advanced (with prototype):
2020-07-21 12:56:39 +02:00
2020-07-24 15:01:11 +02:00
```javascript
2020-07-21 12:56:39 +02:00
// Prototype and super()
const firstObject = {
a: "a",
hello() {
return "hello";
},
};
const secondObject = {
__proto__: firstObject,
hello() {
return super.hello() + " from second object";
},
};
console.assert(secondObject.hello() === "hello from second object");
2020-07-20 17:49:56 +02:00
```
### Array
```javascript
const theArray = [1, 2, 3];
const [first, second] = theArray;
const [first1, second2, ...rest] = theArray;
console.assert(first === 1);
console.assert(second === 2);
console.assert(_.isEqualWith(rest, [3]));
```
## `let` and `const`
```javascript
2020-07-21 09:14:24 +02:00
const constantVar = "a";
2020-07-20 17:49:56 +02:00
// Raises "constantVar" is read-only
2020-07-21 09:14:24 +02:00
constantVar = "b";
2020-07-20 17:49:56 +02:00
2020-07-21 12:16:54 +02:00
let theVar = "a";
theVar = "a";
2020-07-20 17:49:56 +02:00
2020-07-24 15:01:11 +02:00
// Note: const != immutable
2020-07-21 09:14:24 +02:00
const constantObject = { a: 1 };
constantObject.a = 2;
constantObject.b = 3;
2020-07-20 17:49:56 +02:00
// Raises: "constantObject" is read-only
2020-07-21 09:14:24 +02:00
constantObject = { a: 1 };
2020-07-20 17:49:56 +02:00
2020-07-24 15:01:11 +02:00
// const and let are block scoped. A block is enclosed in {} (if, loops, functions, etc.)
2020-07-20 17:49:56 +02:00
{
2020-07-21 09:14:24 +02:00
const a = "a";
console.log({ a });
2020-07-20 17:49:56 +02:00
}
// Raises: ReferenceError: a is not defined
2020-07-21 09:14:24 +02:00
console.log({ a });
2020-07-20 17:49:56 +02:00
```
Note: try to use `const` as much as you can.
2020-07-22 18:11:56 +02:00
- Those variables can't be reassigned. More constraints leads to safer code.
- You can't define a `const` without providing its initial value.
- Most people do this in modern JS.
2020-07-20 17:49:56 +02:00
Never use `var`:
- `var` variables are initialized with `undefined`, while `let` and `const` vars are not initialized and will raise an error if used before definition.
- `var` is globally or function-scoped, depending on whether it is used inside a function.
- `let` and `const` are block-scoped
- `let` and `const` cannot be reused for the same variable name
2020-07-24 15:01:11 +02:00
Future of JavaScript: [tc39/proposal-record-tuple: ECMAScript proposal for the Record and Tuple value types](https://github.com/tc39/proposal-record-tuple)
2020-07-21 12:34:19 +02:00
### Hoisting
See [Hoisting on MDN](https://developer.mozilla.org/en-US/docs/Glossary/Hoisting)
2020-07-24 14:06:54 +02:00
```javascript
console.log(typeof variable); // undefined
// console.log(variable); // Raises: ReferenceError: variable is not defined
function hoist() {
a = 20;
var b = 100;
}
hoist();
// 20, accessible as a global variable outside of hoist
console.log(a);
// Raises: ReferenceError: b is not defined
// console.log(b);
```
2020-07-20 17:49:56 +02:00
## Arrow functions
The first advantage of arrow function is that they're shorter to write:
```javascript
// You can define a function this way:
2020-07-21 09:14:24 +02:00
const myFunction = function () {
2020-07-20 17:49:56 +02:00
console.log("hello world");
2020-07-21 09:14:24 +02:00
};
2020-07-20 17:49:56 +02:00
// With an arrow function, you save a few characters:
const myArrowFunction = () => {
console.log("hello world");
2020-07-21 09:14:24 +02:00
};
2020-07-20 17:49:56 +02:00
// Some things, like params parentheses, and function code brackets, are optional
2020-07-21 09:14:24 +02:00
const myFunctionToBeShortened = function (a) {
2020-07-20 17:49:56 +02:00
return a;
2020-07-21 09:14:24 +02:00
};
2020-07-20 17:49:56 +02:00
// Shorter arrow function
const myFunctionToBeShortenedArrowV1 = (a) => {
return a;
2020-07-21 09:14:24 +02:00
};
2020-07-20 17:49:56 +02:00
// Shortest arrow function
// Remove single param parenthesis, remove function code bracket, remove return
2020-07-21 09:14:24 +02:00
const myFunctionToBeShortenedArrowV2 = (a) => a;
console.assert(myFunctionToBeShortenedArrowV2(1) === 1);
2020-07-20 17:49:56 +02:00
```
2020-07-20 18:12:51 +02:00
### How `this` works in arrow functions
2020-07-24 15:01:11 +02:00
TODO
2020-07-20 18:12:51 +02:00
### Best practices
2020-07-20 17:49:56 +02:00
2020-07-24 15:01:11 +02:00
I usually keep the parameters parenthesis. If you add a parameter and weren't including them, you'll have to add them back:
```javascript
const a1 = (arg) => {};
const a2 = (arg1, arg2) => {};
// vs.
const a3 = (arg) => {};
```
2020-07-20 17:49:56 +02:00
2020-07-20 18:12:51 +02:00
## Classes
2020-07-21 12:34:19 +02:00
```javascript
class Toaster {
2020-07-21 12:56:39 +02:00
constructor(color) {
this.color = color;
}
2020-07-21 12:34:19 +02:00
2020-07-21 12:56:39 +02:00
dring() {
return "dring";
}
2020-07-21 12:34:19 +02:00
}
// Don't forget new!
// Raises: TypeError: Cannot call a class as a function
// const toaster = Toaster('red');
2020-07-21 12:56:39 +02:00
const toaster = new Toaster("red");
console.log(toaster.dring());
2020-07-21 12:34:19 +02:00
// Inheritance
class BunToaster extends Toaster {
dring() {
2020-07-21 12:56:39 +02:00
return super.dring() + " dring";
2020-07-21 12:34:19 +02:00
}
2020-07-21 12:56:39 +02:00
}
2020-07-21 12:34:19 +02:00
2020-07-21 12:56:39 +02:00
const bunToaster = new BunToaster("red");
console.assert(bunToaster.dring() === "dring dring");
2020-07-21 12:34:19 +02:00
```
Those are my opinions about other class features:
- Avoid using `static` methods, use plain functions instead.
- Avoid using more than one level of inheritance.
- Avoid using getter and setters (`get` and `set`).
2020-07-24 15:01:11 +02:00
- Avoid using classes if you can.
2020-07-21 12:34:19 +02:00
2020-07-20 18:12:51 +02:00
## Template literals
2020-07-21 12:08:28 +02:00
```javascript
const longString = `multi
line
string`;
const name = "Louis";
// Template interpolation
const hello = `Hello ${name}`;
2020-07-21 12:56:39 +02:00
// You can have expressions
const hello1 = `Hello ${name + "!"}`;
const hello2 = `Hello ${name === "Louis" ? name : "Noname"}`;
2020-07-21 12:08:28 +02:00
```
2020-07-20 18:12:51 +02:00
### Template tags
2020-07-21 12:56:39 +02:00
They are used in some libraries, like Apollo and Styled Components.
```javascript
2020-07-24 15:01:11 +02:00
// First arg is an array of string values, the rest is the expressions
// ["hello ", ""], 3
2020-07-21 12:56:39 +02:00
function templateTag(literals, ...expressions) {
console.assert(_.isEqual(literals, ["hello ", ""]));
console.assert(_.isEqual(expressions, [3]));
return _.join(_.flatten(_.zip(literals, expressions)), "");
}
const result = templateTag`hello ${1 + 2}`;
console.assert(result === "hello 3");
```
2020-07-24 18:03:15 +02:00
Here's an example with Styled Components:
```javascript
const Button = styled.a`
/* This renders the buttons above... Edit me! */
display: inline-block;
border-radius: 3px;
padding: 0.5rem 0;
margin: 0.5rem 1rem;
width: 11rem;
background: transparent;
color: white;
border: 2px solid white;
/* The GitHub button is a primary button
* edit this to target it specifically! */
${props => props.primary && css`
background: white;
color: black;
`}
`
```
You can see how template tags and arrow functions lead to more concise code!
2020-07-20 18:12:51 +02:00
## Loops
### `for... of`
Note: prefer using some functional constructs such as `map`, `reduce`, etc.
2020-07-21 12:56:39 +02:00
```javascript
for (const i of [1, 2, 3]) {
console.log({ i });
}
// 1, 2, 3
for (const key in { a: "aaa", b: "bbb" }) {
console.log({ key });
}
// 'a', 'b'
```
2020-07-20 18:12:51 +02:00
## Promises
2020-07-22 09:47:58 +02:00
This is only going to be an introduction to the magnificent world of promise.
- Async functions (seen later) use promises as a building block.
- Promise are indeed async in nature: the calling code continues executing the promise does its thing.
- Some Web API return promises, including `Fetch`
2020-07-20 18:12:51 +02:00
### Creating a promise
2020-07-22 09:47:58 +02:00
Note: we use TypeScript in this example, to clarify what's return. You can ignore the type annotations for now.
```typescript
let isDone: boolean = true
const thePromise = new Promise((resolve, reject) => {
if (isDone) {
resolve("the work is done");
} else {
reject("this is still pending");
}
}
console.assert(thePromise === 'the work is done')
```
TODO
2020-07-20 18:12:51 +02:00
### Consuming a promise
### Chaining promises
## Async functions
## Modules
CommonJS syntax:
2020-07-22 18:11:56 +02:00
```javascript
const lodash = require("lodash");
```
2020-07-20 18:12:51 +02:00
ES Module syntax:
2020-07-22 18:11:56 +02:00
```javascript
import lodash from "lodash";
```
### Imports
```javascript
// Import all and provide under name
import * as toaster from "./toaster";
// Named import (same as object destructuring!)
import { defaultColor, defaultSize } from "./toaster";
// Renaming imports
import { defaultBrand as toasterDefaultBrand } from "./toaster";
// Default import
import createToaster from "./toaster";
// Import both defaults and other
// import createToaster, {defaultColor} from './toaster'
```
### Exports
In `toaster.js`:
```javascript
// Shorthand definition + export
export const defaultSize = 4;
// Alternative export syntax
const defaultBrand = "Moulinex";
export { defaultBrand };
// Default export
const createToaster = ({ size, color }) => ({ size, color });
export default createToaster;
// Note that you have a shorthand default export, but it's not recommended to
// use it as the export won't have a name.
// export default () => ({})
```
2020-07-20 18:12:51 +02:00
2020-07-21 12:16:54 +02:00
## Other features
### Optional chaining
2020-07-24 15:01:11 +02:00
```javascript
let nestedProp = obj.first && obj.first.second;
// with optional chaining:
let nestedProp = obj.first?.second;
```
2020-07-27 12:43:02 +02:00
### Ternary operator
```javascript
const a = 'a'
const r = a === 'a' ? 'isA' : 'isNotA'
console.assert(r === 'isA')
```
2020-07-23 11:01:29 +02:00
## Self assessment
- How old is JavaScript?
- Is it a modern language?
- Can we say that JavaScript does not have types?
2020-07-24 15:01:11 +02:00
- What is the value of this expression: `"1" + "1"`? `3 + 2 + "5"`?
2020-07-24 18:03:15 +02:00
- What should I use? `let`, `var`, or `const`?
2020-07-23 11:01:29 +02:00
- How do you add support for modern JS features in older browsers?
2020-07-24 14:06:54 +02:00
- How are variables scoped in JavaScript?
- What should you watch for when comparing variables in JavaScript?
2020-07-24 18:03:15 +02:00
- `const a = [1]; const b = [1];`: what does `a == b` evaluates to?
2020-07-24 14:06:54 +02:00
- How do you write arrow functions?
- `const {a} = {a: 1}`: what does `a` evaluate to?
2020-07-27 12:43:02 +02:00
- How do you write the ternary operator?
2020-07-24 14:06:54 +02:00
Advanced:
2020-07-24 18:03:15 +02:00
- How does JavaScript objects "inherit" from each other?
```javascript
// Write transform1 using a one-line arrow function with object structuring
console.assert(_.isEqual(transform1({name: "Foo"}), {FooA:1}))
console.assert(_.isEqual(transform1({name: "Bar"}), {Bar:1}))
2020-07-27 12:43:02 +02:00
```
The three things you need:
- Use `let` and `const`
- Object destructuring `const { a } = {a: 1}`
- Arrow functions `const noop = () => { }`
2020-07-24 14:06:54 +02:00
Other assessments:
- [37 Essential JavaScript Interview Questions and Answers](https://www.toptal.com/javascript/interview-questions)
- [70 JavaScript Interview Questions](https://dev.to/macmacky/70-javascript-interview-questions-5gfi), DEV
2020-07-23 11:01:29 +02:00
2020-07-20 17:49:56 +02:00
## References
- [ES5 to ESNextheres every feature added to JavaScript since 2015](https://www.freecodecamp.org/news/es5-to-esnext-heres-every-feature-added-to-javascript-since-2015-d0c255e13c6e/)
2020-07-21 12:08:28 +02:00
- [ES2015 / ES6: Basics of modern Javascript](https://www.slideshare.net/WojciechDzikowski/es2015-es6-basics-of-modern-javascript)
2020-07-23 11:01:29 +02:00
- [JavaScript](https://en.wikipedia.org/wiki/JavaScript), Wikipedia
2020-07-24 14:06:54 +02:00
- [mbeaudru/modern-js-cheatsheet](https://github.com/mbeaudru/modern-js-cheatsheet)
2020-10-06 11:26:09 +02:00
- [The vanilla Javascript basics to know before learning React JS - DEV](https://dev.to/tracycss/the-vanilla-javascript-basics-to-know-before-learning-react-js-53aj)
2020-07-23 11:01:29 +02:00
Future changes:
- [tc39/proposal-record-tuple: ECMAScript proposal for the Record and Tuple value types.](https://github.com/tc39/proposal-record-tuple)