Modern Javascript: Everything you missed over the last 10 years by Sandro Turriate<br>Modern Javascript: Everything you missed over the last 10 years (ECMAScript 2020)<br>JavaScript has come a long way since I knew it as the “D” in DHTML. For anyone like me, who’s been reluctant to use the latest syntax that could require polyfills or a transpiler, I’ve written this cheatsheet to get you caught up on all the goodness that’s widely supported in modern browsers.I’ve made this page concise, with runnable examples and links to further documentation. If you have any questions or spot any errata, please contact me.Array functions<br>Check out all these new built-in array functions! No more need for underscore or lodash!Array.every()Array.filter()Array.find()Array.findIndex()Array.forEach()Array.from()Array.includes()Array.isArray()Array.lastIndexOf()Array.map()Array.reduce()Array.reduceRight()Array.some()Array docsconst/let<br>These new keywords declare variables in block scope (as opposed to global or function scope). Using const implies that the value will not change as the reference is immutable. Use let if the value will change.Let documentationNullish coalescing ?? and Optional chaining ?. operators<br>The ?? operator checks if the value is null or undefined. No more need to use the !! check.The ?. operator checks if the value is truthy before calling the next property or function. Extremely useful when dealing with optional props.Optional chaining documentationlet a, b=1<br>let result = a ?? b<br>print(result)
result = (a !== null && a !== undefined) ? a : b;<br>print(result)
print({x:1}?.a?.b ?? "not found")
Async/Await<br>The async/await keywords are here to save you from callback hell. Use await to make an asynchronous call resemble a synchronous call, i.e. running await fetchUserName() will not proceed to the next line until fetchUserName() is complete. Note, in order to use await, you have to be executing a function declared as async, i.e.<br>async function fn(){ await fetchUserName() }.Async/Await docs.function fetchUserName() {<br>return new Promise(resolve => setTimeout(resolve, 500))
async function withAsync() {<br>print("withAsync: fetching...")<br>await fetchUserName()<br>print("withAsync: done")<br>await withAsync()
function withoutAsync() {<br>print("withoutAsync: fetching...")<br>fetchUserName().then(()=>print("withoutAsync done"))<br>withoutAsync()
Arrow functions ()=>{}<br>These are functions that are bound to the current context. There are three main forms you’ll see in the wild:<br>single argument, single line, multi-line.The single argument form does not require parenthesis, and the single line form does not require a return statement; the return is implicit.1<br>const fn = a => a*2<br>Single argument. Single line.The multi-line form requires a return statement if the function intends to returns something. Multiple arguments require parenthesis.1<br>const fn = (a,b) => {<br>console.log(a,b)<br>return a*b<br>Multiple arguments, multiple lines.Arrow function docsfunction example() {<br>this.x = 1<br>this.foo = function() {<br>setTimeout(function() {<br>print("foo lost binding. this = " + JSON.stringify(this))<br>})<br>this.bar = function() {<br>setTimeout(()=> {<br>print("bar this = " + JSON.stringify(this))<br>})<br>const x = new example()<br>x.foo()<br>x.bar()
for...of<br>Used for looping over an iterator. Similar to for...in except you don’t have to check for hasOwnProperty. You cannot use this looping syntax on an Object directly because the Object doesn’t have an iterator. Instead use Object.entries({}) to retrieve an iterable.for...of docsconst x = {a: 1, b: 2}<br>for (const [key, value] of Object.entries(x)) {<br>print(`${key}=${value}`)
for await...of<br>Asynchronous iteration was introduced In 2018. Much like Promise.all, it can be used to synchronize many asynchronous tasks. The example below shows 3 tasks happening asynchronously. The loop processes one result at a time, in order; in this case, the quickest tasks to complete are only evident at the end of the iteration.for await...of docsconst delay = (n) => {<br>return new Promise((resolve) => {<br>setTimeout(()=>{<br>print("resolve "+n)<br>resolve(n)<br>}, n)<br>})
const delays = [<br>delay(150),<br>delay(50),<br>delay(25)
for await (const ret of delays) {<br>print("for loop await "+ret)<br>Classes<br>In 2015, ES6 brought classes to Javascript 🎉. Javascript classes are similar to the classes you know and love from other languages. Inheritance, class methods, getters and setters, properties, etc.Class documentationclass A {<br>constructor(name) {<br>this.name = name<br>myProp = "myProp"<br>static foo() {<br>print("Static method says foo")<br>class B extends A {<br>constructor(name, age) {<br>super(name)<br>this.age = age<br>toString() {<br>return `${this.name} ${this.age}`<br>A.foo()<br>const b = new B("Catch", 22)<br>print(b)<br>print(b.myProp)<br>get/set<br>Get and set are functions that are called like properties, i.e. person.age = 16; person.age > 18. These are very convenient when you need a dynamic or computed property. And they can be used with both classes and regular objects.get/set documentationClasses with getters...