# Modern JavaScript/TypeScript Note: run code quickly with https://codesandbox.io/s/ ## Quirks ### Printing and interacting with the console ```javascript // Do not leave console.log in your code! There are linters such as eslint that will check for their absence console.log("hello"); ``` ### Comparing scalar, arrays, and objects #### Always use triple comparators (`===`) instead of double (`==`) ```javascript // ??? console.assert('1' == 1) // Better console.assert(!('1' === 1)) console.assert('1' !== 1) ``` #### Comparing non-scalar Applied on arrays and objects, `==` and `===` will check for object identity, which is almost never what you want. ```javascript console.assert({a: 1} != {a: 1}) console.assert({a: 1} !== {a: 1}) const obj = {a: 1} const obj2 = obj console.assert(obj == obj2) console.assert(obj === obj2) ``` Use a library such as [lodash](https://lodash.com/) to properly compare objects and array ```javascript import _ from 'lodash' console.assert(_.isEqual({a: 1}, {a: 1})) console.assert(_.isEqual([1, 2], [1, 2])) ``` ### `Object` methods #### `Object.assign`, spread operator `Object.assign` (ES 2015) ### `Array` methods #### `Array.includes` (ES7) ## Object literals, assignment and destructuring ### Objects ```javascript const toaster = {size: 2, color: 'red', brand: 'NoName'}; // Get one object key const {size} = toaster; console.assert(size === 2) // Get the rest with ...rest const {color, brand, ...rest} = toaster; console.assert(_.isEqual(rest, {size: 2})); // Set default const {size2 = 3} = toaster console.assert(size2 === 3) // Rename variables const {size: size3} = toaster console.assert(size3 === 2) // Enhances object literals const name = 'Louis' const person = {name} console.assert(_.isEqual(person, {name: 'Louis'})) // Dynamic properties const person2 = {['first' + 'Name']: 'Olympe'} console.assert(_.isEqual(person2, {firstName: 'Olympe'})) // Btw, you can include quotes although nobody does this console.assert(_.isEqual(person2, {'firstName': 'Olympe'})) ``` ### 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 const constantVar = 'a'; // Raises "constantVar" is read-only constantVar = 'b'; let mutableVar = 'a'; mutableVar = 'a'; // Note: this will work ok const constantObject = {a: 1} constantObject.a = 2 constantObject.b = 3 // Raises: "constantObject" is read-only constantObject = {a: 1} // const and let are block scoped. A block is enclosed in {} { const a = 'a'; console.log({a}) } // Raises: ReferenceError: a is not defined console.log({a}) ``` Note: try to use `const` as much as you can. - More constraints = safer code - Some kind of "immutability" is good (since `const` objects can be modified, it is not true immutability) - You can't define a `const` without providing its initial value - Most people do this in modern JS 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 ## Arrow functions The first advantage of arrow function is that they're shorter to write: ```javascript // You can define a function this way: const myFunction = function() { console.log("hello world"); } // With an arrow function, you save a few characters: const myArrowFunction = () => { console.log("hello world"); } // Some things, like params parentheses, and function code brackets, are optional const myFunctionToBeShortened = function(a) { return a; } // Shorter arrow function const myFunctionToBeShortenedArrowV1 = (a) => { return a; } // Shortest arrow function // Remove single param parenthesis, remove function code bracket, remove return const myFunctionToBeShortenedArrowV2 = a => a console.assert(myFunctionToBeShortenedArrowV2(1) === 1) ``` ### How `this` works in arrow functions ### Best practices - I usually keep the parameters parenthesis. If you add a parameter, you'll have to add them back. ## Classes ### Prototypal inheritance ## Template literals ### Template tags ## Loops ### `for... of` Note: prefer using some functional constructs such as `map`, `reduce`, etc. ## Promises ### Creating a promise ### Consuming a promise ### Chaining promises ## Async functions ## Modules CommonJS syntax: ES Module syntax: - default export and imports - renaming imports ## TypeScript ### Differences between TypeScript and JavaScript ### An introduction to TypeScript's type system ## References - [ES5 to ESNext — here’s every feature added to JavaScript since 2015](https://www.freecodecamp.org/news/es5-to-esnext-heres-every-feature-added-to-javascript-since-2015-d0c255e13c6e/)