[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-71505":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":10,"languages":10,"totalLinesOfCode":10,"stars":11,"forks":12,"watchers":13,"openIssues":14,"contributorsCount":15,"subscribersCount":15,"size":15,"stars1d":15,"stars7d":15,"stars30d":15,"stars90d":15,"forks30d":15,"starsTrendScore":15,"compositeScore":16,"rankGlobal":10,"rankLanguage":10,"license":17,"archived":18,"fork":18,"defaultBranch":19,"hasWiki":20,"hasPages":20,"topics":21,"createdAt":10,"pushedAt":10,"updatedAt":24,"readmeContent":25,"aiSummary":26,"trendingCount":15,"starSnapshotCount":15,"syncStatus":27,"lastSyncTime":28,"discoverSource":29},71505,"modern-js-cheatsheet","mbeaudru\u002Fmodern-js-cheatsheet","mbeaudru","Cheatsheet for the JavaScript knowledge you will frequently encounter in modern projects.","https:\u002F\u002Fmbeaudru.github.io\u002Fmodern-js-cheatsheet\u002F",null,25632,3164,621,9,0,70,"MIT License",false,"master",true,[22,23],"es6","javascript","2026-06-12 04:01:01","# Modern JavaScript Cheatsheet\n\n![Modern JavaScript cheatsheet](https:\u002F\u002Fi.imgur.com\u002FaexPxMb.png)\n\u003Csub>Image Credits: [Ahmad Awais ⚡️](https:\u002F\u002Fgithub.com\u002Fahmadawais)\u003C\u002Fsub>\n\n> If you like this content, you can ping me or follow me on Twitter :+1:\n\n[![Tweet for help](https:\u002F\u002Fimg.shields.io\u002Ftwitter\u002Ffollow\u002Fmbeaudru?label=Tweet%20%40mbeaudru&style=social)](https:\u002F\u002Ftwitter.com\u002Fmbeaudru\u002F)\n\n## Introduction\n\n### Motivation\n\nThis document is a cheatsheet for JavaScript you will frequently encounter in modern projects and most contemporary sample code.\n\nThis guide is not intended to teach you JavaScript from the ground up, but to help developers with basic knowledge who may struggle to get familiar with modern codebases (or let's say to learn React for instance) because of the JavaScript concepts used.\n\nBesides, I will sometimes provide personal tips that may be debatable but will take care to mention that it's a personal recommendation when I do so.\n\n> **Note:** Most of the concepts introduced here are coming from a JavaScript language update (ES2015, often called ES6). You can find new features added by this update [here](http:\u002F\u002Fes6-features.org); it's very well done.\n\n### Complementary Resources\n\nWhen you struggle to understand a notion, I suggest you look for answers on the following resources:\n\n- [MDN (Mozilla Developer Network)](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fsearch?q=)\n- [You don't know JS (book)](https:\u002F\u002Fgithub.com\u002Fgetify\u002FYou-Dont-Know-JS)\n- [Eloquent JavaScript (book)](https:\u002F\u002Feloquentjavascript.net)\n- [Douglas Crockford's blog](https:\u002F\u002Fwww.crockford.com\u002Fjavascript\u002F)\n- [Wes Bos blog (ES6)](https:\u002F\u002Fwesbos.com\u002Fjavascript)\n- [Javascript Basics for Beginners](https:\u002F\u002Fwww.udacity.com\u002Fcourse\u002Fjavascript-basics--ud804) - a free Udacity course\n- [Reddit (JavaScript)](https:\u002F\u002Fwww.reddit.com\u002Fr\u002Fjavascript\u002F)\n- [Google](https:\u002F\u002Fwww.google.com\u002F) to find specific blog and resources\n- [StackOverflow](https:\u002F\u002Fstackoverflow.com\u002Fquestions\u002Ftagged\u002Fjavascript)\n\n## Table of Contents\n\n- [Modern JavaScript cheatsheet](#modern-javascript-cheatsheet)\n  * [Introduction](#introduction)\n    + [Motivation](#motivation)\n    + [Complementary resources](#complementary-resources)\n  * [Table of contents](#table-of-contents)\n  * [Notions](#notions)\n    + [Variable declaration: var, const, let](#variable-declaration-var-const-let)\n      - [Short explanation](#short-explanation)\n      - [Sample code](#sample-code)\n      - [Detailed explanation](#detailed-explanation)\n      - [External resource](#external-resource)\n    + [Arrow function](#-arrow-function)\n      - [Sample code](#sample-code-1)\n      - [Detailed explanation](#detailed-explanation-1)\n        * [Concision](#concision)\n        * [*this* reference](#this-reference)\n      - [Useful resources](#useful-resources)\n    + [Function default parameter value](#function-default-parameter-value)\n      - [External resource](#external-resource-1)\n    + [Destructuring objects and arrays](#destructuring-objects-and-arrays)\n      - [Explanation with sample code](#explanation-with-sample-code)\n      - [Useful resources](#useful-resources-1)\n    + [Array methods - map \u002F filter \u002F reduce](#array-methods---map--filter--reduce--find)\n      - [Sample code](#sample-code-2)\n      - [Explanation](#explanation)\n        * [Array.prototype.map()](#arrayprototypemap)\n        * [Array.prototype.filter()](#arrayprototypefilter)\n        * [Array.prototype.reduce()](#arrayprototypereduce)\n        * [Array.prototype.find()](#arrayprototypefind)\n      - [External Resource](#external-resource-2)\n    + [Spread operator \"...\"](#spread-operator-)\n      - [Sample code](#sample-code-3)\n      - [Explanation](#explanation-1)\n        * [In iterables (like arrays)](#in-iterables-like-arrays)\n        * [Function rest parameter](#function-rest-parameter)\n        * [Object properties spreading](#object-properties-spreading)\n      - [External resources](#external-resources)\n    + [Object property shorthand](#object-property-shorthand)\n      - [Explanation](#explanation-2)\n      - [External resources](#external-resources-1)\n    + [Promises](#promises)\n      - [Sample code](#sample-code-4)\n      - [Explanation](#explanation-3)\n        * [Create the promise](#create-the-promise)\n        * [Promise handlers usage](#promise-handlers-usage)\n      - [External Resources](#external-resources-2)\n    + [Template literals](#template-literals)\n      - [Sample code](#sample-code-5)\n      - [External resources](#external-resources-3)\n    + [Tagged Template Literals](#tagged-template-literals)\n      - [External resources](#external-resources-4)\n    + [Imports \u002F Exports](#imports--exports)\n      - [Explanation with sample code](#explanation-with-sample-code-1)\n        * [Named exports](#named-exports)\n        * [Default import \u002F export](#default-import--export)\n      - [External resources](#external-resources-5)\n    + [JavaScript *this*](#-javascript-this)\n      - [External resources](#external-resources-6)\n    + [Class](#class)\n      - [Samples](#samples)\n      - [External resources](#external-resources-7)\n    + [Extends and super keywords](#extends-and-super-keywords)\n      - [Sample Code](#sample-code-6)\n      - [External Resources](#external-resources-8)\n    + [Async Await](#async-await)\n      - [Sample code](#sample-code-7)\n      - [Explanation with sample code](#explanation-with-sample-code-2)\n      - [Error handling](#error-handling)\n      - [External resources](#external-resources-9)\n    + [Truthy \u002F Falsy](#truthy--falsy)\n      - [External resources](#external-resources-10)\n    + [Anamorphisms \u002F Catamporphisms](#anamorphisms-and-catamorphisms)\n      - [Anamorphisms](#anamorphisms)\n      - [Catamorphisms](#catamorphisms)\n      - [External resources](#external-resources-11)\n    + [Generators](#generators)\n      - [External resources](#external-resources-12)\n    + [Static Methods](#static-methods)\n      - [Short Explanation](#short-explanation-1)\n      - [Sample Code](#sample-code-8)\n      - [Detailed Explanation](#detailed-explanation-2)\n        * [Calling other static methods from a static method](#calling-other-static-methods-from-a-static-method)\n        * [Calling static methods from non-static methods](#calling-static-methods-from-non-static-methods)\n      - [External resources](#external-resources-13)\n  * [Glossary](#glossary)\n    + [Scope](#-scope)\n    + [Variable mutation](#-variable-mutation)\n\n## Notions\n\n### Variable declaration: var, const, let\n\nIn JavaScript, there are three keywords available to declare a variable, and each has its differences. Those are ```var```, ```let``` and ```const```.\n\n#### Short explanation\n\nVariables declared with ```const``` keyword can't be reassigned, while ```let``` and ```var``` can.\n\nI recommend always declaring your variables with ```const``` by default, but with ```let``` if it is a variable that you need to *mutate* or reassign later.\n\n\u003Ctable>\n  \u003Ctr>\n    \u003Cth>\u003C\u002Fth>\n    \u003Cth>Scope\u003C\u002Fth>\n    \u003Cth>Reassignable\u003C\u002Fth>\n    \u003Cth>Mutable\u003C\u002Fth>\n   \u003Cth>\u003Ca href=\"#tdz_sample\">Temporal Dead Zone\u003C\u002Fa>\u003C\u002Fth>\n  \u003C\u002Ftr>\n  \u003Ctr>\n    \u003Cth>const\u003C\u002Fth>\n    \u003Ctd>Block\u003C\u002Ftd>\n    \u003Ctd>No\u003C\u002Ftd>\n    \u003Ctd>\u003Ca href=\"#const_mutable_sample\">Yes\u003C\u002Fa>\u003C\u002Ftd>\n    \u003Ctd>Yes\u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n    \u003Cth>let\u003C\u002Fth>\n    \u003Ctd>Block\u003C\u002Ftd>\n    \u003Ctd>Yes\u003C\u002Ftd>\n    \u003Ctd>Yes\u003C\u002Ftd>\n    \u003Ctd>Yes\u003C\u002Ftd>\n  \u003C\u002Ftr>\n   \u003Ctr>\n    \u003Cth>var\u003C\u002Fth>\n    \u003Ctd>Function\u003C\u002Ftd>\n    \u003Ctd>Yes\u003C\u002Ftd>\n    \u003Ctd>Yes\u003C\u002Ftd>\n    \u003Ctd>No\u003C\u002Ftd>\n  \u003C\u002Ftr>\n\u003C\u002Ftable>\n\n#### Sample code\n\n```javascript\nconst person = \"Nick\";\nperson = \"John\" \u002F\u002F Will raise an error, person can't be reassigned\n```\n\n```javascript\nlet person = \"Nick\";\nperson = \"John\";\nconsole.log(person) \u002F\u002F \"John\", reassignment is allowed with let\n```\n\n#### Detailed explanation\n\nThe [*scope*](#scope_def) of a variable roughly means \"where is this variable available in the code\".\n\n##### var\n\n```var``` declared variables are *function scoped*, meaning that when a variable is created in a function, everything in that function can access that variable. Besides, a *function scoped* variable created in a function can't be accessed outside this function.\n\nI recommend you to picture it as if an *X scoped* variable meant that this variable was a property of X.\n\n```javascript\nfunction myFunction() {\n  var myVar = \"Nick\";\n  console.log(myVar); \u002F\u002F \"Nick\" - myVar is accessible inside the function\n}\nconsole.log(myVar); \u002F\u002F Throws a ReferenceError, myVar is not accessible outside the function.\n```\n\nStill focusing on the variable scope, here is a more subtle example:\n\n```javascript\nfunction myFunction() {\n  var myVar = \"Nick\";\n  if (true) {\n    var myVar = \"John\";\n    console.log(myVar); \u002F\u002F \"John\"\n    \u002F\u002F actually, myVar being function scoped, we just erased the previous myVar value \"Nick\" for \"John\"\n  }\n  console.log(myVar); \u002F\u002F \"John\" - see how the instructions in the if block affected this value\n}\nconsole.log(myVar); \u002F\u002F Throws a ReferenceError, myVar is not accessible outside the function.\n```\n\nBesides, *var* declared variables are moved to the top of the scope at execution. This is what we call [var hoisting](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FStatements\u002Fvar#var_hoisting).\n\nThis portion of code:\n\n```js\nconsole.log(myVar) \u002F\u002F undefined -- no error raised\nvar myVar = 2;\n```\n\nis understood at execution like:\n\n```js\nvar myVar;\nconsole.log(myVar) \u002F\u002F undefined -- no error raised\nmyVar = 2;\n```\n\n##### let\n\n```var``` and ```let ``` are about the same, but ```let``` declared variables\n\n- are *block scoped*\n- are **not** accessible before they are assigned\n- can't be re-declared in the same scope\n\nLet's see the impact of block-scoping taking our previous example:\n\n```javascript\nfunction myFunction() {\n  let myVar = \"Nick\";\n  if (true) {\n    let myVar = \"John\";\n    console.log(myVar); \u002F\u002F \"John\"\n    \u002F\u002F actually, myVar being block scoped, we just created a new variable myVar.\n    \u002F\u002F this variable is not accessible outside this block and totally independent\n    \u002F\u002F from the first myVar created !\n  }\n  console.log(myVar); \u002F\u002F \"Nick\", see how the instructions in the if block DID NOT affect this value\n}\nconsole.log(myVar); \u002F\u002F Throws a ReferenceError, myVar is not accessible outside the function.\n```\n\n\u003Ca name=\"tdz_sample\">\u003C\u002Fa> Now, what it means for *let* (and *const*) variables for not being accessible before being assigned:\n\n```js\nconsole.log(myVar) \u002F\u002F raises a ReferenceError !\nlet myVar = 2;\n```\n\nBy contrast with *var* variables, if you try to read or write on a *let* or *const* variable before they are assigned an error will be raised. This phenomenon is often called [*Temporal dead zone*](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FStatements\u002Flet#Temporal_Dead_Zone_and_errors_with_let) or *TDZ*.\n\n> **Note:** Technically, *let* and *const* variables declarations are being hoisted too, but not their assignation. Since they're made so that they can't be used before assignation, it intuitively feels like there is no hoisting, but there is. Find out more on this [very detailed explanation here](http:\u002F\u002Fjsrocks.org\u002F2015\u002F01\u002Ftemporal-dead-zone-tdz-demystified) if you want to know more.\n\nIn addition, you can't re-declare a *let* variable:\n\n```js\nlet myVar = 2;\nlet myVar = 3; \u002F\u002F Raises a SyntaxError\n```\n\n##### const\n\n```const``` declared variables behave like *let* variables, but also they can't be reassigned.\n\nTo sum it up, *const* variables:\n\n- are *block scoped*\n- are not accessible before being assigned\n- can't be re-declared in the same scope\n- can't be reassigned\n\n```js\nconst myVar = \"Nick\";\nmyVar = \"John\" \u002F\u002F raises an error, reassignment is not allowed\n```\n\n```js\nconst myVar = \"Nick\";\nconst myVar = \"John\" \u002F\u002F raises an error, re-declaration is not allowed\n```\n\n\u003Ca name=\"const_mutable_sample\">\u003C\u002Fa> But there is a subtlety : ```const``` variables are not [**immutable**](#mutation_def) ! Concretely, it means that *object* and *array* ```const``` declared variables **can** be mutated.\n\nFor objects:\n```js\nconst person = {\n  name: 'Nick'\n};\nperson.name = 'John' \u002F\u002F this will work ! person variable is not completely reassigned, but mutated\nconsole.log(person.name) \u002F\u002F \"John\"\nperson = \"Sandra\" \u002F\u002F raises an error, because reassignment is not allowed with const declared variables\n```\n\nFor arrays:\n```js\nconst person = [];\nperson.push('John'); \u002F\u002F this will work ! person variable is not completely reassigned, but mutated\nconsole.log(person[0]) \u002F\u002F \"John\"\nperson = [\"Nick\"] \u002F\u002F raises an error, because reassignment is not allowed with const declared variables\n```\n\n#### External resource\n\n- [How let and const are scoped in JavaScript - WesBos](http:\u002F\u002Fwesbos.com\u002Fjavascript-scoping\u002F)\n- [Temporal Dead Zone (TDZ) Demystified](http:\u002F\u002Fjsrocks.org\u002F2015\u002F01\u002Ftemporal-dead-zone-tdz-demystified)\n\n### \u003Ca name=\"arrow_func_concept\">\u003C\u002Fa> Arrow function\n\nThe ES6 JavaScript update has introduced *arrow functions*, which is another way to declare and use functions. Here are the benefits they bring:\n\n- More concise\n- *this* is picked up from surroundings\n- implicit return\n\n#### Sample code\n\n- Concision and implicit return\n\n```js\nfunction double(x) { return x * 2; } \u002F\u002F Traditional way\nconsole.log(double(2)) \u002F\u002F 4\n```\n\n```js\nconst double = x => x * 2; \u002F\u002F Same function written as an arrow function with implicit return\nconsole.log(double(2)) \u002F\u002F 4\n```\n\n- *this* reference\n\nIn an arrow function, *this* is equal to the *this* value of the enclosing execution context. Basically, with arrow functions, you don't have to do the \"that = this\" trick before calling a function inside a function anymore.\n\n```js\nfunction myFunc() {\n  this.myVar = 0;\n  setTimeout(() => {\n    this.myVar++;\n    console.log(this.myVar) \u002F\u002F 1\n  }, 0);\n}\n```\n\n#### Detailed explanation\n\n##### Concision\n\nArrow functions are more concise than traditional functions in many ways. Let's review all the possible cases:\n\n- Implicit VS Explicit return\n\nAn **explicit return** is a function where the *return* keyword is used in its body.\n\n```js\n  function double(x) {\n    return x * 2; \u002F\u002F this function explicitly returns x * 2, *return* keyword is used\n  }\n```\n\nIn the traditional way of writing functions, the return was always explicit. But with arrow functions, you can do *implicit return* which means that you don't need to use the keyword *return* to return a value.\n\n```js\n  const double = (x) => {\n    return x * 2; \u002F\u002F Explicit return here\n  }\n```\n\nSince this function only returns something (no instructions before the *return* keyword) we can do an implicit return.\n\n```js\n  const double = (x) => x * 2; \u002F\u002F Correct, returns x*2\n```\n\nTo do so, we only need to **remove the brackets** and the **return** keyword. That's why it's called an *implicit* return, the *return* keyword is not there, but this function will indeed return ```x * 2```.\n\n> **Note:** If your function does not return a value (with *side effects*), it doesn't do an explicit nor an implicit return.\n\nBesides, if you want to implicitly return an *object* you **must have parentheses around it** since it will conflict with the block braces:\n\n```js\nconst getPerson = () => ({ name: \"Nick\", age: 24 })\nconsole.log(getPerson()) \u002F\u002F { name: \"Nick\", age: 24 } -- object implicitly returned by arrow function\n```\n\n- Only one argument\n\nIf your function only takes one parameter, you can omit the parentheses around it. If we take back the above *double* code:\n\n```js\n  const double = (x) => x * 2; \u002F\u002F this arrow function only takes one parameter\n```\n\nParentheses around the parameter can be avoided:\n\n```js\n  const double = x => x * 2; \u002F\u002F this arrow function only takes one parameter\n```\n\n- No arguments\n\nWhen there is no argument provided to an arrow function, you need to provide parentheses, or it won't be valid syntax.\n\n```js\n  () => { \u002F\u002F parentheses are provided, everything is fine\n    const x = 2;\n    return x;\n  }\n```\n\n```js\n  => { \u002F\u002F No parentheses, this won't work!\n    const x = 2;\n    return x;\n  }\n```\n\n##### *this* reference\n\nTo understand this subtlety introduced with arrow functions, you must know how [this](#this_def) behaves in JavaScript.\n\nIn an arrow function, *this* is equal to the *this* value of the enclosing execution context. What it means is that an arrow function doesn't create a new *this*, it grabs it from its surrounding instead.\n\nWithout arrow function, if you wanted to access a variable from *this* in a function inside a function, you had to use the *that = this* or *self = this* trick.\n\nFor instance, using setTimeout function inside myFunc:\n\n```js\nfunction myFunc() {\n  this.myVar = 0;\n  var that = this; \u002F\u002F that = this trick\n  setTimeout(\n    function() { \u002F\u002F A new *this* is created in this function scope\n      that.myVar++;\n      console.log(that.myVar) \u002F\u002F 1\n\n      console.log(this.myVar) \u002F\u002F undefined -- see function declaration above\n    },\n    0\n  );\n}\n```\n\nBut with arrow function, *this* is taken from its surrounding:\n\n```js\nfunction myFunc() {\n  this.myVar = 0;\n  setTimeout(\n    () => { \u002F\u002F this taken from surrounding, meaning myFunc here\n      this.myVar++;\n      console.log(this.myVar) \u002F\u002F 1\n    },\n    0\n  );\n}\n```\n\n#### Useful resources\n\n- [Arrow functions introduction - WesBos](http:\u002F\u002Fwesbos.com\u002Farrow-functions\u002F)\n- [JavaScript arrow function - MDN](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FFunctions\u002FArrow_functions)\n- [Arrow function and lexical *this*](https:\u002F\u002Fhackernoon.com\u002Fjavascript-es6-arrow-functions-and-lexical-this-f2a3e2a5e8c4)\n\n### Function default parameter value\n\nStarting from ES2015 JavaScript update, you can set default value to your function parameters using the following syntax:\n\n```js\nfunction myFunc(x = 10) {\n  return x;\n}\nconsole.log(myFunc()) \u002F\u002F 10 -- no value is provided so x default value 10 is assigned to x in myFunc\nconsole.log(myFunc(5)) \u002F\u002F 5 -- a value is provided so x is equal to 5 in myFunc\n\nconsole.log(myFunc(undefined)) \u002F\u002F 10 -- undefined value is provided so default value is assigned to x\nconsole.log(myFunc(null)) \u002F\u002F null -- a value (null) is provided, see below for more details\n```\n\nThe default parameter is applied in two and only two situations:\n\n- No parameter provided\n- *undefined* parameter provided\n\nIn other words, if you pass in *null* the default parameter **won't be applied**.\n\n> **Note:** Default value assignment can be used with destructured parameters as well (see next notion to see an example)\n\n#### External resource\n\n- [Default parameter value - ES6 Features](http:\u002F\u002Fes6-features.org\u002F#DefaultParameterValues)\n- [Default parameters - MDN](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FFunctions\u002FDefault_parameters)\n\n### Destructuring objects and arrays\n\n*Destructuring* is a convenient way of creating new variables by extracting some values from data stored in objects or arrays.\n\nTo name a few use cases, *destructuring* can be used to destructure function parameters or *this.props* in React projects for instance.\n\n#### Explanation with sample code\n\n- Object\n\nLet's consider the following object for all the samples:\n\n```js\nconst person = {\n  firstName: \"Nick\",\n  lastName: \"Anderson\",\n  age: 35,\n  sex: \"M\"\n}\n```\n\nWithout destructuring\n\n```js\nconst first = person.firstName;\nconst age = person.age;\nconst city = person.city || \"Paris\";\n```\n\nWith destructuring, all in one line:\n\n```js\nconst { firstName: first, age, city = \"Paris\" } = person; \u002F\u002F That's it !\n\nconsole.log(age) \u002F\u002F 35 -- A new variable age is created and is equal to person.age\nconsole.log(first) \u002F\u002F \"Nick\" -- A new variable first is created and is equal to person.firstName\nconsole.log(firstName) \u002F\u002F ReferenceError -- person.firstName exists BUT the new variable created is named first\nconsole.log(city) \u002F\u002F \"Paris\" -- A new variable city is created and since person.city is undefined, city is equal to the default value provided \"Paris\".\n```\n\n**Note :** In ```const { age } = person;```, the brackets after *const* keyword are not used to declare an object nor a block but is the *destructuring* syntax.\n\n- Function parameters\n\n*Destructuring* is often used to destructure objects parameters in functions.\n\nWithout destructuring\n\n```js\nfunction joinFirstLastName(person) {\n  const firstName = person.firstName;\n  const lastName = person.lastName;\n  return firstName + '-' + lastName;\n}\n\njoinFirstLastName(person); \u002F\u002F \"Nick-Anderson\"\n```\n\nIn destructuring the object parameter *person*, we get a more concise function:\n\n```js\nfunction joinFirstLastName({ firstName, lastName }) { \u002F\u002F we create firstName and lastName variables by destructuring person parameter\n  return firstName + '-' + lastName;\n}\n\njoinFirstLastName(person); \u002F\u002F \"Nick-Anderson\"\n```\n\nDestructuring is even more pleasant to use with [arrow functions](#arrow_func_concept):\n\n```js\nconst joinFirstLastName = ({ firstName, lastName }) => firstName + '-' + lastName;\n\njoinFirstLastName(person); \u002F\u002F \"Nick-Anderson\"\n```\n\n- Array\n\nLet's consider the following array:\n\n```js\nconst myArray = [\"a\", \"b\", \"c\"];\n```\n\nWithout destructuring\n\n```js\nconst x = myArray[0];\nconst y = myArray[1];\n```\n\nWith destructuring\n\n```js\nconst [x, y] = myArray; \u002F\u002F That's it !\n\nconsole.log(x) \u002F\u002F \"a\"\nconsole.log(y) \u002F\u002F \"b\"\n```\n\n#### Useful resources\n\n- [ES6 Features - Destructuring Assignment](http:\u002F\u002Fes6-features.org\u002F#ArrayMatching)\n- [Destructuring Objects - WesBos](http:\u002F\u002Fwesbos.com\u002Fdestructuring-objects\u002F)\n- [ExploringJS - Destructuring](http:\u002F\u002Fexploringjs.com\u002Fes6\u002Fch_destructuring.html)\n\n### Array methods - map \u002F filter \u002F reduce \u002F find\n\n*Map*, *filter*, *reduce* and *find* are array methods that are coming from a programming paradigm named [*functional programming*](https:\u002F\u002Fmedium.com\u002Fjavascript-scene\u002Fmaster-the-javascript-interview-what-is-functional-programming-7f218c68b3a0).\n\nTo sum it up:\n\n- **Array.prototype.map()** takes an array, does something on its elements and returns an array with the transformed elements.\n- **Array.prototype.filter()** takes an array, decides element by element if it should keep it or not and returns an array with the kept elements only\n- **Array.prototype.reduce()** takes an array and aggregates the elements into a single value (which is returned)\n- **Array.prototype.find()** takes an array, and returns the first element that satisfies the provided condition.\n\nI recommend to use them as much as possible in following the principles of functional programming because they are composable, concise and elegant.\n\nWith those four methods, you can avoid the use of *for* and *forEach* loops in most situations. When you are tempted to do a *for* loop, try to do it with *map*, *filter*, *reduce* and *find* composed. You might struggle to do it at first because it requires you to learn a new way of thinking, but once you've got it things get easier.\n\n#### Sample code\n\n```js\nconst numbers = [0, 1, 2, 3, 4, 5, 6];\nconst doubledNumbers = numbers.map(n => n * 2); \u002F\u002F [0, 2, 4, 6, 8, 10, 12]\nconst evenNumbers = numbers.filter(n => n % 2 === 0); \u002F\u002F [0, 2, 4, 6]\nconst sum = numbers.reduce((prev, next) => prev + next, 0); \u002F\u002F 21\nconst greaterThanFour = numbers.find((n) => n>4); \u002F\u002F 5\n```\n\nCompute total grade sum for students with grades 10 or above by composing map, filter and reduce:\n\n```js\nconst students = [\n  { name: \"Nick\", grade: 10 },\n  { name: \"John\", grade: 15 },\n  { name: \"Julia\", grade: 19 },\n  { name: \"Nathalie\", grade: 9 },\n];\n\nconst aboveTenSum = students\n  .map(student => student.grade) \u002F\u002F we map the students array to an array of their grades\n  .filter(grade => grade >= 10) \u002F\u002F we filter the grades array to keep those 10 or above\n  .reduce((prev, next) => prev + next, 0); \u002F\u002F we sum all the grades 10 or above one by one\n\nconsole.log(aboveTenSum) \u002F\u002F 44 -- 10 (Nick) + 15 (John) + 19 (Julia), Nathalie below 10 is ignored\n```\n\n#### Explanation\n\nLet's consider the following array of numbers for our examples:\n\n```js\nconst numbers = [0, 1, 2, 3, 4, 5, 6];\n```\n\n##### Array.prototype.map()\n\n```js\nconst doubledNumbers = numbers.map(function(n) {\n  return n * 2;\n});\nconsole.log(doubledNumbers); \u002F\u002F [0, 2, 4, 6, 8, 10, 12]\n```\n\nWhat's happening here? We are using .map on the *numbers* array, the map is iterating on each element of the array and passes it to our function. The goal of the function is to produce and return a new value from the one passed so that map can replace it.\n\nLet's extract this function to make it more clear, just for this once:\n\n```js\nconst doubleN = function(n) { return n * 2; };\nconst doubledNumbers = numbers.map(doubleN);\nconsole.log(doubledNumbers); \u002F\u002F [0, 2, 4, 6, 8, 10, 12]\n```\n\n**Note** : You will frequently encounter this method used in combination with [arrow functions](#-arrow-function)\n\n```js\nconst doubledNumbers = numbers.map(n => n * 2);\nconsole.log(doubledNumbers); \u002F\u002F [0, 2, 4, 6, 8, 10, 12]\n```\n\n```numbers.map(doubleN)``` produces ```[doubleN(0), doubleN(1), doubleN(2), doubleN(3), doubleN(4), doubleN(5), doubleN(6)]``` which is equal to ```[0, 2, 4, 6, 8, 10, 12]```.\n\n> **Note:** If you do not need to return a new array and just want to do a loop that has side effects, you might just want to use a for \u002F forEach loop instead of a map.\n\n##### Array.prototype.filter()\n\n```js\nconst evenNumbers = numbers.filter(function(n) {\n  return n % 2 === 0; \u002F\u002F true if \"n\" is par, false if \"n\" isn't\n});\nconsole.log(evenNumbers); \u002F\u002F [0, 2, 4, 6]\n```\n\n**Note** : You will frequently encounter this method used in combination with [arrow functions](#-arrow-function)\n\n```js\nconst evenNumbers = numbers.filter(n => n % 2 === 0);\nconsole.log(evenNumbers); \u002F\u002F [0, 2, 4, 6]\n```\n\nWe are using .filter on the *numbers* array, filter is iterating on each element of the array and passes it to our function. The goal of the function is to return a boolean that will determine whether the current value will be kept or not. Filter then returns the array with only the kept values.\n\n##### Array.prototype.reduce()\n\nThe reduce method goal is to *reduce* all elements of the array it iterates on into a single value. How it aggregates those elements is up to you.\n\n```js\nconst sum = numbers.reduce(\n  function(acc, n) {\n    return acc + n;\n  },\n  0 \u002F\u002F accumulator variable value at first iteration step\n);\n\nconsole.log(sum) \u002F\u002F 21\n```\n\n**Note** : You will frequently encounter this method used in combination with [arrow functions](#-arrow-function)\n\n```js\nconst sum = numbers.reduce((acc, n) => acc + n, 0);\nconsole.log(sum) \u002F\u002F 21\n```\n\nJust like for .map and .filter methods, .reduce is applied on an array and takes a function as the first parameter.\n\nThis time though, there are changes:\n\n- .reduce takes two parameters\n\nThe first parameter is a function that will be called at each iteration step.\n\nThe second parameter is the value of the accumulator variable (*acc* here) at the first iteration step (read next point to understand).\n\n- Function parameters\n\nThe function you pass as the first parameter of .reduce takes two parameters. The first one (*acc* here) is the accumulator variable, whereas the second parameter (*n*) is the current element.\n\nThe accumulator variable is equal to the return value of your function at the **previous** iteration step. At the first step of the iteration, *acc* is equal to the value you passed as .reduce second parameter.\n\n###### At first iteration step\n\n```acc = 0``` because we passed in 0 as the second parameter for reduce\n\n```n = 0``` first element of the *number* array\n\nFunction returns *acc* + *n* --> 0 + 0 --> 0\n\n###### At second iteration step\n\n```acc = 0``` because it's the value the function returned at the previous iteration step\n\n```n = 1``` second element of the *number* array\n\nFunction returns *acc* + *n* --> 0 + 1 --> 1\n\n###### At third iteration step\n\n```acc = 1``` because it's the value the function returned at the previous iteration step\n\n```n = 2``` third element of the *number* array\n\nFunction returns *acc* + *n* --> 1 + 2 --> 3\n\n###### At fourth iteration step\n\n```acc = 3``` because it's the value the function returned at the previous iteration step\n\n```n = 3``` fourth element of the *number* array\n\nFunction returns *acc* + *n* --> 3 + 3 --> 6\n\n###### [...] At last iteration step\n\n```acc = 15``` because it's the value the function returned at the previous iteration step\n\n```n = 6``` last element of the *number* array\n\nFunction returns *acc* + *n* --> 15 + 6 --> 21\n\nAs it is the last iteration step, **.reduce** returns 21.\n\n##### Array.prototype.find()\n\n```js\nconst greaterThanZero = numbers.find(function(n) {\n  return n > 0; \u002F\u002F return number just greater than 0 is present\n});\nconsole.log(greaterThanZero); \u002F\u002F 1\n```\n\n**Note** : You will frequently encounter this method used in combination with [arrow functions](#-arrow-function)\n\nWe are using .find on the *numbers* array, .find is iterating on each element of the array and passes it to our function, until the condition is met. The goal of the function is to return the element that satisfies the current testing function. The .find method executes the callback function once for each index of the array until the callback returns a truthy value.\n\n**Note** : It immediately returns the value of that element (that satisfies the condition) if found. Otherwise, returns undefined.\n\n#### External Resource\n\n- [Understanding map \u002F filter \u002F reduce in JS](https:\u002F\u002Fhackernoon.com\u002Funderstanding-map-filter-and-reduce-in-javascript-5df1c7eee464)\n\n### Spread operator \"...\"\n\nThe spread operator ```...``` has been introduced with ES2015 and is used to expand elements of an iterable (like an array) into places where multiple elements can fit.\n\n#### Sample code\n\n```js\nconst arr1 = [\"a\", \"b\", \"c\"];\nconst arr2 = [...arr1, \"d\", \"e\", \"f\"]; \u002F\u002F [\"a\", \"b\", \"c\", \"d\", \"e\", \"f\"]\n```\n\n```js\nfunction myFunc(x, y, ...params) {\n  console.log(x);\n  console.log(y);\n  console.log(params)\n}\n\nmyFunc(\"a\", \"b\", \"c\", \"d\", \"e\", \"f\")\n\u002F\u002F \"a\"\n\u002F\u002F \"b\"\n\u002F\u002F [\"c\", \"d\", \"e\", \"f\"]\n```\n\n```js\nconst { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };\nconsole.log(x); \u002F\u002F 1\nconsole.log(y); \u002F\u002F 2\nconsole.log(z); \u002F\u002F { a: 3, b: 4 }\n\nconst n = { x, y, ...z };\nconsole.log(n); \u002F\u002F { x: 1, y: 2, a: 3, b: 4 }\n```\n\n#### Explanation\n\n##### In iterables (like arrays)\n\nIf we have the two following arrays:\n\n```js\nconst arr1 = [\"a\", \"b\", \"c\"];\nconst arr2 = [arr1, \"d\", \"e\", \"f\"]; \u002F\u002F [[\"a\", \"b\", \"c\"], \"d\", \"e\", \"f\"]\n```\n\n*arr2* the first element is an array because *arr1* is injected as is into *arr2*. But what we want is *arr2* to be an array of letters. To do so, we can *spread* the elements of *arr1* into *arr2*.\n\nWith spread operator\n\n```js\nconst arr1 = [\"a\", \"b\", \"c\"];\nconst arr2 = [...arr1, \"d\", \"e\", \"f\"]; \u002F\u002F [\"a\", \"b\", \"c\", \"d\", \"e\", \"f\"]\n```\n\n##### Function rest parameter\n\nIn function parameters, we can use the rest operator to inject parameters into an array we can loop in. There is already an **arguments** object bound to every function that is equal to an array of all the parameters passed into the function.\n\n```js\nfunction myFunc() {\n  for (var i = 0; i \u003C arguments.length; i++) {\n    console.log(arguments[i]);\n  }\n}\n\nmyFunc(\"Nick\", \"Anderson\", 10, 12, 6);\n\u002F\u002F \"Nick\"\n\u002F\u002F \"Anderson\"\n\u002F\u002F 10\n\u002F\u002F 12\n\u002F\u002F 6\n```\n\nBut let's say that we want this function to create a new student with its grades and with its average grade. Wouldn't it be more convenient to extract the first two parameters into two separate variables, and then have all the grades in an array we can iterate over?\n\nThat's exactly what the rest operator allows us to do!\n\n```js\nfunction createStudent(firstName, lastName, ...grades) {\n  \u002F\u002F firstName = \"Nick\"\n  \u002F\u002F lastName = \"Anderson\"\n  \u002F\u002F [10, 12, 6] -- \"...\" takes all other parameters passed and creates a \"grades\" array variable that contains them\n\n  const avgGrade = grades.reduce((acc, curr) => acc + curr, 0) \u002F grades.length; \u002F\u002F computes average grade from grades\n\n  return {\n    firstName: firstName,\n    lastName: lastName,\n    grades: grades,\n    avgGrade: avgGrade\n  }\n}\n\nconst student = createStudent(\"Nick\", \"Anderson\", 10, 12, 6);\nconsole.log(student);\n\u002F\u002F {\n\u002F\u002F   firstName: \"Nick\",\n\u002F\u002F   lastName: \"Anderson\",\n\u002F\u002F   grades: [10, 12, 6],\n\u002F\u002F   avgGrade: 9,33\n\u002F\u002F }\n```\n\n> **Note:** createStudent function is bad because we don't check if grades.length exists or is different from 0. But it's easier to read this way, so I didn't handle this case.\n\n##### Object properties spreading\n\nFor this one, I recommend you read previous explanations about the rest operator on iterables and function parameters.\n\n```js\nconst myObj = { x: 1, y: 2, a: 3, b: 4 };\nconst { x, y, ...z } = myObj; \u002F\u002F object destructuring here\nconsole.log(x); \u002F\u002F 1\nconsole.log(y); \u002F\u002F 2\nconsole.log(z); \u002F\u002F { a: 3, b: 4 }\n\n\u002F\u002F z is the rest of the object destructured: myObj object minus x and y properties destructured\n\nconst n = { x, y, ...z };\nconsole.log(n); \u002F\u002F { x: 1, y: 2, a: 3, b: 4 }\n\n\u002F\u002F Here z object properties are spread into n\n```\n\n#### External resources\n\n- [TC39 - Object rest\u002Fspread](https:\u002F\u002Fgithub.com\u002Ftc39\u002Fproposal-object-rest-spread)\n- [Spread operator introduction - WesBos](https:\u002F\u002Fgithub.com\u002Fwesbos\u002Fes6-articles\u002Fblob\u002Fmaster\u002F28%20-%20Spread%20Operator%20Introduction.md)\n- [JavaScript & the spread operator](https:\u002F\u002Fcodeburst.io\u002Fjavascript-the-spread-operator-a867a71668ca)\n- [6 Great uses of the spread operator](https:\u002F\u002Fdavidwalsh.name\u002Fspread-operator)\n\n### Object property shorthand\n\nWhen assigning a variable to an object property, if the variable name is equal to the property name, you can do the following:\n\n```js\nconst x = 10;\nconst myObj = { x };\nconsole.log(myObj.x) \u002F\u002F 10\n```\n\n#### Explanation\n\nUsually (pre-ES2015) when you declare a new *object literal* and want to use variables as object properties values, you would write this kind of code:\n\n```js\nconst x = 10;\nconst y = 20;\n\nconst myObj = {\n  x: x, \u002F\u002F assigning x variable value to myObj.x\n  y: y \u002F\u002F assigning y variable value to myObj.y\n};\n\nconsole.log(myObj.x) \u002F\u002F 10\nconsole.log(myObj.y) \u002F\u002F 20\n```\n\nAs you can see, this is quite repetitive because the properties name of myObj are the same as the variable names you want to assign to those properties.\n\nWith ES2015, when the variable name is the same as the property name, you can do this shorthand:\n\n```js\nconst x = 10;\nconst y = 20;\n\nconst myObj = {\n  x,\n  y\n};\n\nconsole.log(myObj.x) \u002F\u002F 10\nconsole.log(myObj.y) \u002F\u002F 20\n```\n\n#### External resources\n\n- [Property shorthand - ES6 Features](http:\u002F\u002Fes6-features.org\u002F#PropertyShorthand)\n\n### Promises\n\nA promise is an object which can be returned synchronously from an asynchronous function ([ref](https:\u002F\u002Fmedium.com\u002Fjavascript-scene\u002Fmaster-the-javascript-interview-what-is-a-promise-27fc71e77261#3cd0)).\n\nPromises can be used to avoid [callback hell](http:\u002F\u002Fcallbackhell.com\u002F), and they are more and more frequently encountered in modern JavaScript projects.\n\n#### Sample code\n\n```js\nconst fetchingPosts = new Promise((res, rej) => {\n  $.get(\"\u002Fposts\")\n    .done(posts => res(posts))\n    .fail(err => rej(err));\n});\n\nfetchingPosts\n  .then(posts => console.log(posts))\n  .catch(err => console.log(err));\n```\n\n#### Explanation\n\nWhen you do an *Ajax request* the response is not synchronous because you want a resource that takes some time to come. It even may never come if the resource you have requested is unavailable for some reason (404).\n\nTo handle that kind of situation, ES2015 has given us *promises*. Promises can have three different states:\n\n- Pending\n- Fulfilled\n- Rejected\n\nLet's say we want to use promises to handle an Ajax request to fetch the resource X.\n\n##### Create the promise\n\nWe firstly are going to create a promise. We will use the jQuery get method to do our Ajax request to X.\n\n```js\nconst xFetcherPromise = new Promise( \u002F\u002F Create promise using \"new\" keyword and store it into a variable\n  function(resolve, reject) { \u002F\u002F Promise constructor takes a function parameter which has resolve and reject parameters itself\n    $.get(\"X\") \u002F\u002F Launch the Ajax request\n      .done(function(X) { \u002F\u002F Once the request is done...\n        resolve(X); \u002F\u002F ... resolve the promise with the X value as parameter\n      })\n      .fail(function(error) { \u002F\u002F If the request has failed...\n        reject(error); \u002F\u002F ... reject the promise with the error as parameter\n      });\n  }\n)\n```\n\nAs seen in the above sample, the Promise object takes an *executor* function which takes two parameters **resolve** and **reject**. Those parameters are functions which when called are going to move the promise *pending* state to respectively a *fulfilled* and *rejected* state.\n\nThe promise is in pending state after instance creation and its *executor* function is executed immediately. Once one of the function *resolve* or *reject* is called in the *executor* function, the promise will call its associated handlers.\n\n##### Promise handlers usage\n\nTo get the promise result (or error), we must attach to it handlers by doing the following:\n\n```js\nxFetcherPromise\n  .then(function(X) {\n    console.log(X);\n  })\n  .catch(function(err) {\n    console.log(err)\n  })\n```\n\nIf the promise succeeds, *resolve* is executed and the function passed as ```.then``` parameter is executed.\n\nIf it fails, *reject* is executed and the function passed as ```.catch``` parameter is executed.\n\n> **Note :** If the promise has already been fulfilled or rejected when a corresponding handler is attached, the handler will be called, so there is no race condition between an asynchronous operation completing and its handlers being attached. [(Ref: MDN)](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FGlobal_Objects\u002FPromise#Description)\n\n#### External Resources\n\n- [JavaScript Promises for dummies - Jecelyn Yeen](https:\u002F\u002Fscotch.io\u002Ftutorials\u002Fjavascript-promises-for-dummies)\n- [JavaScript Promise API - David Walsh](https:\u002F\u002Fdavidwalsh.name\u002Fpromises)\n- [Using promises - MDN](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FJavaScript\u002FGuide\u002FUsing_promises)\n- [What is a promise - Eric Elliott](https:\u002F\u002Fmedium.com\u002Fjavascript-scene\u002Fmaster-the-javascript-interview-what-is-a-promise-27fc71e77261)\n- [JavaScript Promises: an Introduction - Jake Archibald](https:\u002F\u002Fdevelopers.google.com\u002Fweb\u002Ffundamentals\u002Fgetting-started\u002Fprimers\u002Fpromises)\n- [Promise documentation - MDN](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FGlobal_Objects\u002FPromise)\n\n### Template literals\n\nTemplate literals is an [*expression interpolation*](https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FString_interpolation) for single and multiple-line strings.\n\nIn other words, it is a new string syntax in which you can conveniently use any JavaScript expressions (variables for instance).\n\n#### Sample code\n\n```js\nconst name = \"Nick\";\n`Hello ${name}, the following expression is equal to four : ${2+2}`;\n\n\u002F\u002F Hello Nick, the following expression is equal to four: 4\n```\n\n#### External resources\n\n- [String interpolation - ES6 Features](http:\u002F\u002Fes6-features.org\u002F#StringInterpolation)\n- [ES6 Template Strings - Addy Osmani](https:\u002F\u002Fdevelopers.google.com\u002Fweb\u002Fupdates\u002F2015\u002F01\u002FES6-Template-Strings)\n\n### Tagged template literals\n\nTemplate tags are *functions that can be prefixed to a [template literal](#template-literals)*. When a function is called this way, the first parameter is an array of the *strings* that appear between the template's interpolated variables, and the subsequent parameters are the interpolated values. Use a spread operator `...` to capture all of them. [(Ref: MDN)](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FTemplate_literals#Tagged_template_literals).\n\n> **Note :** A famous library named [styled-components](https:\u002F\u002Fwww.styled-components.com\u002F) heavily relies on this feature.\n\nBelow is a toy example on how they work.\n```js\nfunction highlight(strings, ...values) {\n  const interpolation = strings.reduce((prev, current) => {\n    return prev + current + (values.length ? \"\u003Cmark>\" + values.shift() + \"\u003C\u002Fmark>\" : \"\");\n  }, \"\");\n\n  return interpolation;\n}\n\nconst condiment = \"jam\";\nconst meal = \"toast\";\n\nhighlight`I like ${condiment} on ${meal}.`;\n\u002F\u002F \"I like \u003Cmark>jam\u003C\u002Fmark> on \u003Cmark>toast\u003C\u002Fmark>.\"\n```\n\nA more interesting example:\n```js\nfunction comma(strings, ...values) {\n  return strings.reduce((prev, next) => {\n    let value = values.shift() || [];\n    value = value.join(\", \");\n    return prev + next + value;\n  }, \"\");\n}\n\nconst snacks = ['apples', 'bananas', 'cherries'];\ncomma`I like ${snacks} to snack on.`;\n\u002F\u002F \"I like apples, bananas, cherries to snack on.\"\n```\n\n#### External resources\n- [Wes Bos on Tagged Template Literals](http:\u002F\u002Fwesbos.com\u002Ftagged-template-literals\u002F)\n- [Library of common template tags](https:\u002F\u002Fgithub.com\u002Fdeclandewet\u002Fcommon-tags)\n\n### Imports \u002F Exports\n\nES6 modules are used to access variables or functions in a module explicitly exported by the modules it imports.\n\nI highly recommend to take a look at MDN resources on import\u002Fexport (see external resources below), it is both straightforward and complete.\n\n#### Explanation with sample code\n\n##### Named exports\n\nNamed exports are used to export several values from a module.\n\n> **Note :** You can only name-export [first-class citizens](https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FFirst-class_citizen) that have a name.\n\n```js\n\u002F\u002F mathConstants.js\nexport const pi = 3.14;\nexport const exp = 2.7;\nexport const alpha = 0.35;\n\n\u002F\u002F -------------\n\n\u002F\u002F myFile.js\nimport { pi, exp } from '.\u002FmathConstants.js'; \u002F\u002F Named import -- destructuring-like syntax\nconsole.log(pi) \u002F\u002F 3.14\nconsole.log(exp) \u002F\u002F 2.7\n\n\u002F\u002F -------------\n\n\u002F\u002F mySecondFile.js\nimport * as constants from '.\u002FmathConstants.js'; \u002F\u002F Inject all exported values into constants variable\nconsole.log(constants.pi) \u002F\u002F 3.14\nconsole.log(constants.exp) \u002F\u002F 2.7\n```\n\nWhile named imports looks like *destructuring*, they have a different syntax and are not the same. They don't support default values nor *deep* destructuring.\n\nBesides, you can do aliases but the syntax is different from the one used in destructuring:\n\n```js\nimport { foo as bar } from 'myFile.js'; \u002F\u002F foo is imported and injected into a new bar variable\n```\n\n##### Default import \u002F export\n\nConcerning the default export, there is only a single default export per module. A default export can be a function, a class, an object or anything else. This value is considered the \"main\" exported value since it will be the simplest to import. [Ref: MDN](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FStatements\u002Fexport#Description)\n\n```js\n\u002F\u002F coolNumber.js\nconst ultimateNumber = 42;\nexport default ultimateNumber;\n\n\u002F\u002F ------------\n\n\u002F\u002F myFile.js\nimport number from '.\u002FcoolNumber.js';\n\u002F\u002F Default export, independently from its name, is automatically injected into number variable;\nconsole.log(number) \u002F\u002F 42\n```\n\nFunction exporting:\n\n```js\n\u002F\u002F sum.js\nexport default function sum(x, y) {\n  return x + y;\n}\n\u002F\u002F -------------\n\n\u002F\u002F myFile.js\nimport sum from '.\u002Fsum.js';\nconst result = sum(1, 2);\nconsole.log(result) \u002F\u002F 3\n```\n\n#### External resources\n\n- [ES6 Modules in bulletpoints](https:\u002F\u002Fponyfoo.com\u002Farticles\u002Fes6#modules)\n- [Export - MDN](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FStatements\u002Fexport)\n- [Import - MDN](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FStatements\u002Fimport)\n- [Understanding ES6 Modules](https:\u002F\u002Fwww.sitepoint.com\u002Funderstanding-es6-modules\u002F)\n- [Destructuring special case - import statements](https:\u002F\u002Fponyfoo.com\u002Farticles\u002Fes6-destructuring-in-depth#special-case-import-statements)\n- [Misunderstanding ES6 Modules - Kent C. Dodds](https:\u002F\u002Fmedium.com\u002F@kentcdodds\u002Fmisunderstanding-es6-modules-upgrading-babel-tears-and-a-solution-ad2d5ab93ce0)\n- [Modules in JavaScript](http:\u002F\u002Fexploringjs.com\u002Fes6\u002Fch_modules.html#sec_modules-in-javascript)\n\n### \u003Ca name=\"this_def\">\u003C\u002Fa> JavaScript *this*\n\n*this* operator behaves differently than in other languages and is in most cases determined by how a function is called. ([Ref: MDN](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FOperators\u002Fthis)).\n\nThis notion is having many subtleties and being quite hard, I highly suggest you to deep dive in the external resources below. Thus, I will provide what I personally have in mind to determine what *this* is equal to. I have learned this tip from [this article written by Yehuda Katz](http:\u002F\u002Fyehudakatz.com\u002F2011\u002F08\u002F11\u002Funderstanding-javascript-function-invocation-and-this\u002F).\n\n```js\nfunction myFunc() {\n  ...\n}\n\n\u002F\u002F After each statement, you find the value of *this* in myFunc\n\nmyFunc.call(\"myString\", \"hello\") \u002F\u002F \"myString\" -- first .call parameter value is injected into *this*\n\n\u002F\u002F In non-strict-mode\nmyFunc(\"hello\") \u002F\u002F window -- myFunc() is syntax sugar for myFunc.call(window, \"hello\")\n\n\u002F\u002F In strict-mode\nmyFunc(\"hello\") \u002F\u002F undefined -- myFunc() is syntax sugar for myFunc.call(undefined, \"hello\")\n```\n\n```js\nvar person = {\n  myFunc: function() { ... }\n}\n\nperson.myFunc.call(person, \"test\") \u002F\u002F person Object -- first call parameter is injected into *this*\nperson.myFunc(\"test\") \u002F\u002F person Object -- person.myFunc() is syntax sugar for person.myFunc.call(person, \"test\")\n\nvar myBoundFunc = person.myFunc.bind(\"hello\") \u002F\u002F Creates a new function in which we inject \"hello\" in *this* value\nperson.myFunc(\"test\") \u002F\u002F person Object -- The bind method has no effect on the original method\nmyBoundFunc(\"test\") \u002F\u002F \"hello\" -- myBoundFunc is person.myFunc with \"hello\" bound to *this*\n```\n\n#### External resources\n\n- [Understanding JavaScript Function Invocation and \"this\" - Yehuda Katz](http:\u002F\u002Fyehudakatz.com\u002F2011\u002F08\u002F11\u002Funderstanding-javascript-function-invocation-and-this\u002F)\n- [JavaScript this - MDN](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FOperators\u002Fthis)\n\n### Class\n\nJavaScript is a [prototype-based](https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FPrototype-based_programming) language (whereas Java is [class-based](https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FClass-based_programming) language, for instance). ES6 has introduced JavaScript classes which are meant to be a syntactic sugar for prototype-based inheritance and **not** a new class-based inheritance model ([ref](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FClasses)).\n\nThe word *class* is indeed error prone if you are familiar with classes in other languages. If you do, avoid assuming how JavaScript classes work on this basis and consider it an entirely different notion.\n\nSince this document is not an attempt to teach you the language from the ground up, I will assume you know what prototypes are and how they behave. If you do not, see the external resources listed below the sample code.\n\n#### Samples\n\nBefore ES6, prototype syntax:\n\n```js\nvar Person = function(name, age) {\n  this.name = name;\n  this.age = age;\n}\nPerson.prototype.stringSentence = function() {\n  return \"Hello, my name is \" + this.name + \" and I'm \" + this.age;\n}\n```\n\nWith ES6 class syntax:\n\n```js\nclass Person {\n  constructor(name, age) {\n    this.name = name;\n    this.age = age;\n  }\n\n  stringSentence() {\n    return `Hello, my name is ${this.name} and I am ${this.age}`;\n  }\n}\n\nconst myPerson = new Person(\"Manu\", 23);\nconsole.log(myPerson.age) \u002F\u002F 23\nconsole.log(myPerson.stringSentence()) \u002F\u002F \"Hello, my name is Manu and I'm 23\n```\n\n#### External resources\n\nFor prototype understanding:\n\n- [Understanding Prototypes in JS - Yehuda Katz](http:\u002F\u002Fyehudakatz.com\u002F2011\u002F08\u002F12\u002Funderstanding-prototypes-in-javascript\u002F)\n- [A plain English guide to JS prototypes - Sebastian Porto](http:\u002F\u002Fsporto.github.io\u002Fblog\u002F2013\u002F02\u002F22\u002Fa-plain-english-guide-to-javascript-prototypes\u002F)\n- [Inheritance and the prototype chain - MDN](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FJavaScript\u002FInheritance_and_the_prototype_chain)\n\nFor classes understanding:\n\n- [ES6 Classes in Depth - Nicolas Bevacqua](https:\u002F\u002Fponyfoo.com\u002Farticles\u002Fes6-classes-in-depth)\n- [ES6 Features - Classes](http:\u002F\u002Fes6-features.org\u002F#ClassDefinition)\n- [JavaScript Classes - MDN](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FClasses)\n\n### `Extends` and `super` keywords\n\nThe `extends` keyword is used in class declarations or class expressions to create a class which is a child of another class ([Ref: MDN](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FClasses\u002Fextends)). The subclass inherits all the properties of the superclass and additionally can add new properties or modify the inherited ones.\n\nThe `super` keyword is used to call functions on an object's parent, including its constructor.\n\n- `super` keyword must be used before the `this` keyword is used in constructor\n- Invoking `super()` calls the parent class constructor. If you want to pass some arguments in a class's constructor to its parent's constructor, you call it with `super(arguments)`.\n- If the parent class have a method (even static) called `X`, you can use `super.X()` to call it in a child class.\n\n#### Sample Code\n\n```js\nclass Polygon {\n  constructor(height, width) {\n    this.name = 'Polygon';\n    this.height = height;\n    this.width = width;\n  }\n\n  getHelloPhrase() {\n    return `Hi, I am a ${this.name}`;\n  }\n}\n\nclass Square extends Polygon {\n  constructor(length) {\n    \u002F\u002F Here, it calls the parent class' constructor with lengths\n    \u002F\u002F provided for the Polygon's width and height\n    super(length, length);\n    \u002F\u002F Note: In derived classes, super() must be called before you\n    \u002F\u002F can use 'this'. Leaving this out will cause a reference error.\n    this.name = 'Square';\n    this.length = length;\n  }\n\n  getCustomHelloPhrase() {\n    const polygonPhrase = super.getHelloPhrase(); \u002F\u002F accessing parent method with super.X() syntax\n    return `${polygonPhrase} with a length of ${this.length}`;\n  }\n\n  get area() {\n    return this.height * this.width;\n  }\n}\n\nconst mySquare = new Square(10);\nconsole.log(mySquare.area) \u002F\u002F 100\nconsole.log(mySquare.getHelloPhrase()) \u002F\u002F 'Hi, I am a Square' -- Square inherits from Polygon and has access to its methods\nconsole.log(mySquare.getCustomHelloPhrase()) \u002F\u002F 'Hi, I am a Square with a length of 10'\n```\n\n**Note :** If we had tried to use `this` before calling `super()` in Square class, a ReferenceError would have been raised:\n\n```js\nclass Square extends Polygon {\n  constructor(length) {\n    this.height; \u002F\u002F ReferenceError, super needs to be called first!\n\n    \u002F\u002F Here, it calls the parent class' constructor with lengths\n    \u002F\u002F provided for the Polygon's width and height\n    super(length, length);\n\n    \u002F\u002F Note: In derived classes, super() must be called before you\n    \u002F\u002F can use 'this'. Leaving this out will cause a reference error.\n    this.name = 'Square';\n  }\n}\n```\n\n#### External Resources\n\n- [Extends - MDN](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FClasses\u002Fextends)\n- [Super operator - MDN](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FOperators\u002Fsuper)\n- [Inheritance - MDN](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FLearn\u002FJavaScript\u002FObjects\u002FInheritance)\n\n### Async Await\n\nIn addition to [Promises](#promises), there is a new syntax you might encounter to handle asynchronous code named *async \u002F await*.\n\nThe purpose of async\u002Fawait functions is to simplify the behavior of using promises synchronously and to perform some behavior on a group of Promises. Just as Promises are similar to structured callbacks, async\u002Fawait is similar to combining generators and promises. Async functions *always* return a Promise. ([Ref: MDN](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FStatements\u002Fasync_function))\n\n> **Note :** You must understand what promises are and how they work before trying to understand async \u002F await since they rely on it.\n\n> **Note 2:** [*await* must be used in an *async* function](https:\u002F\u002Fhackernoon.com\u002F6-reasons-why-javascripts-async-await-blows-promises-away-tutorial-c7ec10518dd9#f3f0), which means that you can't use await in the top level of our code since that is not inside an async function.\n\n#### Sample code\n\n```js\nasync function getGithubUser(username) { \u002F\u002F async keyword allows usage of await in the function and means function returns a promise\n  const response = await fetch(`https:\u002F\u002Fapi.github.com\u002Fusers\u002F${username}`); \u002F\u002F Execution is paused here until the Promise returned by fetch is resolved\n  return response.json();\n}\n\ngetGithubUser('mbeaudru')\n  .then(user => console.log(user)) \u002F\u002F logging user response - cannot use await syntax since this code isn't in async function\n  .catch(err => console.log(err)); \u002F\u002F if an error is thrown in our async function, we will catch it here\n```\n\n#### Explanation with sample code\n\n*Async \u002F Await* is built on promises but they allow a more imperative style of code.\n\nThe *async* operator marks a function as asynchronous and will always return a *Promise*. You can use the *await* operator in an *async* function to pause execution on that line until the returned Promise from the expression either resolves or rejects.\n\n```js\nasync function myFunc() {\n  \u002F\u002F we can use await operator because this function is async\n  return \"hello world\";\n}\n\nmyFunc().then(msg => console.log(msg)) \u002F\u002F \"hello world\" -- myFunc's return value is turned into a promise because of async operator\n```\n\nWhen the *return* statement of an async function is reached, the Promise is fulfilled with the value returned. If an error is thrown inside an async function, the Promise state will turn to *rejected*. If no value is returned from an async function, a Promise is still returned and resolves with no value when execution of the async function is complete.\n\n*await* operator is used to wait for a *Promise* to be fulfilled and can only be used inside an *async* function body. When encountered, the code execution is paused until the promise is fulfilled.\n\n> **Note :** *fetch* is a function that returns a Promise that allows to do an AJAX request\n\nLet's see how we could fetch a github user with promises first:\n\n```js\nfunction getGithubUser(username) {\n  return fetch(`https:\u002F\u002Fapi.github.com\u002Fusers\u002F${username}`).then(response => response.json());\n}\n\ngetGithubUser('mbeaudru')\n  .then(user => console.log(user))\n  .catch(err => console.log(err));\n```\n\nHere's the *async \u002F await* equivalent:\n\n```js\nasync function getGithubUser(username) { \u002F\u002F promise + await keyword usage allowed\n  const response = await fetch(`https:\u002F\u002Fapi.github.com\u002Fusers\u002F${username}`); \u002F\u002F Execution stops here until fetch promise is fulfilled\n  return response.json();\n}\n\ngetGithubUser('mbeaudru')\n  .then(user => console.log(user))\n  .catch(err => console.log(err));\n```\n\n*async \u002F await* syntax is particularly convenient when you need to chain promises that are interdependent.\n\nFor instance, if you need to get a token in order to be able to fetch a blog post on a database and then the author informations:\n\n> **Note :** *await* expressions needs to be wrapped in parentheses to call its resolved value's methods and properties on the same line.\n\n```js\nasync function fetchPostById(postId) {\n  const token = (await fetch('token_url')).json().token;\n  const post = (await fetch(`\u002Fposts\u002F${postId}?token=${token}`)).json();\n  const author = (await fetch(`\u002Fusers\u002F${post.authorId}`)).json();\n\n  post.author = author;\n  return post;\n}\n\nfetchPostById('gzIrzeo64')\n  .then(post => console.log(post))\n  .catch(err => console.log(err));\n```\n\n##### Error handling\n\nUnless we add *try \u002F catch* blocks around *await* expressions, uncaught exceptions – regardless of whether they were thrown in the body of your *async* function or while it’s suspended during *await* – will reject the promise returned by the *async* function. Using the `throw` statement in an async function is the same as returning a Promise that rejects. [(Ref: PonyFoo)](https:\u002F\u002Fponyfoo.com\u002Farticles\u002Funderstanding-javascript-async-await#error-handling).\n\n> **Note :** Promises behave the same!\n\nWith promises, here is how you would handle the error chain:\n\n```js\nfunction getUser() { \u002F\u002F This promise will be rejected!\n  return new Promise((res, rej) => rej(\"User not found !\"));\n}\n\nfunction getAvatarByUsername(userId) {\n  return getUser(userId).then(user => user.avatar);\n}\n\nfunction getUserAvatar(username) {\n  return getAvatarByUsername(username).then(avatar => ({ username, avatar }));\n}\n\ngetUserAvatar('mbeaudru')\n  .then(res => console.log(res))\n  .catch(err => console.log(err)); \u002F\u002F \"User not found !\"\n```\n\nThe equivalent with *async \u002F await*:\n\n```js\nasync function getUser() { \u002F\u002F The returned promise will be rejected!\n  throw \"User not found !\";\n}\n\nasync function getAvatarByUsername(userId) => {\n  const user = await getUser(userId);\n  return user.avatar;\n}\n\nasync function getUserAvatar(username) {\n  var avatar = await getAvatarByUsername(username);\n  return { username, avatar };\n}\n\ngetUserAvatar('mbeaudru')\n  .then(res => console.log(res))\n  .catch(err => console.log(err)); \u002F\u002F \"User not found !\"\n```\n\n#### External resources\n\n- [Async\u002FAwait - JavaScript.Info](https:\u002F\u002Fjavascript.info\u002Fasync-await)\n- [ES7 Async\u002FAwait](http:\u002F\u002Frossboucher.com\u002Fawait\u002F#\u002F)\n- [6 Reasons Why JavaScript’s Async\u002FAwait Blows Promises Away](https:\u002F\u002Fhackernoon.com\u002F6-reasons-why-javascripts-async-await-blows-promises-away-tutorial-c7ec10518dd9)\n- [JavaScript awaits](https:\u002F\u002Fdev.to\u002Fkayis\u002Fjavascript-awaits)\n- [Using Async Await in Express with Node 8](https:\u002F\u002Fmedium.com\u002F@Abazhenov\u002Fusing-async-await-in-express-with-node-8-b8af872c0016)\n- [Async Function](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FStatements\u002Fasync_function)\n- [Await](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FOperators\u002Fawait)\n- [Using async \u002F await in express with node 8](https:\u002F\u002Fmedium.com\u002F@Abazhenov\u002Fusing-async-await-in-express-with-node-8-b8af872c0016)\n\n### Truthy \u002F Falsy\n\nIn JavaScript, a truthy or falsy value is a value that is being casted into a boolean when evaluated in a boolean context. An example of boolean context would be the evaluation of an ```if``` condition:\n\nEvery value will be casted to ```true``` unless they are equal to:\n\n- ```false```\n- ```0```\n- ```\"\"``` (empty string)\n- ```null```\n- ```undefined```\n- ```NaN```\n\nHere are examples of *boolean context*:\n\n- ```if``` condition evaluation\n\n```js\nif (myVar) {}\n```\n\n```myVar``` can be any [first-class citizen](https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FFirst-class_citizen) (variable, function, boolean) but it will be casted into a boolean because it's evaluated in a boolean context.\n\n- After logical **NOT** ```!``` operator\n\nThis operator returns false if its single operand can be converted to true; otherwise, returns true.\n\n```js\n!0 \u002F\u002F true -- 0 is falsy so it returns true\n!!0 \u002F\u002F false -- 0 is falsy so !0 returns true so !(!0) returns false\n!!\"\" \u002F\u002F false -- empty string is falsy so NOT (NOT false) equals false\n```\n\n- With the *Boolean* object constructor\n\n```js\nnew Boolean(0) \u002F\u002F false\nnew Boolean(1) \u002F\u002F true\n```\n\n- In a ternary evaluation\n\n```js\nmyVar ? \"truthy\" : \"falsy\"\n```\n\nmyVar is evaluated in a boolean context.\n\nBe careful when comparing 2 values. The object values (that should be cast to true) is **not** being casted to Boolean but it forced to convert into a primitive value one using [ToPrimitives specification](http:\u002F\u002Fjavascript.info\u002Fobject-toprimitive). Internally, when an object is compared to Boolean value like `[] == true`, it does `[].toString() == true` so...\n\n```js\nlet a = [] == true \u002F\u002F a is false since [].toString() give \"\" back.\nlet b = [1] == true \u002F\u002F b is true since [1].toString() give \"1\" back.\nlet c = [2] == true \u002F\u002F c is false since [2].toString() give \"2\" back.\n```\n\n#### External resources\n\n- [Truthy (MDN)](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FGlossary\u002FTruthy)\n- [Falsy (MDN)](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FGlossary\u002FFalsy)\n- [Truthy and Falsy values in JS - Josh Clanton](http:\u002F\u002Fadripofjavascript.com\u002Fblog\u002Fdrips\u002Ftruthy-and-falsy-values-in-javascript.html)\n\n### Anamorphisms and Catamorphisms\n\n#### Anamorphisms\n\nAnamorphisms are functions that map from some object to a more complex structure containing the type of the object. It is the process of *unfolding* a simple structure into a more complex one. Consider unfolding an integer to a list of integers. The integer is our initial object and the list of integers is the more complex structure.\n\n**Sample code**\n\n```js\nfunction downToOne(n) {\n  const list = [];\n\n  for (let i = n; i > 0; --i) {\n    list.push(i);\n  }\n\n  return list;\n}\n\ndownToOne(5)\n  \u002F\u002F=> [ 5, 4, 3, 2, 1 ]\n```\n\n#### Catamorphisms\n\nCatamorphisms are the opposite of Anamorphisms, in that they take objects of more complex structure and *fold* them into simpler structures. Take the following example `product` which take a list of integers and returns a single integer.\n\n**Sample code**\n\n```js\nfunction product(list) {\n  let product = 1;\n\n  for (const n of list) {\n    product = product * n;\n  }\n\n  return product;\n}\n\nproduct(downToOne(5)) \u002F\u002F 120\n```\n\n#### External resources\n\n* [Anamorphisms in JavaScript](http:\u002F\u002Fraganwald.com\u002F2016\u002F11\u002F30\u002Fanamorphisms-in-javascript.html)\n* [Anamorphism](https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FAnamorphism)\n* [Catamorphism](https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FCatamorphism)\n\n### Generators\n\nAnother way to write the `downToOne` function is to use a Generator. To instantiate a `Generator` object, one must use the `function *` declaration. Generators are functions that can be exited and later re-entered with its context (variable bindings) saved across re-entrances.\n\nFor example, the `downToOne` function above can be rewritten as:\n\n```js\nfunction * downToOne(n) {\n  for (let i = n; i > 0; --i) {\n    yield i;\n  }\n}\n\n[...downToOne(5)] \u002F\u002F [ 5, 4, 3, 2, 1 ]\n```\n\nGenerators return an iterable object. When the iterator's `next()` function is called, it is executed until the first `yield` expression, which specifies the value to be returned from the iterator or with `yield*`, which delegates to another generator function. When a `return` expression is called in the generator, it will mark the generator as done and pass back as the return value. Further calls to `next()` will not return any new values.\n\n**Sample code**\n\n```js\n\u002F\u002F Yield Example\nfunction * idMaker() {\n  var index = 0;\n  while (index \u003C 2) {\n    yield index;\n    index = index + 1;\n  }\n}\n\nvar gen = idMaker();\n\ngen.next().value; \u002F\u002F 0\ngen.next().value; \u002F\u002F 1\ngen.next().value; \u002F\u002F undefined\n```\n\nThe `yield*` expression enables a generator to call another generator function during iteration.\n\n```js\n\u002F\u002F Yield * Example\nfunction * genB(i) {\n  yield i + 1;\n  yield i + 2;\n  yield i + 3;\n}\n\nfunction * genA(i) {\n  yield i;\n  yield* genB(i);\n  yield i + 10;\n}\n\nvar gen = genA(10);\n\ngen.next().value; \u002F\u002F 10\ngen.next().value; \u002F\u002F 11\ngen.next().value; \u002F\u002F 12\ngen.next().value; \u002F\u002F 13\ngen.next().value; \u002F\u002F 20\n```\n\n```js\n\u002F\u002F Generator Return Example\nfunction* yieldAndReturn() {\n  yield \"Y\";\n  return \"R\";\n  yield \"unreachable\";\n}\n\nvar gen = yieldAndReturn()\ngen.next(); \u002F\u002F { value: \"Y\", done: false }\ngen.next(); \u002F\u002F { value: \"R\", done: true }\ngen.next(); \u002F\u002F { value: undefined, done: true }\n```\n\n#### External resources\n\n* [Mozilla MDN Web Docs, Iterators and Generators](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FJavaScript\u002FGuide\u002FIterators_and_Generators#Generators)\n\n### Static Methods\n\n#### Short explanation\n\nThe `static` keyword is used in classes to declare static methods. Static methods are functions in a class that belongs to the class object and are not available to any instance of that class.\n\n#### Sample code\n\n```js\nclass Repo {\n  static getName() {\n    return \"Repo name is modern-js-cheatsheet\"\n  }\n}\n\n\u002F\u002F Note that we did not have to create an instance of the Repo class\nconsole.log(Repo.getName()) \u002F\u002F Repo name is modern-js-cheatsheet\n\nlet r = new Repo();\nconsole.log(r.getName()) \u002F\u002F Uncaught TypeError: r.getName is not a function\n```\n\n#### Detailed explanation\n\nStatic methods can be called within another static method by using the `this` keyword, this doesn't work for non-static methods though. Non-static methods cannot directly access static methods using the `this` keyword.\n\n##### Calling other static methods from a static method.\n\nTo call a static method from another static method, the `this` keyword can be used like so;\n\n```js\nclass Repo {\n  static getName() {\n    return \"Repo name is modern-js-cheatsheet\"\n  }\n\n  static modifyName() {\n    return this.getName() + '-added-this'\n  }\n}\n\nconsole.log(Repo.modifyName()) \u002F\u002F Repo name is modern-js-cheatsheet-added-this\n```\n\n##### Calling static methods from non-static methods.\n\nNon-static methods can call static methods in 2 ways;\n1. ###### Using the class name.\n\nTo get access to a static method from a non-static method we use the class name and call the static method like a property. e.g `ClassName.StaticMethodName`\n\n```js\nclass Repo {\n  static getName() {\n    return \"Repo name is modern-js-cheatsheet\"\n  }\n\n  useName() {\n    return Repo.getName() + ' and it contains some really important stuff'\n  }\n}\n\n\u002F\u002F we need to instantiate the class to use non-static methods\nlet r = new Repo()\nconsole.log(r.useName()) \u002F\u002F Repo name is modern-js-cheatsheet and it contains some really important stuff\n```\n\n2. ###### Using the constructor\n\nStatic methods can be called as properties on the constructor object.\n\n```js\nclass Repo {\n  static getName() {\n    return \"Repo name is modern-js-cheatsheet\"\n  }\n\n  useName() {\n    \u002F\u002F Calls the static method as a property of the constructor\n    return this.constructor.getName() + ' and it contains some really important stuff'\n  }\n}\n\n\u002F\u002F we need to instantiate the class to use non-static methods\nlet r = new Repo()\nconsole.log(r.useName()) \u002F\u002F Repo name is modern-js-cheatsheet and it contains some really important stuff\n```\n\n#### External resources\n- [static keyword- MDN](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FClasses\u002Fstatic)\n- [Static Methods- Javascript.info](https:\u002F\u002Fjavascript.info\u002Fclass#static-methods)\n- [Static Members in ES6- OdeToCode](http:\u002F\u002Fodetocode.com\u002Fblogs\u002Fscott\u002Farchive\u002F2015\u002F02\u002F02\u002Fstatic-members-in-es6.aspx)\n\n## Glossary\n\n### \u003Ca name=\"scope_def\">\u003C\u002Fa> Scope\n\nThe context in which values and expressions are \"visible,\" or can be ref","这是一个现代JavaScript项目中常用知识的速查表。它涵盖了ES6（ES2015）引入的关键特性和语法，包括变量声明（var, const, let）、箭头函数、默认参数值以及对象和数组解构等核心功能。此外，该项目还提供了丰富的外部学习资源链接，帮助开发者更好地理解和掌握这些概念。适合于那些已经具备一定JavaScript基础但希望快速熟悉或复习现代JavaScript语言特性的开发者使用，特别是在准备学习React等现代前端框架时非常有用。",2,"2026-06-11 03:38:09","high_star"]