[
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2017 BEAUDRU Manuel\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# Modern JavaScript Cheatsheet\n\n![Modern JavaScript cheatsheet](https://i.imgur.com/aexPxMb.png)\n<sub>Image Credits: [Ahmad Awais ⚡️](https://github.com/ahmadawais)</sub>\n\n> If you like this content, you can ping me or follow me on Twitter :+1:\n\n[![Tweet for help](https://img.shields.io/twitter/follow/mbeaudru?label=Tweet%20%40mbeaudru&style=social)](https://twitter.com/mbeaudru/)\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://es6-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://developer.mozilla.org/en-US/search?q=)\n- [You don't know JS (book)](https://github.com/getify/You-Dont-Know-JS)\n- [Eloquent JavaScript (book)](https://eloquentjavascript.net)\n- [Douglas Crockford's blog](https://www.crockford.com/javascript/)\n- [Wes Bos blog (ES6)](https://wesbos.com/javascript)\n- [Javascript Basics for Beginners](https://www.udacity.com/course/javascript-basics--ud804) - a free Udacity course\n- [Reddit (JavaScript)](https://www.reddit.com/r/javascript/)\n- [Google](https://www.google.com/) to find specific blog and resources\n- [StackOverflow](https://stackoverflow.com/questions/tagged/javascript)\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 / filter / 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 / Exports](#imports--exports)\n      - [Explanation with sample code](#explanation-with-sample-code-1)\n        * [Named exports](#named-exports)\n        * [Default import / 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 / Falsy](#truthy--falsy)\n      - [External resources](#external-resources-10)\n    + [Anamorphisms / 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<table>\n  <tr>\n    <th></th>\n    <th>Scope</th>\n    <th>Reassignable</th>\n    <th>Mutable</th>\n   <th><a href=\"#tdz_sample\">Temporal Dead Zone</a></th>\n  </tr>\n  <tr>\n    <th>const</th>\n    <td>Block</td>\n    <td>No</td>\n    <td><a href=\"#const_mutable_sample\">Yes</a></td>\n    <td>Yes</td>\n  </tr>\n  <tr>\n    <th>let</th>\n    <td>Block</td>\n    <td>Yes</td>\n    <td>Yes</td>\n    <td>Yes</td>\n  </tr>\n   <tr>\n    <th>var</th>\n    <td>Function</td>\n    <td>Yes</td>\n    <td>Yes</td>\n    <td>No</td>\n  </tr>\n</table>\n\n#### Sample code\n\n```javascript\nconst person = \"Nick\";\nperson = \"John\" // Will raise an error, person can't be reassigned\n```\n\n```javascript\nlet person = \"Nick\";\nperson = \"John\";\nconsole.log(person) // \"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); // \"Nick\" - myVar is accessible inside the function\n}\nconsole.log(myVar); // 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); // \"John\"\n    // actually, myVar being function scoped, we just erased the previous myVar value \"Nick\" for \"John\"\n  }\n  console.log(myVar); // \"John\" - see how the instructions in the if block affected this value\n}\nconsole.log(myVar); // 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://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var#var_hoisting).\n\nThis portion of code:\n\n```js\nconsole.log(myVar) // undefined -- no error raised\nvar myVar = 2;\n```\n\nis understood at execution like:\n\n```js\nvar myVar;\nconsole.log(myVar) // 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); // \"John\"\n    // actually, myVar being block scoped, we just created a new variable myVar.\n    // this variable is not accessible outside this block and totally independent\n    // from the first myVar created !\n  }\n  console.log(myVar); // \"Nick\", see how the instructions in the if block DID NOT affect this value\n}\nconsole.log(myVar); // Throws a ReferenceError, myVar is not accessible outside the function.\n```\n\n<a name=\"tdz_sample\"></a> Now, what it means for *let* (and *const*) variables for not being accessible before being assigned:\n\n```js\nconsole.log(myVar) // 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://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let#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://jsrocks.org/2015/01/temporal-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; // 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\" // raises an error, reassignment is not allowed\n```\n\n```js\nconst myVar = \"Nick\";\nconst myVar = \"John\" // raises an error, re-declaration is not allowed\n```\n\n<a name=\"const_mutable_sample\"></a> 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' // this will work ! person variable is not completely reassigned, but mutated\nconsole.log(person.name) // \"John\"\nperson = \"Sandra\" // raises an error, because reassignment is not allowed with const declared variables\n```\n\nFor arrays:\n```js\nconst person = [];\nperson.push('John'); // this will work ! person variable is not completely reassigned, but mutated\nconsole.log(person[0]) // \"John\"\nperson = [\"Nick\"] // 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://wesbos.com/javascript-scoping/)\n- [Temporal Dead Zone (TDZ) Demystified](http://jsrocks.org/2015/01/temporal-dead-zone-tdz-demystified)\n\n### <a name=\"arrow_func_concept\"></a> 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; } // Traditional way\nconsole.log(double(2)) // 4\n```\n\n```js\nconst double = x => x * 2; // Same function written as an arrow function with implicit return\nconsole.log(double(2)) // 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) // 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; // 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; // 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; // 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()) // { 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; // 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; // 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  () => { // parentheses are provided, everything is fine\n    const x = 2;\n    return x;\n  }\n```\n\n```js\n  => { // 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; // that = this trick\n  setTimeout(\n    function() { // A new *this* is created in this function scope\n      that.myVar++;\n      console.log(that.myVar) // 1\n\n      console.log(this.myVar) // 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    () => { // this taken from surrounding, meaning myFunc here\n      this.myVar++;\n      console.log(this.myVar) // 1\n    },\n    0\n  );\n}\n```\n\n#### Useful resources\n\n- [Arrow functions introduction - WesBos](http://wesbos.com/arrow-functions/)\n- [JavaScript arrow function - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions)\n- [Arrow function and lexical *this*](https://hackernoon.com/javascript-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()) // 10 -- no value is provided so x default value 10 is assigned to x in myFunc\nconsole.log(myFunc(5)) // 5 -- a value is provided so x is equal to 5 in myFunc\n\nconsole.log(myFunc(undefined)) // 10 -- undefined value is provided so default value is assigned to x\nconsole.log(myFunc(null)) // 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://es6-features.org/#DefaultParameterValues)\n- [Default parameters - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_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; // That's it !\n\nconsole.log(age) // 35 -- A new variable age is created and is equal to person.age\nconsole.log(first) // \"Nick\" -- A new variable first is created and is equal to person.firstName\nconsole.log(firstName) // ReferenceError -- person.firstName exists BUT the new variable created is named first\nconsole.log(city) // \"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); // \"Nick-Anderson\"\n```\n\nIn destructuring the object parameter *person*, we get a more concise function:\n\n```js\nfunction joinFirstLastName({ firstName, lastName }) { // we create firstName and lastName variables by destructuring person parameter\n  return firstName + '-' + lastName;\n}\n\njoinFirstLastName(person); // \"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); // \"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; // That's it !\n\nconsole.log(x) // \"a\"\nconsole.log(y) // \"b\"\n```\n\n#### Useful resources\n\n- [ES6 Features - Destructuring Assignment](http://es6-features.org/#ArrayMatching)\n- [Destructuring Objects - WesBos](http://wesbos.com/destructuring-objects/)\n- [ExploringJS - Destructuring](http://exploringjs.com/es6/ch_destructuring.html)\n\n### Array methods - map / filter / reduce / find\n\n*Map*, *filter*, *reduce* and *find* are array methods that are coming from a programming paradigm named [*functional programming*](https://medium.com/javascript-scene/master-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); // [0, 2, 4, 6, 8, 10, 12]\nconst evenNumbers = numbers.filter(n => n % 2 === 0); // [0, 2, 4, 6]\nconst sum = numbers.reduce((prev, next) => prev + next, 0); // 21\nconst greaterThanFour = numbers.find((n) => n>4); // 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) // we map the students array to an array of their grades\n  .filter(grade => grade >= 10) // we filter the grades array to keep those 10 or above\n  .reduce((prev, next) => prev + next, 0); // we sum all the grades 10 or above one by one\n\nconsole.log(aboveTenSum) // 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); // [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); // [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); // [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 / 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; // true if \"n\" is par, false if \"n\" isn't\n});\nconsole.log(evenNumbers); // [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); // [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 // accumulator variable value at first iteration step\n);\n\nconsole.log(sum) // 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) // 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; // return number just greater than 0 is present\n});\nconsole.log(greaterThanZero); // 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 / filter / reduce in JS](https://hackernoon.com/understanding-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\"]; // [\"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// \"a\"\n// \"b\"\n// [\"c\", \"d\", \"e\", \"f\"]\n```\n\n```js\nconst { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };\nconsole.log(x); // 1\nconsole.log(y); // 2\nconsole.log(z); // { a: 3, b: 4 }\n\nconst n = { x, y, ...z };\nconsole.log(n); // { 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\"]; // [[\"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\"]; // [\"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 < arguments.length; i++) {\n    console.log(arguments[i]);\n  }\n}\n\nmyFunc(\"Nick\", \"Anderson\", 10, 12, 6);\n// \"Nick\"\n// \"Anderson\"\n// 10\n// 12\n// 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  // firstName = \"Nick\"\n  // lastName = \"Anderson\"\n  // [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) / grades.length; // 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// {\n//   firstName: \"Nick\",\n//   lastName: \"Anderson\",\n//   grades: [10, 12, 6],\n//   avgGrade: 9,33\n// }\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; // object destructuring here\nconsole.log(x); // 1\nconsole.log(y); // 2\nconsole.log(z); // { a: 3, b: 4 }\n\n// 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); // { x: 1, y: 2, a: 3, b: 4 }\n\n// Here z object properties are spread into n\n```\n\n#### External resources\n\n- [TC39 - Object rest/spread](https://github.com/tc39/proposal-object-rest-spread)\n- [Spread operator introduction - WesBos](https://github.com/wesbos/es6-articles/blob/master/28%20-%20Spread%20Operator%20Introduction.md)\n- [JavaScript & the spread operator](https://codeburst.io/javascript-the-spread-operator-a867a71668ca)\n- [6 Great uses of the spread operator](https://davidwalsh.name/spread-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) // 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, // assigning x variable value to myObj.x\n  y: y // assigning y variable value to myObj.y\n};\n\nconsole.log(myObj.x) // 10\nconsole.log(myObj.y) // 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) // 10\nconsole.log(myObj.y) // 20\n```\n\n#### External resources\n\n- [Property shorthand - ES6 Features](http://es6-features.org/#PropertyShorthand)\n\n### Promises\n\nA promise is an object which can be returned synchronously from an asynchronous function ([ref](https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-promise-27fc71e77261#3cd0)).\n\nPromises can be used to avoid [callback hell](http://callbackhell.com/), 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(\"/posts\")\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( // Create promise using \"new\" keyword and store it into a variable\n  function(resolve, reject) { // Promise constructor takes a function parameter which has resolve and reject parameters itself\n    $.get(\"X\") // Launch the Ajax request\n      .done(function(X) { // Once the request is done...\n        resolve(X); // ... resolve the promise with the X value as parameter\n      })\n      .fail(function(error) { // If the request has failed...\n        reject(error); // ... 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://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise#Description)\n\n#### External Resources\n\n- [JavaScript Promises for dummies - Jecelyn Yeen](https://scotch.io/tutorials/javascript-promises-for-dummies)\n- [JavaScript Promise API - David Walsh](https://davidwalsh.name/promises)\n- [Using promises - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises)\n- [What is a promise - Eric Elliott](https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-promise-27fc71e77261)\n- [JavaScript Promises: an Introduction - Jake Archibald](https://developers.google.com/web/fundamentals/getting-started/primers/promises)\n- [Promise documentation - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)\n\n### Template literals\n\nTemplate literals is an [*expression interpolation*](https://en.wikipedia.org/wiki/String_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// Hello Nick, the following expression is equal to four: 4\n```\n\n#### External resources\n\n- [String interpolation - ES6 Features](http://es6-features.org/#StringInterpolation)\n- [ES6 Template Strings - Addy Osmani](https://developers.google.com/web/updates/2015/01/ES6-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://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#Tagged_template_literals).\n\n> **Note :** A famous library named [styled-components](https://www.styled-components.com/) 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 ? \"<mark>\" + values.shift() + \"</mark>\" : \"\");\n  }, \"\");\n\n  return interpolation;\n}\n\nconst condiment = \"jam\";\nconst meal = \"toast\";\n\nhighlight`I like ${condiment} on ${meal}.`;\n// \"I like <mark>jam</mark> on <mark>toast</mark>.\"\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// \"I like apples, bananas, cherries to snack on.\"\n```\n\n#### External resources\n- [Wes Bos on Tagged Template Literals](http://wesbos.com/tagged-template-literals/)\n- [Library of common template tags](https://github.com/declandewet/common-tags)\n\n### Imports / 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/export (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://en.wikipedia.org/wiki/First-class_citizen) that have a name.\n\n```js\n// mathConstants.js\nexport const pi = 3.14;\nexport const exp = 2.7;\nexport const alpha = 0.35;\n\n// -------------\n\n// myFile.js\nimport { pi, exp } from './mathConstants.js'; // Named import -- destructuring-like syntax\nconsole.log(pi) // 3.14\nconsole.log(exp) // 2.7\n\n// -------------\n\n// mySecondFile.js\nimport * as constants from './mathConstants.js'; // Inject all exported values into constants variable\nconsole.log(constants.pi) // 3.14\nconsole.log(constants.exp) // 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'; // foo is imported and injected into a new bar variable\n```\n\n##### Default import / 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://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export#Description)\n\n```js\n// coolNumber.js\nconst ultimateNumber = 42;\nexport default ultimateNumber;\n\n// ------------\n\n// myFile.js\nimport number from './coolNumber.js';\n// Default export, independently from its name, is automatically injected into number variable;\nconsole.log(number) // 42\n```\n\nFunction exporting:\n\n```js\n// sum.js\nexport default function sum(x, y) {\n  return x + y;\n}\n// -------------\n\n// myFile.js\nimport sum from './sum.js';\nconst result = sum(1, 2);\nconsole.log(result) // 3\n```\n\n#### External resources\n\n- [ES6 Modules in bulletpoints](https://ponyfoo.com/articles/es6#modules)\n- [Export - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export)\n- [Import - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import)\n- [Understanding ES6 Modules](https://www.sitepoint.com/understanding-es6-modules/)\n- [Destructuring special case - import statements](https://ponyfoo.com/articles/es6-destructuring-in-depth#special-case-import-statements)\n- [Misunderstanding ES6 Modules - Kent C. Dodds](https://medium.com/@kentcdodds/misunderstanding-es6-modules-upgrading-babel-tears-and-a-solution-ad2d5ab93ce0)\n- [Modules in JavaScript](http://exploringjs.com/es6/ch_modules.html#sec_modules-in-javascript)\n\n### <a name=\"this_def\"></a> 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://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this)).\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://yehudakatz.com/2011/08/11/understanding-javascript-function-invocation-and-this/).\n\n```js\nfunction myFunc() {\n  ...\n}\n\n// After each statement, you find the value of *this* in myFunc\n\nmyFunc.call(\"myString\", \"hello\") // \"myString\" -- first .call parameter value is injected into *this*\n\n// In non-strict-mode\nmyFunc(\"hello\") // window -- myFunc() is syntax sugar for myFunc.call(window, \"hello\")\n\n// In strict-mode\nmyFunc(\"hello\") // 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\") // person Object -- first call parameter is injected into *this*\nperson.myFunc(\"test\") // person Object -- person.myFunc() is syntax sugar for person.myFunc.call(person, \"test\")\n\nvar myBoundFunc = person.myFunc.bind(\"hello\") // Creates a new function in which we inject \"hello\" in *this* value\nperson.myFunc(\"test\") // person Object -- The bind method has no effect on the original method\nmyBoundFunc(\"test\") // \"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://yehudakatz.com/2011/08/11/understanding-javascript-function-invocation-and-this/)\n- [JavaScript this - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this)\n\n### Class\n\nJavaScript is a [prototype-based](https://en.wikipedia.org/wiki/Prototype-based_programming) language (whereas Java is [class-based](https://en.wikipedia.org/wiki/Class-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://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes)).\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) // 23\nconsole.log(myPerson.stringSentence()) // \"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://yehudakatz.com/2011/08/12/understanding-prototypes-in-javascript/)\n- [A plain English guide to JS prototypes - Sebastian Porto](http://sporto.github.io/blog/2013/02/22/a-plain-english-guide-to-javascript-prototypes/)\n- [Inheritance and the prototype chain - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain)\n\nFor classes understanding:\n\n- [ES6 Classes in Depth - Nicolas Bevacqua](https://ponyfoo.com/articles/es6-classes-in-depth)\n- [ES6 Features - Classes](http://es6-features.org/#ClassDefinition)\n- [JavaScript Classes - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes)\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://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/extends)). 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    // Here, it calls the parent class' constructor with lengths\n    // provided for the Polygon's width and height\n    super(length, length);\n    // Note: In derived classes, super() must be called before you\n    // 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(); // 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) // 100\nconsole.log(mySquare.getHelloPhrase()) // 'Hi, I am a Square' -- Square inherits from Polygon and has access to its methods\nconsole.log(mySquare.getCustomHelloPhrase()) // '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; // ReferenceError, super needs to be called first!\n\n    // Here, it calls the parent class' constructor with lengths\n    // provided for the Polygon's width and height\n    super(length, length);\n\n    // Note: In derived classes, super() must be called before you\n    // 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://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/extends)\n- [Super operator - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/super)\n- [Inheritance - MDN](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Inheritance)\n\n### Async Await\n\nIn addition to [Promises](#promises), there is a new syntax you might encounter to handle asynchronous code named *async / await*.\n\nThe purpose of async/await 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/await is similar to combining generators and promises. Async functions *always* return a Promise. ([Ref: MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function))\n\n> **Note :** You must understand what promises are and how they work before trying to understand async / await since they rely on it.\n\n> **Note 2:** [*await* must be used in an *async* function](https://hackernoon.com/6-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) { // async keyword allows usage of await in the function and means function returns a promise\n  const response = await fetch(`https://api.github.com/users/${username}`); // 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)) // logging user response - cannot use await syntax since this code isn't in async function\n  .catch(err => console.log(err)); // if an error is thrown in our async function, we will catch it here\n```\n\n#### Explanation with sample code\n\n*Async / 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  // we can use await operator because this function is async\n  return \"hello world\";\n}\n\nmyFunc().then(msg => console.log(msg)) // \"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://api.github.com/users/${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 / await* equivalent:\n\n```js\nasync function getGithubUser(username) { // promise + await keyword usage allowed\n  const response = await fetch(`https://api.github.com/users/${username}`); // 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 / 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(`/posts/${postId}?token=${token}`)).json();\n  const author = (await fetch(`/users/${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 / 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://ponyfoo.com/articles/understanding-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() { // 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)); // \"User not found !\"\n```\n\nThe equivalent with *async / await*:\n\n```js\nasync function getUser() { // 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)); // \"User not found !\"\n```\n\n#### External resources\n\n- [Async/Await - JavaScript.Info](https://javascript.info/async-await)\n- [ES7 Async/Await](http://rossboucher.com/await/#/)\n- [6 Reasons Why JavaScript’s Async/Await Blows Promises Away](https://hackernoon.com/6-reasons-why-javascripts-async-await-blows-promises-away-tutorial-c7ec10518dd9)\n- [JavaScript awaits](https://dev.to/kayis/javascript-awaits)\n- [Using Async Await in Express with Node 8](https://medium.com/@Abazhenov/using-async-await-in-express-with-node-8-b8af872c0016)\n- [Async Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)\n- [Await](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await)\n- [Using async / await in express with node 8](https://medium.com/@Abazhenov/using-async-await-in-express-with-node-8-b8af872c0016)\n\n### Truthy / 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://en.wikipedia.org/wiki/First-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 // true -- 0 is falsy so it returns true\n!!0 // false -- 0 is falsy so !0 returns true so !(!0) returns false\n!!\"\" // 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) // false\nnew Boolean(1) // 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://javascript.info/object-toprimitive). Internally, when an object is compared to Boolean value like `[] == true`, it does `[].toString() == true` so...\n\n```js\nlet a = [] == true // a is false since [].toString() give \"\" back.\nlet b = [1] == true // b is true since [1].toString() give \"1\" back.\nlet c = [2] == true // c is false since [2].toString() give \"2\" back.\n```\n\n#### External resources\n\n- [Truthy (MDN)](https://developer.mozilla.org/en-US/docs/Glossary/Truthy)\n- [Falsy (MDN)](https://developer.mozilla.org/en-US/docs/Glossary/Falsy)\n- [Truthy and Falsy values in JS - Josh Clanton](http://adripofjavascript.com/blog/drips/truthy-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  //=> [ 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)) // 120\n```\n\n#### External resources\n\n* [Anamorphisms in JavaScript](http://raganwald.com/2016/11/30/anamorphisms-in-javascript.html)\n* [Anamorphism](https://en.wikipedia.org/wiki/Anamorphism)\n* [Catamorphism](https://en.wikipedia.org/wiki/Catamorphism)\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)] // [ 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// Yield Example\nfunction * idMaker() {\n  var index = 0;\n  while (index < 2) {\n    yield index;\n    index = index + 1;\n  }\n}\n\nvar gen = idMaker();\n\ngen.next().value; // 0\ngen.next().value; // 1\ngen.next().value; // undefined\n```\n\nThe `yield*` expression enables a generator to call another generator function during iteration.\n\n```js\n// 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; // 10\ngen.next().value; // 11\ngen.next().value; // 12\ngen.next().value; // 13\ngen.next().value; // 20\n```\n\n```js\n// Generator Return Example\nfunction* yieldAndReturn() {\n  yield \"Y\";\n  return \"R\";\n  yield \"unreachable\";\n}\n\nvar gen = yieldAndReturn()\ngen.next(); // { value: \"Y\", done: false }\ngen.next(); // { value: \"R\", done: true }\ngen.next(); // { value: undefined, done: true }\n```\n\n#### External resources\n\n* [Mozilla MDN Web Docs, Iterators and Generators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_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// Note that we did not have to create an instance of the Repo class\nconsole.log(Repo.getName()) // Repo name is modern-js-cheatsheet\n\nlet r = new Repo();\nconsole.log(r.getName()) // 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()) // 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// we need to instantiate the class to use non-static methods\nlet r = new Repo()\nconsole.log(r.useName()) // 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    // 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// we need to instantiate the class to use non-static methods\nlet r = new Repo()\nconsole.log(r.useName()) // Repo name is modern-js-cheatsheet and it contains some really important stuff\n```\n\n#### External resources\n- [static keyword- MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/static)\n- [Static Methods- Javascript.info](https://javascript.info/class#static-methods)\n- [Static Members in ES6- OdeToCode](http://odetocode.com/blogs/scott/archive/2015/02/02/static-members-in-es6.aspx)\n\n## Glossary\n\n### <a name=\"scope_def\"></a> Scope\n\nThe context in which values and expressions are \"visible,\" or can be referenced. If a variable or other expression is not \"in the current scope,\" then it is unavailable for use.\n\nSource: [MDN](https://developer.mozilla.org/en-US/docs/Glossary/Scope)\n\n### <a name=\"mutation_def\"></a> Variable mutation\n\nA variable is said to have been mutated when its initial value has changed afterward.\n\n```js\nvar myArray = [];\nmyArray.push(\"firstEl\") // myArray is being mutated\n```\n\nA variable is said to be *immutable* if it can't be mutated.\n\n[Check MDN Mutable article](https://developer.mozilla.org/en-US/docs/Glossary/Mutable) for more details.\n"
  },
  {
    "path": "_config.yml",
    "content": "theme: jekyll-theme-cayman\ntitle: Modern JS Cheatsheet\n"
  },
  {
    "path": "translations/de-DE.md",
    "content": "# Modern JavaScript Cheatsheet\n\n![Modern JavaScript cheatsheet](https://i.imgur.com/aexPxMb.png)\n<sub>Bildnachweis: [Ahmad Awais ⚡️](https://github.com/ahmadawais)</sub>\n\n> Wenn dir dieser Inhalt gefällt, kannst du mich anpingen oder mir auf Twitter folgen :+1:\n\n[![Tweet for help](https://img.shields.io/twitter/follow/mbeaudru?label=Tweet%20%40mbeaudru&style=social)](https://twitter.com/mbeaudru/)\n\n## Einführung\n\n### Motivation\n\nDieses Dokument ist ein Spickzettel für JavaScript, das du häufig in modernen Projekten und den meisten aktuellen Beispielcodes antreffen wirst.\n\nDieser Leitfaden ist nicht dazu gedacht, dir JavaScript von Grund auf beizubringen, sondern ist eine Hilfe für Entwickler mit grundlegendem Wissen, die Schwierigkeiten haben, sich mit modernen Codebasen vertraut zu machen (oder sagen wir, React zu lernen), aufgrund der in JavaScript verwendeten Konzepte.\n\nAußerdem werde ich manchmal persönliche Tipps geben, die diskutierbar sein könnten, aber ich werde darauf hinweisen, dass es eine persönliche Empfehlung ist, wenn ich das tue.\n\n> **Hinweis:** Die meisten der hier eingeführten Konzepte stammen aus einem JavaScript Sprachupdate (ES2015, oft als ES6 bezeichnet). Neue Funktionen, die durch dieses Update hinzugefügt wurden, findest du [hier](http://es6-features.org); sehr gut gemacht.\n\n### Ergänzende Ressourcen\n\nWenn du Schwierigkeiten hast, eine Vorstellung zu verstehen, schlage ich vor, dass du nach Antworten in den folgenden Ressourcen suchst:\n\n- [MDN (Mozilla Developer Network)](https://developer.mozilla.org/de/search?q=)\n- [You don't know JS (Buch)](https://github.com/getify/You-Dont-Know-JS)\n- [Eloquent JavaScript (Buch)](https://eloquentjavascript.net)\n- [Douglas Crockford's Blog](https://www.crockford.com/javascript/)\n- [ES6 Features mit Beispielen](http://es6-features.org)\n- [Wes Bos Blog (ES6)](https://wesbos.com/javascript)\n- [Javascript Grundlagen für Anfänger](https://www.udacity.com/course/javascript-basics--ud804) - ein kostenloser Udacity-Kurs\n- [Reddit (JavaScript)](https://www.reddit.com/r/javascript/)\n- [Google](https://www.google.com/) um spezifische Blogs und Ressourcen zu finden\n- [StackOverflow](https://stackoverflow.com/questions/tagged/javascript)\n\n## Inhaltsverzeichnis\n\n- [Modern JavaScript Cheatsheet](#modern-javascript-cheatsheet)\n  * [Einführung](#einführung)\n    + [Motivation](#motivation)\n    + [Ergänzende Ressourcen](#ergänzende-ressourcen)\n  * [Inhaltsverzeichnis](#inhaltsverzeichnis)\n  * [Begriffe](#begriffe)\n    + [Variablendeklaration: var, const, let](#variablendeklaration-var-const-let)\n      - [Kurze Erklärung](#kurze-erklärung)\n      - [Beispielcode](#beispielcode)\n      - [Ausführliche Erklärung](#ausführliche-erklärung)\n      - [Externe Ressource](#externe-ressource)\n    + [Pfeilfunktion](#-pfeilfunktion)\n      - [Beispielcode](#beispielcode-1)\n      - [Ausführliche Erklärung](#ausführliche-erklärung-1)\n        * [Prägnanz](#prägnanz)\n        * [*this* Referenz](#this-referenz)\n      - [Nützliche Ressourcen](#nützliche-ressourcen)\n    + [Standardparameterwert für Funktionen](#standardparameterwert-für-funktionen)\n      - [Externe Ressource](#externe-ressource-1)\n    + [Destrukturierung von Objekten und Arrays](#destrukturierung-von-objekten-und-arrays)\n      - [Erklärung mit Beispielcode](#erklärung-mit-beispielcode)\n      - [Nützliche Ressourcen](#nützliche-ressourcen-1)\n    + [Array-Methoden - map / filter / reduce](#array-methoden---map--filter--reduce--find)\n      - [Beispielcode](#beispielcode-2)\n      - [Erklärung](#erklärung)\n        * [Array.prototype.map()](#arrayprototypemap)\n        * [Array.prototype.filter()](#arrayprototypefilter)\n        * [Array.prototype.reduce()](#arrayprototypereduce)\n        * [Array.prototype.find()](#arrayprototypefind)\n      - [Externe Ressource](#externe-ressource-2)\n    + [Spread-Operator \"...\"](#spread-operator-)\n      - [Beispielcode](#beispielcode-3)\n      - [Erklärung](#erklärung-1)\n        * [In Iterables (wie Arrays)](#in-iterables-wie-arrays)\n        * [Funktionsrestparameter](#funktionsrestparameter)\n        * [Objekteigenschaften ausbreiten](#objekteigenschaften-ausbreiten)\n      - [Externe Ressourcen](#externe-ressourcen)\n    + [Objekteigenschaften Kurzschreibweise](#objekteigenschaften-kurzschreibweise)\n      - [Erklärung](#erklärung-2)\n      - [Externe Ressourcen](#externe-ressourcen-1)\n    + [Promises](#promises)\n      - [Beispielcode](#beispielcode-4)\n      - [Erklärung](#erklärung-3)\n        * [Das Promise erstellen](#das-promise-erstellen)\n        * [Verwendung von Promise-Handlern](#verwendung-von-promise-handlern)\n      - [Externe Ressourcen](#externe-ressourcen-2)\n    + [Template Literale](#template-literale)\n      - [Beispielcode](#beispielcode-5)\n      - [Externe Ressourcen](#externe-ressourcen-3)\n    + [Tagged Template Literale](#tagged-template-literale)\n      - [Externe Ressourcen](#externe-ressourcen-4)\n    + [Imports / Exports](#imports--exports)\n      - [Erklärung mit Beispielcode](#erklärung-mit-beispielcode-1)\n        * [Benannte Exports](#benannte-exports)\n        * [Standardimport / export](#standardimport--export)\n      - [Externe Ressourcen](#externe-ressourcen-5)\n    + [JavaScript *this*](#-javascript-this)\n      - [Externe Ressourcen](#externe-ressourcen-6)\n    + [Klasse](#klasse)\n      - [Beispiele](#beispiele)\n      - [Externe Ressourcen](#externe-ressourcen-7)\n    + [Extends und super](#extends-und-super)\n      - [Beispielcode](#beispielcode-6)\n      - [Externe Ressourcen](#externe-ressourcen-8)\n    + [Async Await](#async-await)\n      - [Beispielcode](#beispielcode-7)\n      - [Erklärung mit Beispielcode](#erklärung-mit-beispielcode-2)\n      - [Fehlerbehandlung](#fehlerbehandlung)\n      - [Externe Ressourcen](#externe-ressourcen-9)\n    + [Truthy / Falsy](#truthy--falsy)\n      - [Externe Ressourcen](#externe-ressourcen-10)\n    + [Anamorphismen / Katamorphismen](#anamorphismen-und-katamorphismen)\n      - [Anamorphismen](#anamorphismen)\n      - [Katamorphismen](#katamorphismen)\n      - [Externe Ressourcen](#externe-ressourcen-11)\n    + [Generatoren](#generatoren)\n      - [Externe Ressourcen](#externe-ressourcen-12)\n    + [Statische Methoden](#statische-methoden)\n      - [Kurze Erklärung](#kurze-erklärung-1)\n      - [Beispielcode](#beispielcode-8)\n      - [Ausführliche Erklärung](#ausführliche-erklärung-2)\n        * [Andere statische Methoden aus einer statischen Methode aufrufen](#andere-statische-methoden-aus-einer-statischen-methode-aufrufen)\n        * [Statische Methoden aus nicht-statischen Methoden aufrufen](#statische-methoden-aus-nicht-statischen-methoden-aufrufen)\n      - [Externe Ressourcen](#externe-ressourcen-13)\n  * [Glossar](#glossar)\n    + [Scope](#-scope)\n    + [Variablenmutation](#-variablenmutation)\n\n## Begriffe\n\n### Variablendeklaration: var, const, let\n\nIn JavaScript gibt es drei Schlüsselwörter, um eine Variable zu deklarieren, und jedes hat seine Unterschiede. Diese Schlüsselwörter sind ```var```, ```let``` und ```const```.\n\n#### Kurze Erklärung\n\nVariablen, die mit dem Schlüsselwort ```const``` deklariert sind, können nicht neu zugewiesen werden, während ```let``` und ```var``` neu zugewiesen werden können.\n\nIch empfehle, deine Variablen standardmäßig mit ```const``` zu deklarieren, aber mit ```let```, wenn es eine Variable ist, die du später *mutieren* oder neu zuweisen musst.\n\n<table>\n  <tr>\n    <th></th>\n    <th>Scope</th>\n    <th>Neu zuzuweisend</th>\n    <th>Veränderbar</th>\n   <th><a href=\"#tdz_sample\">Temporal Dead Zone</a></th>\n  </tr>\n  <tr>\n    <th>const</th>\n    <td>Block</td>\n    <td>Nein</td>\n    <td><a href=\"#const_mutable_sample\">Ja</a></td>\n    <td>Ja</td>\n  </tr>\n  <tr>\n    <th>let</th>\n    <td>Block</td>\n    <td>Ja</td>\n    <td>Ja</td>\n    <td>Ja</td>\n  </tr>\n   <tr>\n    <th>var</th>\n    <td>Funktion</td>\n    <td>Ja</td>\n    <td>Ja</td>\n    <td>Nein</td>\n  </tr>\n</table>\n\n#### Beispielcode\n\n```javascript\nconst person = \"Nick\";\nperson = \"John\" // Wird einen Fehler werfen, person kann nicht neu zugewiesen werden\n```\n\n```javascript\nlet person = \"Nick\";\nperson = \"John\";\nconsole.log(person) // \"John\", Neu-Zuweisung ist erlaubt mit let\n```\n\n#### Ausführliche Erklärung\n\nDer [*Scope*](#scope_def) einer Variable bedeutet grob \"wo ist diese Variable im Code verfügbar\".\n\n##### var\n\n```var``` deklarierte Variablen sind *funktionsumfänglich*, was bedeutet, dass, wenn eine Variable in einer Funktion erstellt wird, alles in dieser Funktion Zugriff auf diese Variable hat. Außerdem kann eine *funktionsumfängliche* Variable, die in einer Funktion erstellt wurde, nicht außerhalb dieser Funktion zugegriffen werden.\n\nIch empfehle dir, es dir so vorzustellen, als ob eine *X-umfängliche* Variable bedeutet, dass diese Variable eine Eigenschaft von X ist.\n\n```javascript\nfunction myFunction() {\n  var myVar = \"Nick\";\n  console.log(myVar); // \"Nick\" - myVar ist innerhalb der Funktion zugänglich\n}\nconsole.log(myVar); // Wirft einen ReferenceError, myVar ist außerhalb der Funktion nicht zugänglich.\n```\n\nFokussieren wir uns immer noch auf den Variablenscope, hier ist ein subtileres Beispiel:\n\n```javascript\nfunction myFunction() {\n  var myVar = \"Nick\";\n  if (true) {\n    var myVar = \"John\";\n    console.log(myVar); // \"John\"\n    // eigentlich, da myVar funktionsumfänglich ist, haben wir einfach den vorherigen myVar-Wert \"Nick\" durch \"John\" ersetzt\n  }\n  console.log(myVar); // \"John\" - sieh, wie die Anweisungen im if-Block diesen Wert beeinflusst haben\n}\nconsole.log(myVar); // Wirft einen ReferenceError, myVar ist außerhalb der Funktion nicht zugänglich.\n```\n\nAußerdem werden *var* deklarierte Variablen zum Anfang des Scopes bei der Ausführung verschoben. Dies nennt man [var hoisting](https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Statements/var#var_hoisting).\n\nDieser Codeabschnitt:\n\n```js\nconsole.log(myVar) // undefined -- kein Fehler geworfen\nvar myVar = 2;\n```\n\nwird bei der Ausführung so verstanden:\n\n```js\nvar myVar;\nconsole.log(myVar) // undefined -- kein Fehler geworfen\nmyVar = 2;\n```\n\n##### let\n\n```var``` und ```let ``` sind ungefähr gleich, aber bei ```let``` deklarierte Variablen\n\n- haben einen *Block-Scope*\n- sind **nicht** zugänglich, bevor sie zugewiesen werden\n- können nicht im gleichen Scope neu deklariert werden\n\nLasst uns die Auswirkung der Block-Scoping anhand unseres vorherigen Beispiels sehen:\n\n```javascript\nfunction myFunction() {\n  let myVar = \"Nick\";\n  if (true) {\n    let myVar = \"John\";\n    console.log(myVar); // \"John\"\n    // eigentlich, da myVar einen Block-Scope hat, haben wir gerade eine neue Variable myVar erstellt.\n    // Diese Variable ist außerhalb dieses Blocks nicht zugänglich und völlig unabhängig\n    // von der ersten erstellten myVar!\n  }\n  console.log(myVar); // \"Nick\", sieh, wie die Anweisungen im if-Block diesen Wert NICHT beeinflusst haben\n}\nconsole.log(myVar); // Wirft einen ReferenceError, myVar ist außerhalb der Funktion nicht zugänglich.\n```\n\n<a name=\"tdz_sample\"></a> Nun, was es für *let* (und *const*) Variablen bedeutet, nicht zugänglich zu sein, bevor sie zugewiesen werden:\n\n```js\nconsole.log(myVar) // wirft einen ReferenceError !\nlet myVar = 2;\n```\n\nIm Gegensatz zu *var* Variablen, wenn du versuchst, eine *let* oder *const* Variable zu lesen oder zu schreiben, bevor sie zugewiesen sind, wird ein Fehler ausgelöst. Dieses Phänomen wird oft [*Temporal Dead Zone*](https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Statements/let#Temporal_Dead_Zone_and_errors_with_let) oder *TDZ* genannt.\n\n> **Hinweis:** Technisch gesehen werden *let* und *const* Variablendeklarationen auch gehoistet, aber nicht ihre Zuweisung. Da sie so gemacht sind, dass sie nicht vor der Zuweisung verwendet werden können, fühlt es sich intuitiv an, als ob es kein Hoisting gäbe, aber es gibt es. Finde mehr in [dieser sehr detaillierten Erklärung](http://jsrocks.org/2015/01/temporal-dead-zone-tdz-demystified) heraus, wenn du mehr wissen möchtest.\n\nAußerdem kannst du eine *let* Variable nicht neu deklarieren:\n\n```js\nlet myVar = 2;\nlet myVar = 3; // Wirft einen SyntaxError\n```\n\n##### const\n\nMit *const* deklarierte Variablen verhalten sich wie *let*-Variablen, können aber auch nicht neu zugewiesen werden.\n\nZusammenfassend können *const*-Variablen:\n\n- haben einen *Block-Scope*\n- sind nicht zugänglich bevor sie zugewiesen werden\n- können nicht im gleichen Scope neu deklariert werden\n- können nicht neu zugewiesen werden\n\n```js\nconst myVar = \"Nick\";\nmyVar = \"John\" // Wirft einen Fehler, Neuzuweisung ist nicht erlaubt\n```\n\n```js\nconst myVar = \"Nick\";\nconst myVar = \"John\" // Wirft einen Fehler, Neudeklarierung ist nicht erlaubt\n```\n\n<a name=\"const_mutable_sample\"></a> Aber es gibt eine Feinheit: ```const``` Variablen sind nicht [**unveränderbar**](#mutation_def)! Konkret bedeutet das, dass *Objekt*- und *Array*-```const``` deklarierte Variablen **verändert** werden können.\n\nFür Objekte:\n```js\nconst person = {\n  name: 'Nick'\n};\nperson.name = 'John' // das funktioniert! Die Variable person wird nicht komplett neu zugewiesen, sondern verändert\nconsole.log(person.name) // \"John\"\nperson = \"Sandra\" // wirft einen Fehler, da Neu-Zuweisung nicht erlaubt ist für const deklarierte Variablen\n```\n\nFür Arrays:\n```js\nconst person = [];\nperson.push('John'); // das funktioniert! Die Variable person wird nicht komplett neu zugewiesen, sondern verändert\nconsole.log(person[0]) // \"John\"\nperson = [\"Nick\"] // wirft einen Fehler, da Neu-Zuweisung nicht erlaubt ist für const deklarierte Variablen\n```\n\n#### Externe Ressource\n\n- [Wie let und const in JavaScript skopiert werden - WesBos](http://wesbos.com/javascript-scoping/)\n- [Temporal Dead Zone (TDZ) Demystifiziert](http://jsrocks.org/2015/01/temporal-dead-zone-tdz-demystified)\n\n### <a name=\"arrow_func_concept\"></a> Pfeilfunktion\n\nDas ES6 JavaScript Update hat *Pfeilfunktionen* eingeführt, die eine weitere Methode darstellen, Funktionen zu deklarieren und zu verwenden. Hier sind die Vorteile, die sie mitbringen:\n\n- Kürzerer Code\n- *this* wird aus der Umgebung übernommen\n- implizite Rückgabe\n\n#### Beispielcode\n\n- Kürze und implizite Rückgabe\n\n```js\nfunction double(x) { return x * 2; } // Traditioneller Weg\nconsole.log(double(2)) // 4\n```\n\n```js\nconst double = x => x * 2; // Gleiche Funktion als Pfeilfunktion mit impliziter Rückgabe geschrieben\nconsole.log(double(2)) // 4\n```\n\n- *this*-Referenz\n\nIn einer Pfeilfunktion ist *this* gleich dem *this*-Wert des umschließenden Ausführungskontextes. Im Grunde musst du mit Pfeilfunktionen nicht mehr den Trick \"that = this\" anwenden, bevor du eine Funktion in einer Funktion aufrufst.\n\n```js\nfunction myFunc() {\n  this.myVar = 0;\n  setTimeout(() => {\n    this.myVar++;\n    console.log(this.myVar) // 1\n  }, 0);\n}\n```\n\n#### Ausführliche Erklärung\n\n##### Prägnanz\n\nPfeilfunktionen sind in vielerlei Hinsicht prägnanter als traditionelle Funktionen. Lass uns alle möglichen Fälle überprüfen:\n\n- Implizite vs. explizite Rückgabe\n\nEine **explizite Rückgabe** ist eine Funktion, in deren Körper das Schlüsselwort *return* verwendet wird.\n\n```js\n  function double(x) {\n    return x * 2; // diese Funktion gibt explizit x * 2 zurück, das Schlüsselwort *return* wird verwendet\n  }\n```\n\nAuf traditionelle Weise geschriebene Funktionen hatten immer eine explizite Rückgabe. Aber mit Pfeilfunktionen kannst du eine *implizite Rückgabe* durchführen, was bedeutet, dass du das Schlüsselwort *return* nicht verwenden musst, um einen Wert zurückzugeben.\n\n```js\n  const double = (x) => {\n    return x * 2; // Hier explizite Rückgabe\n  }\n```\n\nDa diese Funktion nur etwas zurückgibt (keine Anweisungen vor dem Schlüsselwort *return*), können wir eine implizite Rückgabe durchführen.\n\n```js\n  const double = (x) => x * 2; // Korrekt, gibt x*2 zurück\n```\n\nUm dies zu tun, müssen wir nur die **Klammern** und das Schlüsselwort **return** entfernen. Daher wird sie als *implizite* Rückgabe bezeichnet, das Schlüsselwort *return* ist nicht vorhanden, aber diese Funktion wird tatsächlich ```x * 2``` zurückgeben.\n\n> **Hinweis:** Wenn deine Funktion keinen Wert zurückgibt (mit *Nebenwirkungen*), führt sie weder eine explizite noch eine implizite Rückgabe durch.\n\nAußerdem, wenn du ein *Objekt* implizit zurückgeben möchtest, **musst du es in Klammern setzen**, da es sonst zu Konflikten mit den Blockklammern kommen würde:\n\n```js\nconst getPerson = () => ({ name: \"Nick\", age: 24 })\nconsole.log(getPerson()) // { name: \"Nick\", age: 24 } -- Objekt wird implizit durch Pfeilfunktion zurückgegeben\n```\n\n- Nur ein Argument\n\nWenn deine Funktion nur einen Parameter hat, kannst du die Klammern um ihn herum weglassen. Wenn wir den oben genannten *double*-Code wieder aufgreifen:\n\n```js\n  const double = (x) => x * 2; // diese Pfeilfunktion nimmt nur einen Parameter entgegen\n```\n\nKlammern um den Parameter können vermieden werden:\n\n```js\n  const double = x => x * 2; // diese Pfeilfunktion nimmt nur einen Parameter entgegen\n```\n\n- Keine Argumente\n\nWenn einer Pfeilfunktion kein Argument übergeben wird, musst du Klammern angeben, sonst ist die Syntax nicht gültig.\n\n```js\n  () => { // Klammern werden angegeben, alles ist in Ordnung\n    const x = 2;\n    return x;\n  }\n```\n\n```js\n  => { // Keine Klammern, das wird nicht funktionieren!\n    const x = 2;\n    return x;\n  }\n```\n\n##### *this*-Referenz\n\nUm diese Nuance, die mit Pfeilfunktionen eingeführt wurde, zu verstehen, muss du wissen, wie [this](#this_def) sich in JavaScript verhält.\n\nIn einer Pfeilfunktion ist *this* gleich dem *this*-Wert des umschließenden Ausführungskontextes. Das bedeutet, dass eine Pfeilfunktion kein neues *this* erstellt, sondern es stattdessen aus seiner Umgebung übernimmt.\n\nOhne Pfeilfunktion, wenn du in einer Funktion innerhalb einer Funktion auf eine Variable von *this* zugreifen wolltest, musstest du den Trick *that = this* oder *self = this* anwenden.\n\nZum Beispiel beim Verwenden der setTimeout-Funktion innerhalb von myFunc:\n\n```js\nfunction myFunc() {\n  this.myVar = 0;\n  var that = this; // that = this Trick\n  setTimeout(\n    function() { // Ein neues *this* wird in diesem Funktionsbereich erstellt\n      that.myVar++;\n      console.log(that.myVar) // 1\n\n      console.log(this.myVar) // undefiniert -- siehe Funktionsdeklaration oben\n    },\n    0\n  );\n}\n```\n\nAber mit Pfeilfunktion wird *this* aus seiner Umgebung übernommen:\n\n```js\nfunction myFunc() {\n  this.myVar = 0;\n  setTimeout(\n    () => { // this wird aus der Umgebung übernommen, was hier myFunc bedeutet\n      this.myVar++;\n      console.log(this.myVar) // 1\n    },\n    0\n  );\n}\n```\n\n#### Nützliche Ressourcen\n\n- [Einführung in Pfeilfunktionen - WesBos](http://wesbos.com/arrow-functions/)\n- [JavaScript Pfeilfunktion - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions)\n- [Pfeilfunktion und lexikalisches *this*](https://hackernoon.com/javascript-es6-arrow-functions-and-lexical-this-f2a3e2a5e8c4)\n\n### Standardparameterwert für Funktionen\n\nAb dem ES2015 JavaScript Update kannst du deinen Funktionsparametern Standardwerte zuweisen, indem du folgende Syntax verwendest:\n\n```js\nfunction myFunc(x = 10) {\n  return x;\n}\nconsole.log(myFunc()) // 10 -- kein Wert wird übergeben, daher wird dem x in myFunc der Standardwert 10 zugewiesen\nconsole.log(myFunc(5)) // 5 -- ein Wert wird übergeben, daher ist x gleich 5 in myFunc\n\nconsole.log(myFunc(undefined)) // 10 -- der Wert undefined wird übergeben, daher wird der Standardwert dem x zugewiesen\nconsole.log(myFunc(null)) // null -- ein Wert (null) wird übergeben, siehe unten für weitere Details\n```\n\nDer Standardparameter wird in zwei und nur zwei Situationen angewendet:\n\n- Kein Parameter übergeben\n- *undefined* Parameter übergeben\n\nAnders ausgedrückt, wenn du *null* übergibst, wird der Standardparameter **nicht angewendet**.\n\n> **Hinweis:** Die Zuweisung eines Standardwerts kann auch mit destrukturierten Parametern verwendet werden (siehe nächste Notion, um ein Beispiel zu sehen)\n\n#### Externe Ressource\n\n- [Standardparameterwert - ES6 Features](http://es6-features.org/#DefaultParameterValues)\n- [Standardparameter - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters)\n\n### Destrukturierung von Objekten und Arrays\n\n*Destrukturierung* ist eine praktische Methode, neue Variablen zu erstellen, indem einige Werte aus in Objekten oder Arrays gespeicherten Daten extrahiert werden.\n\nUm nur einige Anwendungsfälle zu nennen, kann die *Destrukturierung* verwendet werden, um Funktionsparameter oder *this.props* in React-Projekten zu destrukturieren.\n\n#### Erklärung mit Beispielcode\n\n- Objekt\n\nBetrachten wir das folgende Objekt für alle Beispiele:\n\n```js\nconst person = {\n  firstName: \"Nick\",\n  lastName: \"Anderson\",\n  age: 35,\n  sex: \"M\"\n}\n```\n\nOhne Destrukturierung\n\n```js\nconst first = person.firstName;\nconst age = person.age;\nconst city = person.city || \"Paris\";\n```\n\nMit Destrukturierung, alles in einer Zeile:\n\n```js\nconst { firstName: first, age, city = \"Paris\" } = person; // Das war's !\n\nconsole.log(age) // 35 -- Eine neue Variable age wird erstellt und ist gleich person.age\nconsole.log(first) // \"Nick\" -- Eine neue Variable first wird erstellt und ist gleich person.firstName\nconsole.log(firstName) // ReferenceError -- person.firstName existiert, ABER die neu erstellte Variable ist als first benannt\nconsole.log(city) // \"Paris\" -- Eine neue Variable city wird erstellt und da person.city undefiniert ist, ist city gleich dem bereitgestellten Standardwert \"Paris\".\n```\n\n**Hinweis:** In ```const { age } = person;``` werden die Klammern nach dem *const*-Schlüsselwort nicht verwendet, um ein Objekt oder einen Block zu deklarieren, sondern es ist die *Destrukturierungssyntax*.\n\n- Funktionsparameter\n\n*Destrukturierung* wird häufig verwendet, um Objektparameter in Funktionen zu destrukturieren.\n\nOhne Destrukturierung\n\n```js\nfunction joinFirstLastName(person) {\n  const firstName = person.firstName;\n  const lastName = person.lastName;\n  return firstName + '-' + lastName;\n}\n\njoinFirstLastName(person); // \"Nick-Anderson\"\n```\n\nBei der Destrukturierung des Objektparameters *person* erhalten wir eine präzisere Funktion:\n\n```js\nfunction joinFirstLastName({ firstName, lastName }) { // wir erstellen Variablen firstName und lastName durch Destrukturierung des person-Parameters\n  return firstName + '-' + lastName;\n}\n\njoinFirstLastName(person); // \"Nick-Anderson\"\n```\n\nDestrukturierung ist noch angenehmer mit [Pfeilfunktionen](#arrow_func_concept) zu verwenden:\n\n```js\nconst joinFirstLastName = ({ firstName, lastName }) => firstName + '-' + lastName;\n\njoinFirstLastName(person); // \"Nick-Anderson\"\n```\n\n- Array\n\nBetrachten wir das folgende Array:\n\n```js\nconst myArray = [\"a\", \"b\", \"c\"];\n```\n\nOhne Destrukturierung\n\n```js\nconst x = myArray[0];\nconst y = myArray[1];\n```\n\nMit Destrukturierung\n\n```js\nconst [x, y] = myArray; // Das war's !\n\nconsole.log(x) // \"a\"\nconsole.log(y) // \"b\"\n```\n\n#### Nützliche Ressourcen\n\n- [ES6 Features - Destrukturierende Zuweisung](http://es6-features.org/#ArrayMatching)\n- [Objektdestrukturierung - WesBos](http://wesbos.com/destructuring-objects/)\n- [ExploringJS - Destrukturierung](http://exploringjs.com/es6/ch_destructuring.html)\n\n### Array-Methoden - map / filter / reduce / find\n\n*Map*, *filter*, *reduce* und *find* sind Array-Methoden, die aus einem Programmierparadigma namens [*funktionale Programmierung*](https://medium.com/javascript-scene/master-the-javascript-interview-what-is-functional-programming-7f218c68b3a0) stammen.\n\nZusammengefasst:\n\n- **Array.prototype.map()** nimmt ein Array, führt eine Operation auf seinen Elementen durch und gibt ein Array mit den transformierten Elementen zurück.\n- **Array.prototype.filter()** nimmt ein Array, entscheidet elementweise, ob es dieses behalten will oder nicht, und gibt ein Array nur mit den behaltenen Elementen zurück.\n- **Array.prototype.reduce()** nimmt ein Array und aggregiert die Elemente zu einem einzelnen Wert (der zurückgegeben wird).\n- **Array.prototype.find()** nimmt ein Array und gibt das erste Element zurück, das die bereitgestellte Bedingung erfüllt.\n\nIch empfehle, sie so oft wie möglich zu verwenden, indem du den Prinzipien der funktionalen Programmierung folgst, da sie zusammensetzbar, prägnant und elegant sind.\n\nMit diesen vier Methoden kannst du in den meisten Situationen die Verwendung von *for* und *forEach* Schleifen vermeiden. Wenn du versucht bist, eine *for*-Schleife zu machen, versuche es mit *map*, *filter*, *reduce* und *find* zusammengesetzt. Es könnte anfangs schwierig sein, da es dich zwingt, eine neue Denkweise zu erlernen, aber sobald du es beherrschst, wird alles einfacher.\n\n#### Beispielcode\n\n```js\nconst numbers = [0, 1, 2, 3, 4, 5, 6];\nconst doubledNumbers = numbers.map(n => n * 2); // [0, 2, 4, 6, 8, 10, 12]\nconst evenNumbers = numbers.filter(n => n % 2 === 0); // [0, 2, 4, 6]\nconst sum = numbers.reduce((prev, next) => prev + next, 0); // 21\nconst greaterThanFour = numbers.find((n) => n>4); // 5\n```\n\nBerechne die Gesamtsumme der Noten für Schüler mit Noten 10 oder darüber, indem du map, filter und reduce zusammensetzt:\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) // wir mappen das students Array auf ein Array ihrer Noten\n  .filter(grade => grade >= 10) // wir filtern das Noten-Array, um diejenigen 10 oder darüber zu behalten\n  .reduce((prev, next) => prev + next, 0); // wir summieren alle Noten 10 oder darüber nacheinander\n\nconsole.log(aboveTenSum) // 44 -- 10 (Nick) + 15 (John) + 19 (Julia), Nathalie unter 10 wird ignoriert\n```\n\n#### Erklärung\n\nBetrachten wir das folgende Array von Zahlen für unsere Beispiele:\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); // [0, 2, 4, 6, 8, 10, 12]\n```\n\nWas passiert hier? Wir verwenden .map auf dem *numbers*-Array, die Map iteriert über jedes Element des Arrays und übergibt es unserer Funktion. Das Ziel der Funktion ist es, einen neuen Wert aus dem übergebenen Wert zu erzeugen und zurückzugeben, so dass map ihn ersetzen kann.\n\nLasst uns diese Funktion extrahieren, um es einmal klarer zu machen:\n\n```js\nconst doubleN = function(n) { return n * 2; };\nconst doubledNumbers = numbers.map(doubleN);\nconsole.log(doubledNumbers); // [0, 2, 4, 6, 8, 10, 12]\n```\n\n**Hinweis**: Du wirst diese Methode oft in Kombination mit [Pfeilfunktionen](#-pfeilfunktion) antreffen\n\n```js\nconst doubledNumbers = numbers.map(n => n * 2);\nconsole.log(doubledNumbers); // [0, 2, 4, 6, 8, 10, 12]\n```\n\n```numbers.map(doubleN)``` produziert ```[doubleN(0), doubleN(1), doubleN(2), doubleN(3), doubleN(4), doubleN(5), doubleN(6)]```, was gleich ```[0, 2, 4, 6, 8, 10, 12]``` ist.\n\n> **Hinweis:** Wenn du kein neues Array zurückgeben musst und nur eine Schleife mit Nebeneffekten machen willst, solltest du vielleicht stattdessen eine for / forEach-Schleife anstelle von map verwenden.\n\n##### Array.prototype.filter()\n\n```js\nconst evenNumbers = numbers.filter(function(n) {\n  return n % 2 === 0; // true, wenn \"n\" gerade ist, false, wenn \"n\" ungerade ist\n});\nconsole.log(evenNumbers); // [0, 2, 4, 6]\n```\n\n**Hinweis**: Du wirst diese Methode oft in Kombination mit [Pfeilfunktionen](#-pfeilfunktion) antreffen\n\n```js\nconst evenNumbers = numbers.filter(n => n % 2 === 0);\nconsole.log(evenNumbers); // [0, 2, 4, 6]\n```\n\nWir verwenden .filter auf dem *numbers*-Array, filter iteriert über jedes Element des Arrays und übergibt es unserer Funktion. Das Ziel der Funktion ist es, einen Boolean zurückzugeben, der bestimmt, ob der aktuelle Wert behalten wird oder nicht. Filter gibt dann das Array nur mit den behaltenen Werten zurück.\n\n##### Array.prototype.reduce()\n\nDas Ziel der reduce-Methode ist es, alle Elemente des Arrays, über das sie iteriert, in einen einzigen Wert zu *reduzieren*. Wie diese Elemente aggregiert werden, liegt bei dir.\n\n```js\nconst sum = numbers.reduce(\n  function(acc, n) {\n    return acc + n;\n  },\n  0 // Wert der Akkumulatorvariablen beim ersten Iterationsschritt\n);\n\nconsole.log(sum) // 21\n```\n\n**Hinweis**: Du wirst diese Methode oft in Kombination mit [Pfeilfunktionen](#-pfeilfunktion) antreffen\n\n```js\nconst sum = numbers.reduce((acc, n) => acc + n, 0);\nconsole.log(sum) // 21\n```\n\nWie bei den .map- und .filter-Methoden wird .reduce auf einem Array angewandt und nimmt eine Funktion als ersten Parameter.\n\nDiesmal gibt es allerdings Änderungen:\n\n- .reduce nimmt zwei Parameter\n\nDer erste Parameter ist eine Funktion, die bei jedem Iterationsschritt aufgerufen wird.\n\nDer zweite Parameter ist der Wert der Akkumulatorvariablen (*acc* hier) beim ersten Iterationsschritt (lies den nächsten Punkt, um dies zu verstehen).\n\n- Funktionsparameter\n\nDie Funktion, die du als ersten Parameter von .reduce übergibst, nimmt zwei Parameter entgegen. Der erste (*acc* hier) ist die Akkumulatorvariable, während der zweite Parameter (*n*) das aktuelle Element ist.\n\nDie Akkumulatorvariable entspricht dem Rückgabewert deiner Funktion im **vorherigen** Iterationsschritt. Beim ersten Schritt der Iteration ist *acc* gleich dem Wert, den du als zweiten Parameter von .reduce übergeben hast.\n\n###### Beim ersten Iterationsschritt\n\n```acc = 0```, weil wir 0 als zweiten Parameter für reduce übergeben haben\n\n```n = 0```, erstes Element des *numbers*-Arrays\n\nDie Funktion gibt *acc* + *n* --> 0 + 0 --> 0 zurück\n\n###### Beim zweiten Iterationsschritt\n\n```acc = 0```, weil es der Wert ist, den die Funktion im vorherigen Iterationsschritt zurückgegeben hat\n\n```n = 1```, zweites Element des *numbers*-Arrays\n\nDie Funktion gibt *acc* + *n* --> 0 + 1 --> 1 zurück\n\n###### Beim dritten Iterationsschritt\n\n```acc = 1```, weil es der Wert ist, den die Funktion im vorherigen Iterationsschritt zurückgegeben hat\n\n```n = 2```, drittes Element des *numbers*-Arrays\n\nDie Funktion gibt *acc* + *n* --> 1 + 2 --> 3 zurück\n\n###### Beim vierten Iterationsschritt\n\n```acc = 3```, weil es der Wert ist, den die Funktion im vorherigen Iterationsschritt zurückgegeben hat\n\n```n = 3```, viertes Element des *numbers*-Arrays\n\nDie Funktion gibt *acc* + *n* --> 3 + 3 --> 6 zurück\n\n###### [...] Beim letzten Iterationsschritt\n\n```acc = 15```, weil es der Wert ist, den die Funktion im vorherigen Iterationsschritt zurückgegeben hat\n\n```n = 6```, letztes Element des *numbers*-Arrays\n\nDie Funktion gibt *acc* + *n* --> 15 + 6 --> 21 zurück\n\nDa dies der letzte Iterationsschritt ist, gibt **.reduce** 21 zurück.\n\n##### Array.prototype.find()\n\n```js\nconst greaterThanZero = numbers.find(function(n) {\n  return n > 0; // gibt die Nummer zurück, die gerade größer als 0 ist\n});\nconsole.log(greaterThanZero); // 1\n```\n\n**Hinweis**: Du wirst diese Methode oft in Kombination mit [Pfeilfunktionen](#-pfeilfunktion) antreffen\n\nWir verwenden .find auf dem *numbers*-Array, .find iteriert über jedes Element des Arrays und übergibt es unserer Funktion, bis die Bedingung erfüllt ist. Das Ziel der Funktion ist es, das Element zurückzugeben, das die aktuelle Testfunktion erfüllt. Die .find-Methode führt die Callback-Funktion einmal für jeden Index des Arrays aus, bis der Callback einen wahren Wert zurückgibt.\n\n**Hinweis**: Sie gibt sofort den Wert des Elements zurück (das die Bedingung erfüllt), wenn gefunden. Andernfalls gibt sie undefined zurück.\n\n#### Externe Ressource\n\n- [Verständnis von map / filter / reduce in JS](https://hackernoon.com/understanding-map-filter-and-reduce-in-javascript-5df1c7eee464)\n\n### Spread-Operator \"...\"\n\nDer Spread-Operator ```...``` wurde mit ES2015 eingeführt und wird verwendet, um Elemente eines iterierbaren Objekts (wie ein Array) an Stellen auszubreiten, an denen mehrere Elemente passen können.\n\n#### Beispielcode\n\n```js\nconst arr1 = [\"a\", \"b\", \"c\"];\nconst arr2 = [...arr1, \"d\", \"e\", \"f\"]; // [\"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// \"a\"\n// \"b\"\n// [\"c\", \"d\", \"e\", \"f\"]\n```\n\n```js\nconst { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };\nconsole.log(x); // 1\nconsole.log(y); // 2\nconsole.log(z); // { a: 3, b: 4 }\n\nconst n = { x, y, ...z };\nconsole.log(n); // { x: 1, y: 2, a: 3, b: 4 }\n```\n\n#### Erklärung\n\n##### In Iterables (wie Arrays)\n\nWenn wir die folgenden zwei Arrays haben:\n\n```js\nconst arr1 = [\"a\", \"b\", \"c\"];\nconst arr2 = [arr1, \"d\", \"e\", \"f\"]; // [[\"a\", \"b\", \"c\"], \"d\", \"e\", \"f\"]\n```\n\n*arr2* das erste Element ist ein Array, weil *arr1* so, wie es ist, in *arr2* eingefügt wird. Aber was wir wollen, ist, dass *arr2* ein Array von Buchstaben ist. Um dies zu erreichen, können wir die Elemente von *arr1* in *arr2* *ausbreiten*.\n\nMit dem Spread-Operator\n\n```js\nconst arr1 = [\"a\", \"b\", \"c\"];\nconst arr2 = [...arr1, \"d\", \"e\", \"f\"]; // [\"a\", \"b\", \"c\", \"d\", \"e\", \"f\"]\n```\n\n##### Funktionsrestparameter\n\nIn Funktionsparametern können wir den Rest-Operator verwenden, um Parameter in einem Array einzufügen, über das wir iterieren können. Es gibt bereits ein **arguments**-Objekt, das an jede Funktion gebunden ist und einem Array mit allen Parametern entspricht, die in die Funktion eingegeben wurden.\n\n```js\nfunction myFunc() {\n  for (var i = 0; i < arguments.length; i++) {\n    console.log(arguments[i]);\n  }\n}\n\nmyFunc(\"Nick\", \"Anderson\", 10, 12, 6);\n// \"Nick\"\n// \"Anderson\"\n// 10\n// 12\n// 6\n```\n\nAber nehmen wir an, dass wir wollen, dass diese Funktion einen neuen Schüler mit seinen Noten und seinem Durchschnitt erstellt. Wäre es nicht praktischer, die ersten beiden Parameter in zwei separate Variablen zu extrahieren und dann alle Noten in einem Array zu haben, über das wir iterieren können?\n\nGenau das ermöglicht der Rest-Operator!\n\n```js\nfunction createStudent(firstName, lastName, ...grades) {\n  // firstName = \"Nick\"\n  // lastName = \"Anderson\"\n  // [10, 12, 6] -- \"...\" nimmt alle anderen übergebenen Parameter und erzeugt eine \"grades\"-Arrayvariable, die sie enthält\n\n  const avgGrade = grades.reduce((acc, curr) => acc + curr, 0) / grades.length; // berechnet den Durchschnitt aus den Noten\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// {\n//   firstName: \"Nick\",\n//   lastName: \"Anderson\",\n//   grades: [10, 12, 6],\n//   avgGrade: 9,33\n// }\n```\n\n> **Hinweis:** Die Funktion createStudent ist schlecht, weil wir nicht überprüfen, ob grades.length existiert oder verschieden von 0 ist. Aber so ist es einfacher zu lesen, deshalb habe ich diesen Fall nicht behandelt.\n\n##### Objekteigenschaften ausbreiten\n\nFür dieses Beispiel empfehle ich, die vorherigen Erklärungen zum Rest-Operator bei iterierbaren Objekten und Funktionsparametern zu lesen.\n\n```js\nconst myObj = { x: 1, y: 2, a: 3, b: 4 };\nconst { x, y, ...z } = myObj; // Objektdestrukturierung hier\nconsole.log(x); // 1\nconsole.log(y); // 2\nconsole.log(z); // { a: 3, b: 4 }\n\n// z sind die restlichen Eigenschaften des destrukturierten Objekts: myObj-Objekt minus x- und y-Eigenschaften, die destrukturiert wurden\n\nconst n = { x, y, ...z };\nconsole.log(n); // { x: 1, y: 2, a: 3, b: 4 }\n\n// Hier werden die Eigenschaften von z-Objekten in n ausgespreitet\n```\n\n#### Externe Ressourcen\n\n- [TC39 - Objekt rest/spread](https://github.com/tc39/proposal-object-rest-spread)\n- [Einführung in den Spread-Operator - WesBos](https://github.com/wesbos/es6-articles/blob/master/28%20-%20Spread%20Operator%20Introduction.md)\n- [JavaScript & der Spread-Operator](https://codeburst.io/javascript-the-spread-operator-a867a71668ca)\n- [6 großartige Verwendungen des Spread-Operators](https://davidwalsh.name/spread-operator)\n\n### Objekteigenschaften Kurzschreibweise\n\nWenn man einer Objekteigenschaft eine Variable zuweist, deren Name gleich dem Eigenschaftsnamen ist, kann man folgendes tun:\n\n```js\nconst x = 10;\nconst myObj = { x };\nconsole.log(myObj.x) // 10\n```\n\n#### Erklärung\n\nNormalerweise (vor ES2015) wenn du ein neues *Objektliteral* deklarierst und Variablen als Werte für Objekteigenschaften verwenden möchtest, würdest du diesen Code schreiben:\n\n```js\nconst x = 10;\nconst y = 20;\n\nconst myObj = {\n  x: x, // weist x Variable Wert myObj.x zu\n  y: y // weist y Variable Wert myObj.y zu\n};\n\nconsole.log(myObj.x) // 10\nconsole.log(myObj.y) // 20\n```\n\nWie du sehen kannst, ist das ziemlich wiederholend, weil die Namen der Eigenschaften von myObj den Variablennamen entsprechen, die du diesen zuweisen willst.\n\nMit ES2015 kannst du diese Abkürzung verwenden, wenn der Variablenname dem Namen der Eigenschaft entspricht:\n\n```js\nconst x = 10;\nconst y = 20;\n\nconst myObj = {\n  x,\n  y\n};\n\nconsole.log(myObj.x) // 10\nconsole.log(myObj.y) // 20\n```\n\n#### Externe Ressourcen\n\n- [Property shorthand - ES6 Features](http://es6-features.org/#PropertyShorthand)\n\n\n### Promises\n\nEin Promise ist ein Objekt, das synchron aus einer asynchronen Funktion zurückgegeben werden kann ([ref](https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-promise-27fc71e77261#3cd0)).\n\nPromises können verwendet werden, um der [Callback-Hölle](http://callbackhell.com/) zu entkommen, und sie begegnen uns in modernen JavaScript-Projekten immer häufiger.\n\n#### Beispielcode\n\n```js\nconst fetchingPosts = new Promise((res, rej) => {\n  $.get(\"/posts\")\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#### Erklärung\n\nWenn du eine *Ajax-Anfrage* machst, ist die Antwort nicht synchron, weil du eine Ressource anforderst, die einige Zeit zur Antwort braucht. Sie könnte sogar nie kommen, falls die angeforderte Ressource aus irgendeinem Grund nicht verfügbar ist (404).\n\nUm diese Art von Situation zu handhaben, hat uns ES2015 *Promises* gegeben. Promises können drei verschiedene Zustände haben:\n\n- Pending (Im Warten)\n- Fulfilled (Erfüllt)\n- Rejected (Abgelehnt)\n\nNehmen wir an, wir möchten Promises verwenden, um eine Ajax-Anfrage zu tätigen und die Ressource X zu holen.\n\n##### Das Promise erstellen\n\nZuerst erstellen wir ein Promise. Wir verwenden die jQuery get-Methode, um unsere Ajax-Anfrage an X zu stellen.\n\n```js\nconst xFetcherPromise = new Promise( // Erstelle Promise mit dem \"new\" Schlüsselwort und speichere es in einer Variable\n  function(resolve, reject) { // Der Promise-Konstruktor nimmt eine Funktion entgegen, die selbst die Parameter resolve und reject besitzt\n    $.get(\"X\") // Starte die Ajax-Anfrage\n      .done(function(X) { // Sobald die Anfrage beendet ist...\n        resolve(X); // ... erfülle das Promise mit dem Wert X als Parameter\n      })\n      .fail(function(error) { // Falls die Anfrage fehlschlägt...\n        reject(error); // ... lehne das Promise mit dem Fehler als Parameter ab\n      });\n  }\n)\n```\n\nWie im obigen Beispiel zu sehen ist, nimmt das Promise-Objekt eine *Executor*-Funktion entgegen, die zwei Parameter **resolve** und **reject** hat. Diese Parameter sind Funktionen, die, wenn aufgerufen, den Promise-Zustand *pending* jeweils in einen *fulfilled* und *rejected* Zustand überführen.\n\nDas Promise befindet sich in einem Pending-Zustand nach seiner Erstellung, und seine *Executor*-Funktion wird sofort ausgeführt. Sobald eine der Funktionen *resolve* oder *reject* in der *Executor*-Funktion aufgerufen wird, ruft das Promise seine zugehörigen Handler auf.\n\n##### Verwendung von Promise-Handlern\n\nUm das Ergebnis (oder den Fehler) des Promises zu erhalten, müssen wir ihm Handler zuweisen, indem wir Folgendes tun:\n\n```js\nxFetcherPromise\n  .then(function(X) {\n    console.log(X);\n  })\n  .catch(function(err) {\n    console.log(err)\n  })\n```\n\nWenn das Promise erfolgreich ist, wird *resolve* ausgeführt und die Funktion, die als `.then` Parameter übergeben wurde, wird ausgeführt.\n\nWenn es fehlschlägt, wird *reject* ausgeführt und die Funktion, die als `.catch` Parameter übergeben wurde, wird ausgeführt.\n\n> **Hinweis :** Wenn das Promise bereits erfüllt oder abgelehnt wurde, wenn ein entsprechender Handler angehängt wird, wird der Handler aufgerufen, sodass es keinen Wettlaufzustand zwischen dem Abschluss einer asynchronen Operation und dem Anhängen ihrer Handler gibt. [(Ref: MDN)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise#Description)\n\n#### Externe Ressourcen\n\n- [JavaScript Promises für Dummys - Jecelyn Yeen](https://scotch.io/tutorials/javascript-promises-for-dummies)\n- [JavaScript Promise API - David Walsh](https://davidwalsh.name/promises)\n- [Promises verwenden - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises)\n- [Was ist ein Promise - Eric Elliott](https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-promise-27fc71e77261)\n- [JavaScript Promises: Eine Einführung - Jake Archibald](https://developers.google.com/web/fundamentals/getting-started/primers/promises)\n- [Promise Dokumentation - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)\n\n### Template Literale\n\nTemplate Literale sind eine [*Ausdrucksinterpolation*](https://en.wikipedia.org/wiki/String_interpolation) für ein- und mehrzeilige Strings.\n\nAnders ausgedrückt, handelt es sich um eine neue String-Syntax, in der du bequem jede JavaScript-Ausdrücke verwenden kannst (beispielsweise Variablen).\n\n#### Beispielcode\n\n```js\nconst name = \"Nick\";\n`Hallo ${name}, der folgende Ausdruck ist gleich vier : ${2+2}`;\n\n// Hallo Nick, der folgende Ausdruck ist gleich vier: 4\n```\n\n#### Externe Ressourcen\n\n- [String-Interpolation - ES6 Features](http://es6-features.org/#StringInterpolation)\n- [ES6 Template Literale - Addy Osmani](https://developers.google.com/web/updates/2015/01/ES6-Template-Strings)\n\n### Tagged Template Literale\n\nTemplate Tags sind *Funktionen, die einem [Template Literal](#template-literals) vorangestellt werden können*. Wenn eine Funktion auf diese Weise aufgerufen wird, ist der erste Parameter ein Array der *Strings*, die zwischen den interpolierten Variablen des Templates auftreten, und die nachfolgenden Parameter sind die interpolierten Werte. Verwende einen Spread-Operator `...`, um alle zu erfassen. [(Ref: MDN)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#Tagged_template_literals).\n\n> **Hinweis :** Eine berühmte Bibliothek namens [styled-components](https://www.styled-components.com/) setzt schwer auf dieses Feature.\n\nHier ist ein Spielzeugbeispiel, wie sie funktionieren.\n```js\nfunction highlight(strings, ...values) {\n  const interpolation = strings.reduce((prev, current) => {\n    return prev + current + (values.length ? \"<mark>\" + values.shift() + \"</mark>\" : \"\");\n  }, \"\");\n\n  return interpolation;\n}\n\nconst condiment = \"Marmelade\";\nconst meal = \"Toast\";\n\nhighlight`Ich mag ${condiment} auf ${meal}.`;\n// \"Ich mag <mark>Marmelade</mark> auf <mark>Toast</mark>.\"\n```\n\nEin interessanteres Beispiel:\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 = ['Äpfel', 'Bananen', 'Kirschen'];\ncomma`Ich mag ${snacks} zum Knabbern.`;\n// \"Ich mag Äpfel, Bananen, Kirschen zum Knabbern.\"\n```\n\n#### Externe Ressourcen\n- [Wes Bos zu gekennzeichneten Template Literalen](http://wesbos.com/tagged-template-literals/)\n- [Bibliothek von gängigen Template Tags](https://github.com/declandewet/common-tags)\n\n### Imports / Exports\n\nES6-Module werden verwendet, um auf Variablen oder Funktionen in einem Modul zuzugreifen, die explizit von den Modulen exportiert wurden, die es importiert.\n\nIch empfehle dringend, sich die Ressourcen von MDN zu Import/Export anzusehen (siehe externe Ressourcen unten), da sie sowohl unkompliziert als auch vollständig sind.\n\n#### Erklärung mit Beispielcode\n\n##### Benannte Exports\n\nMit benannten Exports können mehrere Werte aus einem Modul exportiert werden.\n\n> **Hinweis :** Du kannst nur [Erstklassige Bürger](https://en.wikipedia.org/wiki/First-class_citizen) mit einem Namen benannt exportieren.\n\n```js\n// mathConstants.js\nexport const pi = 3.14;\nexport const exp = 2.7;\nexport const alpha = 0.35;\n\n// -------------\n\n// myFile.js\nimport { pi, exp } from './mathConstants.js'; // Benannter Import -- Destructuring-ähnliche Syntax\nconsole.log(pi) // 3.14\nconsole.log(exp) // 2.7\n\n// -------------\n\n// mySecondFile.js\nimport * as constants from './mathConstants.js'; // Injiziere alle exportierten Werte in die Variable constants\nconsole.log(constants.pi) // 3.14\nconsole.log(constants.exp) // 2.7\n```\n\nObwohl benannte Imports wie *Destructuring* aussehen, haben sie eine andere Syntax und sind nicht dasselbe. Sie unterstützen keine Standardwerte oder *tiefes* Destructuring.\n\nAußerdem kannst du Aliase verwenden, aber die Syntax ist anders als die, die beim Destructuring verwendet wird:\n\n```js\nimport { foo as bar } from 'myFile.js'; // foo wird importiert und in eine neue bar Variable injiziert\n```\n\n##### Standardimport / export\n\nBezüglich des Standardexports gibt es nur einen einzigen Standardexport pro Modul. Ein Standardexport kann eine Funktion, eine Klasse, ein Objekt oder irgendetwas anderes sein. Dieser Wert wird als der \"Haupt\"-exportierte Wert angesehen, da er am einfachsten zu importieren ist. [Ref: MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export#Description)\n\n```js\n// coolNumber.js\nconst ultimateNumber = 42;\nexport default ultimateNumber;\n\n// ------------\n\n// myFile.js\nimport number from './coolNumber.js';\n// Standardexport, unabhängig von seinem Namen, wird automatisch in die Variable number injiziert;\nconsole.log(number) // 42\n```\n\nExportieren einer Funktion:\n\n```js\n// sum.js\nexport default function sum(x, y) {\n  return x + y;\n}\n// -------------\n\n// myFile.js\nimport sum from './sum.js';\nconst result = sum(1, 2);\nconsole.log(result) // 3\n```\n\n#### Externe Ressourcen\n\n- [ES6-Module in Stichpunkten](https://ponyfoo.com/articles/es6#modules)\n- [Export - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export)\n- [Import - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import)\n- [Verständnis von ES6-Modulen](https://www.sitepoint.com/understanding-es6-modules/)\n- [Destructuring Sonderfall - Importanweisungen](https://ponyfoo.com/articles/es6-destructuring-in-depth#special-case-import-statements)\n- [Missverständnisse bezüglich ES6-Modulen - Kent C. Dodds](https://medium.com/@kentcdodds/misunderstanding-es6-modules-upgrading-babel-tears-and-a-solution-ad2d5ab93ce0)\n- [Module in JavaScript](http://exploringjs.com/es6/ch_modules.html#sec_modules-in-javascript)\n\n### <a name=\"this_def\"></a> JavaScript *this*\n\nDer *this*-Operator verhält sich anders als in anderen Sprachen und wird in den meisten Fällen durch die Art und Weise bestimmt, wie eine Funktion aufgerufen wird. ([Ref: MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this)).\n\nDiese Vorstellung hat viele Feinheiten und ist ziemlich schwierig, daher schlage ich vor, in die unten aufgeführten externen Ressourcen einzutauchen. Ich werde das wiedergeben, was ich persönlich im Kopf habe, um zu bestimmen, was *this* gleich ist. Ich habe diesen Tipp aus [diesem Artikel von Yehuda Katz](http://yehudakatz.com/2011/08/11/understanding-javascript-function-invocation-and-this/) gelernt.\n\n```js\nfunction myFunc() {\n  ...\n}\n\n// Nach jeder Anweisung findest du den Wert von *this* in myFunc\n\nmyFunc.call(\"myString\", \"hallo\") // \"myString\" -- der erste .call-Parameterwert wird in *this* injiziert\n\n// Im Nicht-Strict-Modus\nmyFunc(\"hallo\") // window -- myFunc() ist syntaktischer Zucker für myFunc.call(window, \"hallo\")\n\n// Im Strict-Modus\nmyFunc(\"hallo\") // undefined -- myFunc() ist syntaktischer Zucker für myFunc.call(undefined, \"hallo\")\n```\n\n```js\nvar person = {\n  myFunc: function() { ... }\n}\n\nperson.myFunc.call(person, \"test\") // person Objekt -- der erste call-Parameter wird in *this* injiziert\nperson.myFunc(\"test\") // person Objekt -- person.myFunc() ist syntaktischer Zucker für person.myFunc.call(person, \"test\")\n\nvar myBoundFunc = person.myFunc.bind(\"hallo\") // Erstellt eine neue Funktion, in der wir \"hallo\" in den *this*-Wert injizieren\nperson.myFunc(\"test\") // person Objekt -- Die bind-Methode hat keine Auswirkung auf die Originalmethode\nmyBoundFunc(\"test\") // \"hallo\" -- myBoundFunc ist person.myFunc mit \"hallo\" gebunden an *this*\n```\n\n#### Externe Ressourcen\n\n- [Verständnis von JavaScript-Funktionsaufrufen und \"this\" - Yehuda Katz](http://yehudakatz.com/2011/08/11/understanding-javascript-function-invocation-and-this/)\n- [JavaScript this - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this)\n\n### Klasse\n\nJavaScript ist eine [prototypbasierte](https://en.wikipedia.org/wiki/Prototype-based_programming) Sprache (während Java beispielsweise eine [klassenbasierte](https://en.wikipedia.org/wiki/Class-based_programming) Sprache ist). ES6 hat JavaScript-Klassen eingeführt, die als syntaktischer Zucker für die prototypbasierte Vererbung gedacht sind und **kein** neues klassenbasiertes Vererbungsmodell darstellen ([ref](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes)).\n\nDas Wort *class* ist tatsächlich irreführend, wenn du mit Klassen in anderen Sprachen vertraut bist. Wenn du es bist, vermeide Annahmen darüber, wie JavaScript-Klassen funktionieren, auf dieser Grundlage und betrachte es als eine völlig unterschiedliche Vorstellung.\n\nDa dieses Dokument nicht den Anspruch hat, dir die Sprache von Grund auf beizubringen, gehe ich davon aus, dass du weißt, was Prototypen sind und wie sie sich verhalten. Wenn nicht, sieh dir die unten aufgeführten externen Ressourcen nach dem Beispielcode an.\n\n\n#### Beispiele\n\nVor ES6, Prototyp-Syntax:\n\n```js\nvar Person = function(name, age) {\n  this.name = name;\n  this.age = age;\n}\nPerson.prototype.stringSentence = function() {\n  return \"Hallo, mein Name ist \" + this.name + \" und ich bin \" + this.age;\n}\n```\n\nMit ES6-Klassensyntax:\n\n```js\nclass Person {\n  constructor(name, age) {\n    this.name = name;\n    this.age = age;\n  }\n\n  stringSentence() {\n    return `Hallo, mein Name ist ${this.name} und ich bin ${this.age}`;\n  }\n}\n\nconst myPerson = new Person(\"Manu\", 23);\nconsole.log(myPerson.age) // 23\nconsole.log(myPerson.stringSentence()) // \"Hallo, mein Name ist Manu und ich bin 23\n```\n\n#### Externe Ressourcen\n\nZum Verständnis von Prototypen:\n\n- [Understanding Prototypes in JS - Yehuda Katz](http://yehudakatz.com/2011/08/12/understanding-prototypes-in-javascript/)\n- [A plain English guide to JS prototypes - Sebastian Porto](http://sporto.github.io/blog/2013/02/22/a-plain-english-guide-to-javascript-prototypes/)\n- [Vererbung und die Prototyp-Kette - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain)\n\nZum Verständnis von Klassen:\n\n- [ES6 Klassen im Detail - Nicolas Bevacqua](https://ponyfoo.com/articles/es6-classes-in-depth)\n- [ES6-Features - Klassen](http://es6-features.org/#ClassDefinition)\n- [JavaScript Klassen - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes)\n\n### `Extends` und `super`\n\nDas Schlüsselwort `extends` wird in Klassendeklarationen oder Klassenausdrücken verwendet, um eine Klasse zu erstellen, die ein Kind einer anderen Klasse ist ([Ref: MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/extends)). Die Unterklasse erbt alle Eigenschaften der Oberklasse und kann zusätzlich neue Eigenschaften hinzufügen oder die geerbten modifizieren.\n\nDas Schlüsselwort `super` wird verwendet, um Funktionen eines Oberobjekts aufzurufen, einschließlich seines Konstruktors.\n\n- Das Schlüsselwort `super` muss verwendet werden, bevor das Schlüsselwort `this` im Konstruktor verwendet wird.\n- Der Aufruf von `super()` ruft den Konstruktor der Oberklasse auf. Wenn du einige Argumente im Konstruktor einer Klasse an den Konstruktor ihres Elternteils weitergeben möchtest, rufst du ihn mit `super(arguments)` auf.\n- Wenn die Oberklasse eine Methode (auch statisch) namens `X` hat, kannst du mit `super.X()` diese in einer Unterklasse aufrufen.\n\n#### Beispielcode\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 `Hallo, ich bin ein ${this.name}`;\n  }\n}\n\nclass Square extends Polygon {\n  constructor(length) {\n    // Hier wird der Konstruktor der Oberklasse mit den Längen\n    // für die Breite und Höhe des Polygons aufgerufen\n    super(length, length);\n    // Hinweis: In abgeleiteten Klassen muss super() aufgerufen werden, bevor du\n    // 'this' verwenden kannst. Wenn du dies auslässt, wird ein Referenzfehler verursacht.\n    this.name = 'Quadrat';\n    this.length = length;\n  }\n\n  getCustomHelloPhrase() {\n    const polygonPhrase = super.getHelloPhrase(); // Zugriff auf die Elternmethode mit super.X()-Syntax\n    return `${polygonPhrase} mit einer Länge von ${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) // 100\nconsole.log(mySquare.getHelloPhrase()) // 'Hallo, ich bin ein Quadrat' -- Square erbt von Polygon und hat Zugriff auf seine Methoden\nconsole.log(mySquare.getCustomHelloPhrase()) // 'Hallo, ich bin ein Quadrat mit einer Länge von 10'\n```\n\n**Hinweis :** Wenn wir versucht hätten, `this` vor dem Aufruf von `super()` in der Square-Klasse zu verwenden, wäre ein ReferenceError ausgelöst worden:\n\n```js\nclass Square extends Polygon {\n  constructor(length) {\n    this.height; // ReferenceError, super muss zuerst aufgerufen werden!\n\n    // Hier wird der Konstruktor der Oberklasse mit den Längen\n    // für die Breite und Höhe des Polygons aufgerufen\n    super(length, length);\n\n    // Hinweis: In abgeleiteten Klassen muss super() aufgerufen werden bevor du\n    // 'this' verwenden kannst. Wenn du dies auslässt, wird ein Referenzfehler verursacht.\n    this.name = 'Quadrat';\n  }\n}\n```\n\n#### Externe Ressourcen\n\n- [Extends - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/extends)\n- [Super-Operator - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/super)\n- [Vererbung - MDN](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Inheritance)\n\n### Async Await\n\nZusätzlich zu [Promises](#promises) gibt es eine neue Syntax, die du vielleicht antriffst, um asynchronen Code zu handhaben, nämlich *async / await*.\n\nDer Zweck von async/await-Funktionen ist es, die Verwendung von Promises synchron zu vereinfachen und ein Verhalten für eine Gruppe von Promises durchzuführen. Genau wie Promises ähnlich wie strukturierte Callbacks sind, ist async/await ähnlich wie die Kombination von Generatoren und Promises. Async-Funktionen geben *immer* ein Promise zurück. ([Ref: MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function))\n\n> **Hinweis :** Du musst verstehen, was Promises sind und wie sie funktionieren, bevor du versuchst, async / await zu verstehen, da diese darauf basieren.\n\n> **Hinweis 2:** [*await* muss in einer *async* Funktion verwendet werden](https://hackernoon.com/6-reasons-why-javascripts-async-await-blows-promises-away-tutorial-c7ec10518dd9#f3f0), was bedeutet, dass du await nicht auf der obersten Ebene unseres Codes verwenden kannst, da dies nicht innerhalb einer async-Funktion ist.\n\n#### Beispielcode\n\n```js\nasync function getGithubUser(username) { // das async-Schlüsselwort ermöglicht die Verwendung von await in der Funktion und bedeutet, dass die Funktion ein Promise zurückgibt\n  const response = await fetch(`https://api.github.com/users/${username}`); // Die Ausführung wird hier pausiert, bis das von fetch zurückgegebene Promise aufgelöst ist\n  return response.json();\n}\n\ngetGithubUser('mbeaudru')\n  .then(user => console.log(user)) // das Nutzer-Response loggen - await-Syntax kann nicht verwendet werden, da dieser Code nicht in einer async-Funktion ist\n  .catch(err => console.log(err)); // wenn ein Fehler in unserer async-Funktion geworfen wird, werden wir ihn hier erwischen\n```\n\n#### Erklärung mit Beispielcode\n\n*Async / Await* basiert auf Promises, ermöglicht aber eine imperativere Code-Stil.\n\nDer *async*-Operator markiert eine Funktion als asynchron und wird immer ein *Promise* zurückgeben. Du kannst den *await*-Operator in einer *async*-Funktion verwenden, um die Ausführung in dieser Zeile zu pausieren, bis das vom Ausdruck zurückgegebene Promise entweder aufgelöst oder abgelehnt wird.\n\n```js\nasync function myFunc() {\n  // wir können den await-Operator verwenden, weil diese Funktion async ist\n  return \"hallo welt\";\n}\n\nmyFunc().then(msg => console.log(msg)) // \"hallo welt\" -- der Rückgabewert von myFunc wird durch den async-Operator in ein Promise umgewandelt\n```\n\nWenn das *return*-Statement einer async-Funktion erreicht wird, wird das Promise mit dem zurückgegebenen Wert erfüllt. Wenn innerhalb einer async-Funktion ein Fehler geworfen wird, wechselt der Promise-Zustand zu *abgelehnt*. Wenn aus einer async-Funktion kein Wert zurückgegeben wird, wird trotzdem ein Promise zurückgegeben und löst ohne Wert auf, wenn die Ausführung der async-Funktion abgeschlossen ist.\n\nDer *await*-Operator wird verwendet, um auf die Erfüllung eines *Promise* zu warten und kann nur im Körper einer *async*-Funktion verwendet werden. Beim Auftreffen wird die Codeausführung pausiert, bis das Promise erfüllt ist.\n\n> **Hinweis :** *fetch* ist eine Funktion, die ein Promise zurückgibt, das einen AJAX-Anfrage ermöglicht\n\nSehen wir uns an, wie wir einen Github-Nutzer mit Promises zuerst abrufen würden:\n\n```js\nfunction getGithubUser(username) {\n  return fetch(`https://api.github.com/users/${username}`).then(response => response.json());\n}\n\ngetGithubUser('mbeaudru')\n  .then(user => console.log(user))\n  .catch(err => console.log(err));\n```\n\nHier ist das äquivalente *async / await*:\n\n```js\nasync function getGithubUser(username) { // promise + await-Schlüsselwortverwendung erlaubt\n  die Antwort = await fetch(`https://api.github.com/users/${username}`); // Die Ausführung stoppt hier, bis das fetch-Promise erfüllt ist\n  return response.json();\n}\n\ngetGithubUser('mbeaudru')\n  .then(user => console.log(user))\n  .catch(err => console.log(err));\n```\n\nDie *async / await*-Syntax ist besonders praktisch, wenn du Promises verketten musst, die voneinander abhängig sind.\n\nWenn du beispielsweise einen Token abrufen musst, um einen Blogeintrag in einer Datenbank und dann die Autoreninformationen abzurufen:\n\n> **Hinweis :** *await*-Ausdrücke müssen in Klammern eingefasst werden, um Methoden und Eigenschaften des aufgelösten Werts auf derselben Zeile aufzurufen.\n\n```js\nasync function fetchPostById(postId) {\n  const token = (await fetch('token_url')).json().token;\n  const post = (await fetch(`/posts/${postId}?token=${token}`)).json();\n  der Autor = (await fetch(`/users/${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##### Fehlerbehandlung\n\nSofern wir *try / catch*-Blöcke nicht um *await*-Ausdrücke herum hinzufügen, werden unerfasste Ausnahmen – unabhängig davon, ob sie im Körper Ihrer *async*-Funktion oder während ihrer Unterbrechung während *await* geworfen wurden – das Promise, das von der *async*-Funktion zurückgegeben wird, ablehnen. Die Verwendung des `throw`-Statements in einer asynchronen Funktion ist dasselbe wie die Rückgabe eines Promises, das abgelehnt wird. [(Ref: PonyFoo)](https://ponyfoo.com/articles/understanding-javascript-async-await#error-handling).\n\n> **Hinweis :** Promises verhalten sich gleich!\n\nMit Promises sieht die Fehlerbearbeitungskette so aus:\n\n```js\nfunction getUser() { // Dieses Promise wird abgelehnt!\n  return new Promise((res, rej) => rej(\"Benutzer nicht gefunden!\"));\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)); // \"Benutzer nicht gefunden!\"\n```\n\nDas Äquivalent mit *async / await*:\n\n```js\nasync function getUser() { // Das zurückgegebene Promise wird abgelehnt sein!\n  wirf \"Benutzer nicht gefunden!\";\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)); // \"Benutzer nicht gefunden!\"\n```\n\n#### Externe Ressourcen\n\n- [Async/Await - JavaScript.Info](https://javascript.info/async-await)\n- [ES7 Async/Await](http://rossboucher.com/await/#/)\n- [6 Gründe, warum JavaScripts Async/Await Promises wegblasen](https://hackernoon.com/6-reasons-why-javascripts-async-await-blows-promises-away-tutorial-c7ec10518dd9)\n- [JavaScript awaits](https://dev.to/kayis/javascript-awaits)\n- [Verwendung von Async Await in Express mit Node 8](https://medium.com/@Abazhenov/using-async-await-in-express-with-node-8-b8af872c0016)\n- [Async-Funktion](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)\n- [Await](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await)\n- [Verwendung von async / await in express mit node 8](https://medium.com/@Abazhenov/using-async-await-in-express-with-node-8-b8af872c0016)\n\n\n### Truthy / Falsy\n\nIn JavaScript ist ein Truthy- oder Falsy-Wert ein Wert, der in einen Boolean umgewandelt wird, wenn er in einem booleschen Kontext ausgewertet wird. Ein Beispiel für einen booleschen Kontext wäre die Auswertung einer ```if```-Bedingung:\n\nJeder Wert wird zu ```true``` umgewandelt, es sei denn, sie sind gleich:\n\n- ```false```\n- ```0```\n- ```\"\"``` (leerer String)\n- ```null```\n- ```undefined```\n- ```NaN```\n\nHier sind Beispiele für *booleschen Kontext*:\n\n- Auswertung einer ```if```-Bedingung\n\n```js\nif (myVar) {}\n```\n\n```myVar``` kann ein [first-class citizen](https://en.wikipedia.org/wiki/First-class_citizen) (Variable, Funktion, Boolean) sein, aber es wird in einen Boolean umgewandelt, weil es in einem booleschen Kontext ausgewertet wird.\n\n- Nach dem logischen **NICHT** ```!```-Operator\n\nDieser Operator gibt false zurück, wenn sein einzelner Operand in true umgewandelt werden kann; andernfalls gibt er true zurück.\n\n```js\n!0 // true -- 0 ist falsy, also gibt es true zurück\n!!0 // false -- 0 ist falsy, also gibt !0 true zurück, daher liefert !(!0) false\n!!\"\" // false -- leerer String ist falsy, also NICHT (NICHT false) ist gleich false\n```\n\n- Mit dem *Boolean*-Objektkonstruktor\n\n```js\nnew Boolean(0) // false\nnew Boolean(1) // true\n```\n\n- In einer ternären Auswertung\n\n```js\nmyVar ? \"truthy\" : \"falsy\"\n```\n\nmyVar wird in einem booleschen Kontext ausgewertet.\n\nSei vorsichtig beim Vergleichen von 2 Werten. Die Objektwerte (die zu true umgewandelt werden sollten) werden **nicht** in einen Boolean umgewandelt, sondern es wird gezwungen, in einen primitiven Wert mithilfe der [ToPrimitives-Spezifikation](http://javascript.info/object-toprimitive) umgewandelt. Intern, wenn ein Objekt mit einem Boolean-Wert wie `[] == true` verglichen wird, macht es `[].toString() == true`, also...\n\n```js\nlet a = [] == true // a ist false, da [].toString() \"\" zurückgibt.\nlet b = [1] == true // b ist true, da [1].toString() \"1\" zurückgibt.\nlet c = [2] == true // c ist false, da [2].toString() \"2\" zurückgibt.\n```\n\n#### Externe Ressourcen\n\n- [Truthy (MDN)](https://developer.mozilla.org/en-US/docs/Glossary/Truthy)\n- [Falsy (MDN)](https://developer.mozilla.org/en-US/docs/Glossary/Falsy)\n- [Truthy und Falsy-Werte in JS - Josh Clanton](http://adripofjavascript.com/blog/drips/truthy-and-falsy-values-in-javascript.html)\n\n### Anamorphismen und Katamorphismen\n\n#### Anamorphismen\n\nAnamorphismen sind Funktionen, die von einem Objekt auf eine komplexere Struktur abbilden, die den Typ des Objekts enthält. Es ist der Prozess des *Entfaltens* einer einfachen Struktur in eine komplexere. Betrachte das Entfalten einer Ganzzahl in eine Liste von Ganzzahlen. Die Ganzzahl ist unser Ausgangsobjekt und die Liste von Ganzzahlen ist die komplexere Struktur.\n\n**Beispielcode**\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  //=> [ 5, 4, 3, 2, 1 ]\n```\n\n#### Katamorphismen\n\nKatamorphismen sind das Gegenteil von Anamorphismen, da sie Objekte einer komplexeren Struktur nehmen und sie in einfachere Strukturen *falten*. Nehme das folgende Beispiel `product`, welches eine Liste von Ganzzahlen nimmt und eine einzelne Ganzzahl zurückgibt.\n\n**Beispielcode**\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)) // 120\n```\n\n#### Externe Ressourcen\n\n* [Anamorphisms in JavaScript](http://raganwald.com/2016/11/30/anamorphisms-in-javascript.html)\n* [Anamorphism](https://en.wikipedia.org/wiki/Anamorphism)\n* [Catamorphism](https://en.wikipedia.org/wiki/Catamorphism)\n\n### Generatoren\n\nEine andere Möglichkeit, die Funktion `downToOne` zu schreiben, ist die Verwendung eines Generators. Um ein `Generator`-Objekt zu instanziieren, muss man die `function *`-Deklaration verwenden. Generatoren sind Funktionen, die verlassen und später mit gespeichertem Kontext (Variablenbindungen) wieder betreten werden können.\n\nZum Beispiel kann die oben genannte Funktion `downToOne` wie folgt umgeschrieben werden:\n\n```js\nfunction * downToOne(n) {\n  for (let i = n; i > 0; --i) {\n    yield i;\n  }\n}\n\n[...downToOne(5)] // [ 5, 4, 3, 2, 1 ]\n```\n\nGeneratoren geben ein iterierbares Objekt zurück. Wenn die `next()`-Funktion des Iterators aufgerufen wird, wird sie ausgeführt, bis zum ersten `yield`-Ausdruck, welcher den zurückzugebenden Wert vom Iterator angibt oder mit `yield*`, das an eine andere Generatorfunktion delegiert. Wenn in dem Generator eine `return`-Anweisung aufgerufen wird, wird der Generator als beendet markiert und gibt den Rückgabewert zurück. Weitere Aufrufe von `next()` geben keine neuen Werte zurück.\n\n**Beispielcode**\n\n```js\n// Yield-Beispiel\nfunction * idMaker() {\n  var index = 0;\n  while (index < 2) {\n    yield index;\n    index = index + 1;\n  }\n}\n\nvar gen = idMaker();\n\ngen.next().value; // 0\ngen.next().value; // 1\ngen.next().value; // undefined\n```\n\nDer `yield*`-Ausdruck ermöglicht einem Generator, eine andere Generatorfunktion während der Iteration aufzurufen.\n\n```js\n// Yield * Beispiel\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; // 10\ngen.next().value; // 11\ngen.next().value; // 12\ngen.next().value; // 13\ngen.next().value; // 20\n```\n\n```js\n// Generator Return-Beispiel\nfunction* yieldAndReturn() {\n  yield \"Y\";\n  return \"R\";\n  yield \"unerreichbar\";\n}\n\nvar gen = yieldAndReturn()\ngen.next(); // { value: \"Y\", done: false }\ngen.next(); // { value: \"R\", done: true }\ngen.next(); // { value: undefined, done: true }\n```\n\n#### Externe Ressourcen\n\n* [Mozilla MDN Web Docs, Iteratoren und Generatoren](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators#Generators)\n\n### Statische Methoden\n\n#### Kurze Erklärung\n\nDas Schlüsselwort `static` wird in Klassen verwendet, um statische Methoden zu deklarieren. Statische Methoden sind Funktionen in einer Klasse, die zum Klassenobjekt gehören und nicht für irgendeine Instanz dieser Klasse verfügbar sind.\n\n#### Beispielcode\n\n```js\nclass Repo {\n  static getName() {\n    return \"Repo name is modern-js-cheatsheet\"\n  }\n}\n\n// Beachte, dass wir keine Instanz der Repo-Klasse erstellen mussten\nconsole.log(Repo.getName()) // Der Name des Repos ist modern-js-cheatsheet\n\nlet r = new Repo();\nconsole.log(r.getName()) // Ungefangener TypeError: r.getName ist keine Funktion\n```\n\n#### Ausführliche Erklärung\n\nStatische Methoden können innerhalb einer anderen statischen Methode mithilfe des Schlüsselworts `this` aufgerufen werden, dies funktioniert jedoch nicht für nicht-statische Methoden. Nicht-statische Methoden können nicht direkt auf statische Methoden mit dem Schlüsselwort `this` zugreifen.\n\n##### Andere statische Methoden aus einer statischen Methode aufrufen.\n\nUm eine statische Methode aus einer anderen statischen Methode aufzurufen, kann das Schlüsselwort `this` verwendet werden wie folgt;\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()) // Der Name des Repos ist modern-js-cheatsheet-added-this\n```\n\n##### Statische Methoden aus nicht-statischen Methoden aufrufen.\n\nNicht-statische Methoden können auf zwei Weisen statische Methoden aufrufen;\n1. ###### Mit dem Klassennamen.\n\nUm Zugriff auf eine statische Methode von einer nicht-statischen Methode zu bekommen, verwenden wir den Klassennamen und rufen die statische Methode wie eine Eigenschaft auf. z.B `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// Wir müssen die Klasse instanziieren, um nicht-statische Methoden zu verwenden\nlet r = new Repo()\nconsole.log(r.useName()) // Der Name des Repos ist modern-js-cheatsheet und enthält einige wirklich wichtige Dinge\n```\n\n2. ###### Mit dem Konstruktor\n\nStatische Methoden können als Eigenschaften des Konstruktorobjekts aufgerufen werden.\n\n```js\nclass Repo {\n  static getName() {\n    return \"Repo name is modern-js-cheatsheet\"\n  }\n\n  useName() {\n    // Ruft die statische Methode als Eigenschaft des Konstruktors auf\n    return this.constructor.getName() + ' and it contains some really important stuff'\n  }\n}\n\n// Wir müssen die Klasse instanziieren, um nicht-statische Methoden zu verwenden\nlet r = new Repo()\nconsole.log(r.useName()) // Der Name des Repos ist modern-js-cheatsheet und enthält einige wirklich wichtige Dinge\n```\n\n#### Externe Ressourcen\n- [static keyword- MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/static)\n- [Statische Methoden- Javascript.info](https://javascript.info/class#static-methods)\n- [Statische Mitglieder in ES6- OdeToCode](http://odetocode.com/blogs/scott/archive/2015/02/02/static-members-in-es6.aspx)\n\n## Glossar\n\n### <a name=\"scope_def\"></a> Scope\n\nDer Kontext, in dem Werte und Ausdrücke \"sichtbar\" sind oder referenziert werden können. Wenn eine Variable oder ein anderer Ausdruck \"nicht im aktuellen Scope\" ist, dann ist er nicht zur Verwendung verfügbar.\n\nQuelle: [MDN](https://developer.mozilla.org/en-US/docs/Glossary/Scope)\n\n### <a name=\"mutation_def\"></a> Variablenmutation\n\nVon einer Variablen wird gesagt, dass sie mutiert wurde, wenn ihr anfänglicher Wert sich danach geändert hat.\n\n```js\nvar myArray = [];\nmyArray.push(\"firstEl\") // myArray wird mutiert\n```\n\nEine Variable wird als *unveränderlich* bezeichnet, wenn sie nicht mutiert werden kann.\n\n[Schau dir den MDN Mutable-Artikel an](https://developer.mozilla.org/en-US/docs/Glossary/Mutable) für weitere Details.\n"
  },
  {
    "path": "translations/fa-IR.md",
    "content": "# برگه تقلب جاوااسکریپت مدرن\n\n## مقدمه\n\n### انگیزه\n\nاین سند، یک برگه تقلب برای مسائلی در جاوااسکپت است که به دفعات در کار با پروژه‌های مدرن و جدیدترین نمونه‌های کد با آن‌ها مواجه خواهید شد.\n\nاین راهنما قصد ندارد جاوااسکریپت را از بیخ آموزش بدهد بلکه می‌خواهد کمکی باشد برای دانش مقدماتی توسعه‌دهندگانی که ممکن است به واسطه مفاهیم جاوااسکریپت به کار برده شده در کدهای مدرن (مثلا در یادگیری ری‌اکت) با آن‌ها دست و پنجه نرم کنند.\n\nدر کنار این، تلاش می‌کنم گاهی نکاتی شخصی را ارائه دهم که ممکن است بحث برانگیز باشند اما هر کجا به آن‌ها اشاره کنم، بیان خواهم کرد که آن موارد، پیشنهادهای شخصی‌ام هستند.\n\n> **نکته:** بیشتر مفاهمیمی که اینجا معرفی می‌شوند از به‌روزرسانی زبان جاوااسکریپت (ES2015 یا آن‌طور که معمولا گفته می‌شود ES6) می‌آیند. می‌توانید ویژگی‌های جدیدی که در این به‌روزرسانی اضافه شده‌اند را [این‌ جا](http://es6-features.org/) پیدا کنید که بسیار خوب ارائه شده‌اند.\n\n## منابع مکمل\n\nپیشنهاد می‌کنم وقتی در درک یک مفهوم دچار مشکل می‌شوید، در منابع زیر دنبال پاسخ بگردید:\n\n- [MDN (Mozilla Developer Network)](https://developer.mozilla.org/en-US/search?q=)\n- [You don't know JS (book)](https://github.com/getify/You-Dont-Know-JS)\n- [Eloquent JavaScript (book)](https://eloquentjavascript.net)\n- [Douglas Crockford's blog](https://www.crockford.com/javascript/)\n- [ES6 Features with examples](http://es6-features.org)\n- [Wes Bos blog (ES6)](http://wesbos.com/category/es6/)\n- [Javascript Basics for Beginners](https://www.udacity.com/course/javascript-basics--ud804) - a free Udacity course\n- [Reddit (JavaScript)](https://www.reddit.com/r/javascript/)\n- [Google](https://www.google.com/) to find specific blog and resources\n- [StackOverflow](https://stackoverflow.com/questions/tagged/javascript)\n\n## فهرست مطالب\n\n- [برگه تقلب جاوااسکریپت مدرن](#برگه-تقلب-جاوااسکریپت-مدرن)\n  - [مقدمه](#مقدمه)\n    - [انگیزه](#انگیزه)\n    - [منابع مکمل](#منابع-مکمل)\n  - [فهرست مطالب](#فهرست-مطالب)\n  - [مفاهیم](#مفاهیم)\n    - [اعلان متغیر: var، const، let](#اعلان-متغیر-var-const-let)\n      - [توضیح کوتاه](#توضیح-کوتاه)\n      - [نمونه کد](#نمونه-کد)\n      - [توضیح مبسوط](#توضیح-مبسوط)\n      - [منابع خارجی](#منابع-خارجی)\n    - [تابع پیکانی](#تابع-پیکانی)\n      - [نمونه کد](#نمونه-کد-1)\n      - [توضیح مبسوط](#توضیح-مبسوط-1)\n        - [اختصار](#اختصار)\n        - [ارجاع this](#ارجاع-this)\n      - [منابع مفید](#منابع-مفید)\n    - [مقدار پیش‌فرض پارامتر تابع](#مقدار-پیشفرض-پارامتر-تابع)\n      - [منابع خارجی](#منابع-خارجی-1)\n    - [تجزیه اشیاء و آرایه‌ها](#تجزیه-اشیاء-و-آرایهها)\n      - [توضیح با مثال](#توضیح-با-مثال)\n      - [منابع مفید](#منابع-مفید-1)\n    - [متدهای آرایه - map / filter / reduce / find](#متدهای-آرایه-map-filter-reduce-find)\n      - [نمونه کد](#نمونه-کد-2)\n      - [توضیح](#توضیح)\n        - [متد ‪Array.prototype.map()‬](#متد-arrayprototypemap)\n        - [متد ‪Array.prototype.filter()‬](#متد-arrayprototypefilter)\n        - [متد ‪Array.prototype.reduce()‬](#متد-arrayprototypereduce)\n        - [متد ‪Array.prototype.find()‬](#متد-arrayprototypefind)\n      - [منبع خارجی](#منبع-خارجی)\n    - [عملگر گسترش «...»](#عملگر-گسترش-)\n      - [نمونه کد](#نمونه-کد-3)\n      - [توضیح](#توضیح-1)\n        - [در شمارش‌پذیرها (مانند آرایه)](#در-شمارشپذیرها-مانند-آرایه)\n        - [پارامتر باقی (rest) تابع](#پارامتر-باقی-rest-تابع)\n        - [گسترش خاصیت‌های شیء](#گسترش-خاصیتهای-شیء)\n      - [منابع خارجی](#منابع-خارجی-2)\n    - [میان‌بر خاصیت شیء](#میانبر-خاصیت-شیء)\n      - [توضیح](#توضیح-2)\n      - [منابع خارجی](#منابع-خارجی-3)\n    - [وعده‌ها (Promises)](#وعدهها-promises)\n      - [نمونه کد](#نمونه-کد-4)\n      - [توضیح](#توضیح-3)\n        - [ساخت یک وعده](#ساخت-یک-وعده)\n        - [به‌کارگیری گرداننده وعده](#بهکارگیری-گرداننده-وعده)\n      - [منابع خارجی](#منابع-خارجی-4)\n    - [قالب لفظی (Template literals)](#قالب-لفظی-template-literals)\n      - [نمونه کد](#نمونه-کد-5)\n      - [منابع خارجی](#منابع-خارجی-5)\n    - [قالب لفظی برچسب‌دار](#قالب-لفظی-برچسبدار)\n      - [منابع خارجی](#منابع-خارجی-6)\n    - [درون‌ریزی / برون‌ریزی](#درونریزی-برونریزی)\n      - [توضیح به همراه نمونه کد](#توضیح-به-همراه-نمونه-کد)\n        - [برون‌ریزی بانام](#برونریزی-بانام)\n        - [درون‌ریزی / برون‌ریزی پیش‌فرض](#درونریزی-برونریزی-پیشفرض)\n      - [منابع خارجی](#منابع-خارجی-7)\n    - [مفهوم this در جاوااسکریپت](#مفهوم-this-در-جاوااسکریپت)\n      - [منابع خارجی](#منابع-خارجی-8)\n    - [کلاس](#کلاس)\n      - [نمونه‌ها](#نمونهها)\n      - [منابع خارجی](#منابع-خارجی-9)\n    - [کلیدواژه‌های `Extends` و `super`](#کلیدواژههای-extends-و-super)\n      - [نمونه کد](#نمونه-کد-6)\n      - [منابع خارجی](#منابع-خارجی-10)\n    - [استفاده از Async Await](#استفاده-از-async-await)\n      - [نمونه کد](#نمونه-کد-7)\n      - [توضیح با نمونه کد](#توضیح-با-نمونه-کد)\n        - [مدیریت خطا](#مدیریت-خطا)\n      - [منابع خارجی](#منابع-خارجی-11)\n    - [درستی / غلطی](#درستی-غلطی)\n      - [منابع خارجی](#منابع-خارجی-12)\n    - [توابع Anamorphisms و Catamorphisms](#توابع-anamorphisms-و-catamorphisms)\n      - [تابع Anamorphisms](#تابع-anamorphisms)\n        - [نمونه کد](#نمونه-کد-8)\n      - [تابع Catamorphisms](#تابع-catamorphisms)\n        - [نمونه کد](#نمونه-کد-9)\n      - [منابع خارجی](#منابع-خارجی-13)\n    - [تولیدکننده‌ها](#تولیدکنندهها)\n      - [نمونه کد](#نمونه-کد-10)\n      - [منابع خارجی](#منابع-خارجی-14)\n    - [متدهای ایستا](#متدهای-ایستا)\n      - [توضیح کوتاه](#توضیح-کوتاه-1)\n        - [نمونه کد](#نمونه-کد-11)\n      - [توضیح مبسوط](#توضیح-مبسوط-2)\n        - [فراخوانی متد ایستا توسط متد ایستای دیگر](#فراخوانی-متد-ایستا-توسط-متد-ایستای-دیگر)\n        - [فراخوانی متدهای ایستا توسط متدهای غیرایستا](#فراخوانی-متدهای-ایستا-توسط-متدهای-غیرایستا)\n      - [منابع خارجی](#منابع-خارجی-15)\n  - [واژه‌نامه](#واژهنامه)\n    - [قلمرو](#قلمرو)\n    - [تغییر متغیر](#تغییر-متغیر)\n\n## مفاهیم\n\n### اعلان متغیر: var، const، let\n\nدر جاوااسکریپت سه کلیدواژه برای اعلان یک متغیر وجود دارند که هر یک دارای ویژگی‌های خاص خود هستند. این کلیدواژه‌ها عبارت‌اند از `var` و `let` و `const`.\n\n#### توضیح کوتاه\n\nمتغیرهایی که با `const` اعلان می‌شوند را نمی‌توان دوباره مقداردهی کرد در حالی که اگر همان متغیر با `var` یا `let` تعریف می‌شد، امکان این کار فراهم می‌بود.\n\nپیشنهاد می‌کنم همیشه متغیرهای خود را به طور پیش‌فرض با `const` تعریف کنید مگر این که بخواهید آن را بعدا تغییر داده یا مقداردهی کنید که در این حالت پیشنهادم استفاده از `let` است.\n\n|     |قلمرو|قابل مقداردهی|قابل تغییر|محدوده مرگ زمانی|\n| --- | --- | --- | --- | --- |\n|const|بلوک|خیر|بله|بله|\n|let|بلوک|بله|بله|بله|\n|var|تابع|بله|بله|خیر|\n\n#### نمونه کد\n```javascript\nconst person = \"Nick\";\nperson = \"John\" // خطایی اعلام می‌شود که مقدار متغییر نمی‌تواند تغییر کند\n```\n\n```javascript\nlet person = \"Nick\";\nperson = \"John\";\nconsole.log(person) // \"John\", بازمقداردهی مجاز است\n```\n\n#### توضیح مبسوط\n[قلمرو](#قلمرو) یک متغیر تقریبا به این معناست که «این متغیر در کجای کد قابل دسترس است».\n\n##### استفاده از var\nمتغیرهایی که با `var` اعلان می‌شوند *در قلمروی تابع* دردسترس‌اند به این معنا که وقتی متغیری در یک تابع تعریف شود، هر چیزی در آن تابع می‌توان به آن متغیر دسترسی داشه باشد. در کنار این، یک متغیر *در قلمروی تابع* که داخل یک تابع تعریف شده است نمی‌تواند خارج از آن تابع در دسترس باشد.\n\nپیشنهاد می‌کنم تصور کنید که یک متغیر *در قلمروی X* مانند آن است که آن متغیر، یکی خصوصیت (property) X باشد.\n\n\n```javascript\nfunction myFunction() {\n  var myVar = \"Nick\";\n  console.log(myVar); // \"Nick\" - متغیر داخل تابع در دسترس است\n}\nconsole.log(myVar); // ReferenceError - متغیر خارج از تابع در دسترس نیست\n```\nو این مثال:\n\n```javascript\nfunction myFunction() {\n  var myVar = \"Nick\";\n  if (true) {\n    var myVar = \"John\";\n    console.log(myVar); // \"John\"\n    // چون متغیر در قلروی تابع است، مقدارش با مقدار جدید جایگزین می‌شود.\n  }\n  console.log(myVar); // \"John\" - ببینید که دستورات داخل شرط چه طور روی مقدار این متغیر اثر می‌گذارد\n}\nconsole.log(myVar); // ReferenceError - متغیر خارج از تابع در دسترس نیست\n```\n\nافزون بر این، متغییرهایی که توسط `var` اعلان می‌شوند به بالای قلمرو در زمان اجرا منتقل می‌گردند.این چیزی است که آن را [var hoisting](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var#var_hoisting) می‌خوانیم.\n\nاین بخش از کد:\n\n```js\nconsole.log(myVar) // undefined -- no error raised\nvar myVar = 2;\n```\n\nدر زمان اجرا به این شکل فهمیده می‌شود:\n\n```js\nvar myVar;\nconsole.log(myVar) // undefined -- no error raised\nmyVar = 2;\n```\n\n##### استفاده از let\nشباهت‌هایی زیادی میان `let` و `var` وجود دارد اما متغیرهایی که با `let` تعریف می‌شوند:\n\n- *در قلمروی بلوک* هستند\n- پیش از مقداردهی قابل دسترسی **نیستند**\n- نمی‌توانند در همان قلمرو بازاعلان شوند\n\nبگذارید اثر تعریف متغیر در قلمروی بلوک را در همان مثال‌های پیشین ببینیم:\n\n```javascript\nfunction myFunction() {\n  let myVar = \"Nick\";\n  if (true) {\n    let myVar = \"John\";\n    console.log(myVar); // \"John\"\n    // چون myVar یک متغیر در قلمروی بلوک است، در واقع یک متغیر جدید اعلان کرده‌ایم.\n    // این متغیر خارج از این بلوک قابل دسترس نیست و در حقیقت، کاملا مستقل\n    // از آن متغیر myVar است که اول تعریف شده بود.\n  }\n  console.log(myVar); // \"Nick\", ببینید که چه طور دستورات داخل شرط، تاثیری روی متغیر بیرون شرط ندارد\n}\nconsole.log(myVar); // ReferenceError - متغیر خارج از تابع قابل دسترس نیست\n```\n\nحال ببینیم که یعنی چه که متغیرهای `let` (و `const`) پیش از مقداردهی دسترسی نیستند:\n\n```js\nconsole.log(myVar) // ReferenceError !\nlet myVar = 2;\n```\n\nبر خلاف متغیرهای `var`، اگر تلاش کنید یک متغیر `let` یا `const` را پیش از مقداردهی بخوانید یا رویش بنویسید، خطا دریافت خواهید کرد. این پدیده معمولا با نام *محدوده مرگ زمانی* یا [*Temporal dead zone*](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let#Temporal_Dead_Zone_and_errors_with_let) یا به اختصار *TDZ* خوانده می‌شود.\n\n> **نکته:** از منظر فنی، اعلان‌های متغیر با `let` و `const` نیز بالاتر اجرا می‌شوند (hoist) اما مقداردهی‌شان نه. از همین رو که این گونه ساخته شده‌اند که تا پیش از مقداردهی، قابل استفاده نباشند این حس ایجاد می‌شود که گویی مورد hoist قرار نگرده‌اند در حالی که قرار گرفته‌اند. اگر می‌خواهید بیشتر بدانید، به [این توضیح بسیار مبسوط](http://jsrocks.org/2015/01/temporal-dead-zone-tdz-demystified) مراجعه کنید.\n\nبه علاوه، نمی‌توانید متغیرهای `let` را مجددا اعلان کنید:\n\n```js\nlet myVar = 2;\nlet myVar = 3; // SyntaxError\n```\n\n##### استفاده از const\n\nمتغیرهای اعلان شده با `const` مشابه متغیرهای `let` رفتار می‌کنند با این تفاوت که قابل مقداردهی مجدد نیستند. به طور خلاصه، متغیرهای `const`:\n\n- *در قلمروی بلوک* هستند\n- پیش از مقداردهی قابل دسترسی نیستند\n- نمی‌توانند در همان قلمرو بازاعلان شوند\n- نمی‌توانند مقداردهی مجدد شوند\n\n```js\nconst myVar = \"Nick\";\nmyVar = \"John\" // خطایی می‌بینید که مقداردهی مجدد ممکن نیست\n```\n\n```js\nconst myVar = \"Nick\";\nconst myVar = \"John\" // خطایی می‌بینید که اعلان مجدد ممکن نیست\n```\n\nاما یک نکته ظریف در این جا وجود دارد: متغیرهای `const` [تغییرناپذیر](#تغییر-متغیر) یا immutable نیستند! به معنای دقیق‌تر، آرایه‌ها و شیءهایی که با `const` اعلان شده‌اند **می‌توانند** تغییر کنند.\n\nبرای شی‌ءها:\n\n```js\nconst person = {\n  name: 'Nick'\n};\nperson.name = 'John' // کار می‌کند چون این متغیر کاملا مقداردهی نشده، می‌تواند تغییر کند\nconsole.log(person.name) // \"John\"\nperson = \"Sandra\" // خطا دریافت خواهید کرد چون قابل مقداردهی مجدد نیست\n```\n\nبرای آرایه‌ها:\n\n```js\nconst person = [];\nperson.push('John'); // کار می‌کند چون این متغیر کاملا مقداردهی نشده، می‌تواند تغییر کند\nconsole.log(person[0]) // \"John\"\nperson = [\"Nick\"] // خطا دریافت خواهید کرد چون قابل مقداردهی مجدد نیست\n```\n\n#### منابع خارجی\n\n\n- [How let and const are scoped in JavaScript - WesBos](http://wesbos.com/javascript-scoping/)\n- [Temporal Dead Zone (TDZ) Demystified](http://jsrocks.org/2015/01/temporal-dead-zone-tdz-demystified)\n\n### تابع پیکانی\n\nدر به‌روزرسانی ES6 جاوااسکریپت، *توابع پیکانی* یا Arrow Function معرفی شدند که روشی دیگری برای اعلان و استفاده از توابع هستند. برخی از فواید این نوع توابع عبارت‌اند از:\n\n- مختصرتر هستند\n- مقدار *this* از محیط برداشته می‌شود\n- بازگشت تلویحی\n\n#### نمونه کد\n\n- اختصار و بازگشت تلویحی\n\n```js\nfunction double(x) { return x * 2; } // روش سنتی\nconsole.log(double(2)) // 4\n```\n\n```js\nconst double = x => x * 2; // همان تابع به صورت تابع پیکانی با مقدار بازگشتی تلویحی\nconsole.log(double(2)) // 4\n```\n\n- ارجاع *this*\n\nدر تابع پیکانی، *this* معادل مقدار *this* در بافتار اجرای محاط بر تابع است. اساسا با توابع پیکانی شما نیازی به ترفند `that = this` پیش از فراخوانی تابع دیگری داخل یک تابع ندارید.\n\n```js\nfunction myFunc() {\n  this.myVar = 0;\n  setTimeout(() => {\n    this.myVar++;\n    console.log(this.myVar) // 1\n  }, 0);\n}\n```\n\n#### توضیح مبسوط\n\n##### اختصار\n\nتوابع پیکانی در قیاس با توابع سندی به روش‌های زیادی مختصرتر هستند. بگذارید همه حالت‌های ممکن را مرور کنیم:\n\n- بازگشت تصریحی در مقابل تلویحی\n\n**بازگشت تصریحی** تابعی است که در آن کلیدواژه *return* در بدنه تابع استفاده شده باشد.\n\n```js\n  function double(x) {\n    return x * 2; // صریحا از کلیدواژه بازگشت استفاده شده است\n  }\n```\n\nدر روش سنتی نوشتن تابع، بازگشت همیشه صریح بوده است. اما با توابع پیکانی، می‌توانید *بازگشت تلویحی* داشه باشید که یعنی برای بازگرداندن یک مقدار، نیازی به استفاده از کلیدواژه *return* ندارید.\n\n```js\n  const double = (x) => {\n    return x * 2; // بازگشت صریح\n  }\n```\n\nاز آن جایی که این تابع فقط چیزی را بر می‌گرداند (فاقد هر گونه دستورالعملی پیش از کلیدواژه *return* است) می‌توانیم از بازگشت تلویحی استفاده کنیم.\n\n```js\n  const double = (x) => x * 2;\n```\n\nبرای این منظور کافی است که کلیدواژه **return** و **گیومه‌ها را برداریم**. به همین دلیل است که این روش، بازگشت *تلویجی* خوانده می‌شود. کلیدواژه *return* وجود ندارد اما این تابع در واقع مقدار `x * 2` را برمی‌گرداند.\n\n> **توجه:** اگر تابع شما مقداری (با *اثر جانبی*) بر نمی‌گرداند، در حقیقت بازگشت تلویحی یا تصریحی انجام نمی‌دهد.\n\nدر کنار این، اگر شما بخواهید تلویحا یک *شیء* را برگردانید **لازم است که آن را در پرانتز قرار دهید** چون در غیر این صورت، با آکولادهای بلوک دچار تداخل می‌شود.\n\n```js\nconst getPerson = () => ({ name: \"Nick\", age: 24 })\nconsole.log(getPerson()) // { name: \"Nick\", age: 24 } -- شیء به صورت تلویحی با کمک تابع پیکانی بازگشت داده شده است\n```\n\n- تنها یک آرگومان\n\nاگر تابع شما تنها یک پارامتر دریافت می‌کند می‌توانید پرانتز را از اطراف آن بردارید. اگر کد **double** بالایی را در نظر بگیریم:\n\n```js\n  const double = (x) => x * 2; // این تابع پیکانی تنها یک پارامتر دریافت می‌کند\n```\n\nپرانتزهای اطراف پارامتر می‌توانند برداشته شوند.\n\n```js\n  const double = x => x * 2; // این تابع پیکانی تنها یک پارامتر دریافت می‌کند\n```\n\n- بدون آرگومان\n\nوقتی ورودی‌ای به تابع پیکانی وجود ندارد باید یک جفت پرانتز وارد کنید مگر نه خطای نحوی دریافت خواهید کرد.\n\n```js \n  () => {\n   // پرانتز درج شده و همه چیز درست کار می‌کند\n    const x = 2;\n    return x;\n  }\n```\n\n```js\n  => {\n   // پرانتز درج نشده و کد اجرا نخواهد شد\n    const x = 2;\n    return x;\n  }\n```\n\n##### ارجاع *this*\n\nبرای درک این ویژگی تازه معرفی شده همراه توابع پیکانی لازم است بدانید که **this** چگونه در جاوااسکریپت رفتار می‌کند.\n\nدر یک تابع پیکانی، *this* معادل *this* در بافتار اجرایی محاط بر تابع است. این یعنی که تابع پیکانی به جای ایجاد یک *this* جدید، آن را از محیطی که در آن احاطه شده می‌قاپد.\n\nبدون تابع پیکانی اگر شما بخواهید از طریق *this* به یک متغیر در تابعی داخل یک تابع دسترسی پیدا کنید لازم است که از ترفند *that = this* یا *self = this* استفاده کنید.\n\nبه عنوان مثال، استفاده کردن از تابع setTimeout داخل تابع myFunc:\n\n```js\nfunction myFunc() {\n  this.myVar = 0;\n  var that = this; // that = this trick\n  setTimeout(\n    function() { // یک‫ this جدید در قلمروی این تابع ساخته می‌شود\n      that.myVar++;\n      console.log(that.myVar) // 1\n\n      console.log(this.myVar) // undefined -- اعلان تابع را ببینید\n    },\n    0\n  );\n}\n```\n\nاما با تابع پیکانی، *this* از محیط پیرامونی‌اش گرفته می‌شود:\n\n```js\nfunction myFunc() {\n  this.myVar = 0;\n  setTimeout(\n    () => {\n    // اینجا this از محیط پیرامونی‌اش یعنی تابع myFunc گرفته می‌شود\n      this.myVar++;\n      console.log(this.myVar) // 1\n    },\n    0\n  );\n}\n```\n\n#### منابع مفید\n\n- [Arrow functions introduction - WesBos](http://wesbos.com/arrow-functions/)\n- [JavaScript arrow function - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions)\n- [Arrow function and lexical *this*](https://hackernoon.com/javascript-es6-arrow-functions-and-lexical-this-f2a3e2a5e8c4)\n\n\n### مقدار پیش‌فرض پارامتر تابع\n\nاز به‌روزرسانی ES2015 جاوااسکریپت می‌توانید با نحو زیر، مقدار پیش‌فرض برای پارامترهای تابع تنظیم کنید:\n\n```js\nfunction myFunc(x = 10) {\n  return x;\n}\nconsole.log(myFunc()) // 10\nconsole.log(myFunc(5)) // 5\n\nconsole.log(myFunc(undefined)) // 10\nconsole.log(myFunc(null)) // null\n```\n\nپارامتر پیش‌فرض تنها در دو و فقط دو موقعیت اعمال می‌شود:\n\n- پارامتری ارائه نشده باشد\n- پارامتر *undefined* ارائه شده باشد\n\nبه بیان دیگر، اگر مقدار *null* را به پارامتر پیش‌فرض بدهید، این مقدار **اعمال نخواهد شد**.\n\n> **نکته:** تخصیص مقدار پیش‌فرض می‌تواند با پارامترهای destructured هم استفاده شود (مفهوم بعدی را برای مثال ببینید)\n\n#### منابع خارجی\n\n- [Default parameter value - ES6 Features](http://es6-features.org/#DefaultParameterValues)\n- [Default parameters - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters)\n\n### تجزیه اشیاء و آرایه‌ها\n\n*تجزیه* (destructuring) روشی آسان برای ساخت متغیرهای جدید از راه استخراج مقادیر از داده‌های ذخیره شده در اشیاء یا آرایه‌هاست.\n\nبه عنوان مثال، *تجزیه کردن* می‌تواند به منظور تجزیه پارامترهای تابع و یا *this.props* در پروژه‌های ری‌اکت مورد استفاده قرار گیرد.\n\n#### توضیح با مثال\n\n- شیء\n\nبگذارید شیء زیر را برای تمام مثال‌ها در نظر بگیریم:\n\n```js\nconst person = {\n  firstName: \"Nick\",\n  lastName: \"Anderson\",\n  age: 35,\n  sex: \"M\"\n}\n```\n\nبدون تجزیه کردن:\n\n```js\nconst first = person.firstName;\nconst age = person.age;\nconst city = person.city || \"Paris\";\n```\n\nبا تجزیه کردن، تماما در یک خط:\n\n```js\nconst { firstName: first, age, city = \"Paris\" } = person; // همین و بس\n\nconsole.log(age) // 35 -- ‫متغیر جدید age ساخته شده و معادل است با person.age \nconsole.log(first) // \"Nick\" -- ‫متغیر جدید first ساخته شده و معادل است با person.firstName\nconsole.log(firstName) // ReferenceError -- ‫در واقع person.firstName وجود دارد اما نام متغیر جدیدی که ساخته شده،first است\nconsole.log(city) // \"Paris\" -- ‫متغیر جدیدی به نام city ساخته شده است اما چون person.city تغیرنشده است، مقدار موجود در city برابر است با مقدار پیش‌فرض ارائه شده یعنی Paris\n```\n\n**نکته:** آکولادهای استفاده شده در `const { age } = person` بعد از *const* نه برای اعلان شیء یا بلوک بلکه به عنوان نحو تجزیه نوشته شده است.\n\n- پارامترهای تابع\n\n*تجزیه کردن* معمولا برای تجزیه پارامترهای شیء در توابع استفاده می‌شود.\n\nبدون تجزیه کردن\n\n```js\nfunction joinFirstLastName(person) {\n  const firstName = person.firstName;\n  const lastName = person.lastName;\n  return firstName + '-' + lastName;\n}\n\njoinFirstLastName(person); // \"Nick-Anderson\"\n```\n\nبا تجزیه کردن پارامتر *person* شیء، ما به یک تابع جمع و جورتر دست پیدا می‌کنیم:\n\n```js\nfunction joinFirstLastName({ firstName, lastName }) { // ‫ما متغیرهای firstName و lastName را با تجزیه پارامترهای شیء person به دست می‌آوریم\n  return firstName + '-' + lastName;\n}\n\njoinFirstLastName(person); // \"Nick-Anderson\"\n```\n\nاستفاده از تجزیه به خصوص در زمان استفاده از توابع پیکانی، شیرین‌تر هم می‌شود:\n\n```js\nconst joinFirstLastName = ({ firstName, lastName }) => firstName + '-' + lastName;\n\njoinFirstLastName(person); // \"Nick-Anderson\"\n```\n\n\n- آرایه\n\nآرایه زیر را در نظر بگیریم:\n\n```js\nconst myArray = [\"a\", \"b\", \"c\"];\n```\n\nبدون تجزیه کردن\n\n```js\nconst x = myArray[0];\nconst y = myArray[1];\n```\n\nبا تجزیه کردن\n\n```js\nconst [x, y] = myArray; // همین و پس\n\nconsole.log(x) // \"a\"\nconsole.log(y) // \"b\"\n```\n\n#### منابع مفید\n\n- [ES6 Features - Destructuring Assignment](http://es6-features.org/#ArrayMatching)\n- [Destructuring Objects - WesBos](http://wesbos.com/destructuring-objects/)\n- [ExploringJS - Destructuring](http://exploringjs.com/es6/ch_destructuring.html)\n\n### متدهای آرایه - map / filter / reduce / find\n\nخواستگاه متدهای *Map*، *filter*، *reduce* و *find* برای آرایه، یک پارادایم برنامه‌نویسی به نام برنامه‌نویسی تابعی یا [*functional programming*](https://medium.com/javascript-scene/master-the-javascript-interview-what-is-functional-programming-7f218c68b3a0) است.\n\nبه طور خلاصه:\n\n- متد ‪**Array.prototype.map()** ‬ یک آرایه دریافت می‌کند، کاری روی تک تک اعضای آن انجام می‌دهد و آرایه‌ای حاوی اعضای تغییریافته باز می‌گرداند.\n- متد ‪**Array.prototype.filter()** ‬ یک آرایه دریافت می‌کند، عضو به عضو پیش می‌رود و تصمیم می‌گیرد که آیا آن عضو در آرایه‌ای که بازگشت داده خواهد شد باقی بماند یا خیر. نهایتا هم یک آرایه از اعضای تایید شده را باز می‌گرداند.\n- متد ‪**Array.prototype.reduce()** ‬ یک آرایه دریافت ی‌کند اعضای آن را روی هم ریخته و به صورت یک مقدار واحد باز می‌گرداند.\n- متد ‪**Array.prototype.find()** ‬ یک آرایه دریافت می‌کند و اولین عضوی را که شرط اعلام شده را داشته باشد باز می‌گرداند.\n\nپیشنهاد می‌کنم که تا می‌توانید از اصول برنامه‌نویسی تابعی بهره ببرید زیرا قابل ترکیب، موجز و زیبا هستند.\n\nبا این چهار متدی که اشاره شد، می‌توانید در موارد بسیاری از به کار بردن حلقه *for* و *forEach* اجتناب کنید. به جای حلقه *for* سعی کنید از ترکیب این چهار متد استفاده کنید. شاید در نگاه اول قدری چالش برانگیز باشد. طبیعی است چون لازم است روش جدیدی برای اندیشیدن را فرابگیرید. اما وقتی این مهارت را فرابگیرید، کارها آسان‌تر می‌شوند.\n\n#### نمونه کد\n\n```js\nconst numbers = [0, 1, 2, 3, 4, 5, 6];\nconst doubledNumbers = numbers.map(n => n * 2); // [0, 2, 4, 6, 8, 10, 12]\nconst evenNumbers = numbers.filter(n => n % 2 === 0); // [0, 2, 4, 6]\nconst sum = numbers.reduce((prev, next) => prev + next, 0); // 21\nconst greaterThanFour = numbers.find((n) => n>4); // 5\n```\nمحاسبه مجموع نمرات دانش‌آموزانی که نمره ۱۰ یا بالاتر گرفته‌اند با کمک ترکیب متدهای map و filter و 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) // ‫ما آرایه student را روی آرایه‌ای از نمره‌های‌شان نگاشت (map) کردیم\n  .filter(grade => grade >= 10) // ‫ما آرایه grades را به منظور نگه‌داشتن نمره‌های ۱۰ و بالاتر مورد پالایش (filter) قرار دادیم\n  .reduce((prev, next) => prev + next, 0); // همه نمره‌های ۱۰ و بالاتر را یک به یک با هم جمع کردیم \n\nconsole.log(aboveTenSum) // 44 -- 10 (Nick) + 15 (John) + 19 (Julia), Nathalie below 10 is ignored\n```\n\n#### توضیح\n\nبیایید آرایه اعداد زیر را به عنوان مثلا در نظر بگیریم:\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); // [0, 2, 4, 6, 8, 10, 12]\n```\n\nچه شد؟ ما از متد ‪.map‬ روی آرایه *numbers* استفاده می‌کنیم. این متد می‌آید و روی یکایک اعضای آرایه حرکت می‌کند و مقدار آن‌ها را به تابع ما می‌دهد. هدف این تابع، تولید و بازگرداندن مقداری جدید بر اساس مقداری است که به آن داده شده و در نتیجه متد نگاشت (map)‌ می‌تواند مقدار جدید را جایگزین کند.\n\nبگذارید فقط برای این مثال، این تابع را باز کرده و واضح‌ترش کنیم:\n\n```js\nconst doubleN = function(n) { return n * 2; };\nconst doubledNumbers = numbers.map(doubleN);\nconsole.log(doubledNumbers); // [0, 2, 4, 6, 8, 10, 12]\n```\n\n**نکته:** شما به دفعات خواهید دید که این متد در ترکیب با توابع پیکانی استفاده می‌شود.\n\n```js\nconst doubledNumbers = numbers.map(n => n * 2);\nconsole.log(doubledNumbers); // [0, 2, 4, 6, 8, 10, 12]\n```\n\nدر این جا، ```numbers.map(doubleN)``` آرایهٔ ```[doubleN(0), doubleN(1), doubleN(2), doubleN(3), doubleN(4), doubleN(5), doubleN(6)]``` تولید می‌کند که معادل است با ```[0, 2, 4, 6, 8, 10, 12]```.\n\n> **نکته:** اگر به جای بازگرداندن آرایه جدید فقط به دنبال ایجاد یک حلقهٔ دارای اثر جانبی هستید احتمالا باید به سراغ همان for یا forEach بروید نه map.\n\n##### متد ‪Array.prototype.filter()\n\n```js\nconst evenNumbers = numbers.filter(function(n) {\n  return n % 2 === 0; // ‫اگر n زوج باشد مقدار true و در غیر این صورت false\n});\nconsole.log(evenNumbers); // [0, 2, 4, 6]\n```\n\n**نکته:** شما به دفعات خواهید دید که این متد در ترکیب با توابع پیکانی استفاده می‌شود.\n\n```js\nconst evenNumbers = numbers.filter(n => n % 2 === 0);\nconsole.log(evenNumbers); // [0, 2, 4, 6]\n```\n\nما از متد ‪.filter‬ روی آرایه *numbers* استفاده می‌کنیم. این متد روی یکایک اعضای آرایه حرکت کرده و آن‌ها را به تابع ما می‌دهد. هدف تابع این است که یک مقدار بولی بازگرداند که مبنای تصمیم ما برای نگه داشتن آن عضو است. نهایتا filter آرایه‌ای از مقادیری را که نگه‌داشته است باز می‌گرداند.\n\n##### متد ‪Array.prototype.reduce()\n\nهدف متد کاهش (reduce) حرکت روی یکایک اعضای یک آرایه و کاستن آن‌ها به یک مقدار واحد است. این که چه طور این اعضا روی هم ریخته شوند به شما بستگی دارد.\n\n```js\nconst sum = numbers.reduce(\n  function(acc, n) {\n    return acc + n;\n  },\n‪  0 // این، مقدار متغیر انباشت‌گر در نخستین گام محاسبه است\n);\n\nconsole.log(sum) // 21\n```\n\n**نکته:** شما به دفعات خواهید دید که این متد در ترکیب با توابع پیکانی استفاده می‌شود.\n\n```js\nconst sum = numbers.reduce((acc, n) => acc + n, 0);\nconsole.log(sum) // 21\n```\n\nدرست هماهنند متدهای map و filter، متد reduce روی یک آرایه اعمال شده و یک تابع را به عنوان اولین پارامتر دریافت می‌کند.\n\nاین بار اما تفاوت‌هایی وجود دارد:\n\n- متد ‪.reduce‬ دو پارامتر دریافت می‌کند\n\nاولی پارامتر یک تابع است که در هر گام از حرکت روی اعضای آرایه فراخوانده می‌شود.\n\nپارامتر دوم، مقدار متغیر انباشت‌گر (در این جا *acc*) در نخستین گام محاسبه است (برای فهمیدن، مورد بعدی را بخوانید).\n\n- پارامترهای تابع\n\nتابعی که به عنوان اولین پارامتر به ‪.reduce‬ می‌دهید دو پارامتر می‌خواهد. اولی (در این جا *acc*) متغیر انباشت‌گر و دومین پارامتر (*n*) عضو جاری آرایه است.\n\nمتغیر انباشت‌گر برابر است با مقدار بازگشت داده شده از تابع در گام **قبلی** محاسبه. در اولین گام از محاسبه، *acc* برابر است با مقداری که در دومین پارامتر ‪.reduce‬ وارد شده است.\n\n###### در گام نخست\n\nمقدار acc برابر صفر است زیرا در دومین پارامتر reduce مقدار صفر وارد شده است.\n\nمقدار n هم صفر است چون اولین عضو آرایه *number* چنین مقداری دارد.\n\nتابع، مقدار ‪*acc* + *n* --> 0 + 0 --> 0‬ را برمی‌گرداند.\n\n###### در گام دوم\n\nمقدار acc برابر صفر است چون تابع ما در مرحله قبل این مقدار را بازگردانده بود.\n\nاین بار n برابر یک است که دومین عضو آرایه *number* است.\n\nاین بار تابع مقدار ‪*acc* + *n* --> 0 + 1 --> 1‬ را بازمی‌گرداند.\n\n###### در گام سوم\n\nمقدار acc برابر یک است زیرا تابع ما در مرحله قبل این مقدار را بازگردانده بود.\n\nاین بار n برابر با ۲ است که سومین عضو آرایه *number* است.\n\nتابع، مقدار ‪*acc* + *n* --> 1 + 2 --> 3‬ را باز می‌گرداند.\n\n\n###### در چهارمین گام\n\nمقدار acc برابر ۳ است زیرا تابع ما در مرحله قبل این مقدار را بازگردانده بود.\n\nاین بار n برابر با ۳ است که چهارمین عضو آرایه *number* است.\n\nتابع، مقدار ‪*acc* + *n* --> 3 + 3 --> 6‬ را باز می‌گرداند.\n\n\n###### نهایتا در آخرین گام\n\nمقدار acc برابر ۱۵ است زیرا تابع ما در مرحله قبل این مقدار را بازگردانده بود.\n\nمقدار n برابر با ۶ است که آخرین عضو آرایه *number* است.\n\nتابع، مقدار ‪*acc* + *n* --> 15 + 6 --> 21‬ را باز می‌گرداند.\n\nاز آن جایی که این، آخرین گام محاسبه است، متد **‪.reduce‬** مقدار ۲۱ را باز می‌گرداند.\n\n##### متد ‪Array.prototype.find()\n\n```js\nconst greaterThanZero = numbers.find(function(n) {\n  return n > 0; // return number just greater than 0 is present\n});\nconsole.log(greaterThanZero); // 1\n```\n\n**نکته:** شما به دفعات خواهید دید که این متد در ترکیب با توابع پیکانی استفاده می‌شود.\n\nاینجا از متد یافتن یا find روی آرایه *numner* استفاده می‌کنیم. این متد روی یکایک اعضای آرایه حرکت کرده و تا زمانی که شرط تعیین شده برقرار شود آن‌ها را به تابع ما می‌دهد. هدف تابع، بازگرداندن عنصری است که روی آن، شرط موجود در تابع آزمون جاری محقق شود. متد find یک تابع callback را به ازای هر اندیس از آرایه و تا زمانی که آن تابع یک مقدار درست یا true را باز گرداند اجرا می‌کند.\n\n**نکته:** این متد به محض پیدا کردن عضوی از آرایه که شرط مشخص شده را محقق می‌کند، مقدارش را باز می‌گرداند. در غیر این صورت مقدار undefined را باز خواهد گرداند.\n\n#### منبع خارجی\n\n- [Understanding map / filter / reduce in JS](https://hackernoon.com/understanding-map-filter-and-reduce-in-javascript-5df1c7eee464)\n\n### عملگر گسترش «...»\n\nعملگر گسترش `...` (spread) با ES2015 معرفی شد و برای گستردن عناصر یک متغیر قابل شمارش یا iterable (مانند یک آرایه) به مکان‌هایی است که چندین عنصر قابل جای‌گذاری هستند.\n\n#### نمونه کد\n\n```js\nconst arr1 = [\"a\", \"b\", \"c\"];\nconst arr2 = [...arr1, \"d\", \"e\", \"f\"]; // [\"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// \"a\"\n// \"b\"\n// [\"c\", \"d\", \"e\", \"f\"]\n```\n\n\n```js\nconst { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };\nconsole.log(x); // 1\nconsole.log(y); // 2\nconsole.log(z); // { a: 3, b: 4 }\n\nconst n = { x, y, ...z };\nconsole.log(n); // { x: 1, y: 2, a: 3, b: 4 }\n```\n\n#### توضیح\n\n##### در شمارش‌پذیرها (مانند آرایه)\n\nاگر دو آرایه زیر را داشته باشیم:\n\n```js\nconst arr1 = [\"a\", \"b\", \"c\"];\nconst arr2 = [arr1, \"d\", \"e\", \"f\"]; // [[\"a\", \"b\", \"c\"], \"d\", \"e\", \"f\"]\n```\n\nدر آرایه *arr2*، اولین عضو ما یک آرایه است چرا که *arr1* همان‌گونه که هست در *arr2* تزریق شده است. اما چیزی که می‌خواهیم این است که *arr2*، آرایه‌ای از حروف باشد. برای این منظور می‌توانید عناصر *arr1* را در *arr2* *گسترش* دهیم.\n\nبا عملگر گسترش\n\n```js\nconst arr1 = [\"a\", \"b\", \"c\"];\nconst arr2 = [...arr1, \"d\", \"e\", \"f\"]; // [\"a\", \"b\", \"c\", \"d\", \"e\", \"f\"]\n```\n\n##### پارامتر باقی (rest) تابع\n\nدر پارامترهای تابع می‌توانیم از عملگر باقی (rest) به منظور تزریق پارامترها به آرایه‌ای که رویش بتوانیم حلقه اجرا کنیم بهره می‌بریم. همواره یک شیء **arguments** همراه با هر تابعی وجود دارد که برابر است با آرایه‌ای از تمام پارامترهایی که به آن تابع حواله شده‌اند.\n\n```js\nfunction myFunc() {\n  for (var i = 0; i < arguments.length; i++) {\n    console.log(arguments[i]);\n  }\n}\n\nmyFunc(\"Nick\", \"Anderson\", 10, 12, 6);\n// \"Nick\"\n// \"Anderson\"\n// 10\n// 12\n// 6\n```\n\nاما حالتی را در نظر بگیرید که بخواهیم این تابع یک دانشجوی جدید همراه با معدل نمره‌هایش بسازد. آیا راحت‌تر نیست که که فقط دو پارامتر اول را استخراج کنیم و در دو متغیر مجزا قرار داده و سپس تمام نمره‌ها را آرایه‌ای بریزیم که بشود روی آن شمارش انجام داد؟\n\nاین دقیقا همان کاری است که عملگر باقی به ما اجازهٔ انجامش را می‌دهد!\n\n```js\nfunction createStudent(firstName, lastName, ...grades) {\n  // firstName = \"Nick\"\n  // lastName = \"Anderson\"\n‪  // [10, 12, 6]\n  // به کمک «...» تمام دیگر پارامترهای را دریافت و در آرایه «grades» ذخیره می‌کنیم\n\n  const avgGrade = grades.reduce((acc, curr) => acc + curr, 0) / grades.length; //‫ معدل نمره‌های موجود در آرایه 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// {\n//   firstName: \"Nick\",\n//   lastName: \"Anderson\",\n//   grades: [10, 12, 6],\n//   avgGrade: 9,33\n// }\n```\n\n> **نکته:** تابع createStudent تابع بدی است زیرا بررسی نمی‌کنیم که اساسا grades.length وجود دارد یا خیر و یا متفاوت از صفر است یا نه. اما چون خوانایی آن به این شکل بهتر بود، آن را این گونه نوشتم.\n\n##### گسترش خاصیت‌های شیء\n\nبرای این مورد پیشنهاد می‌کنم توضیحات قبلی را درباره عملگر باقی بر روی پارامترهای تابع و عناصر شمارش‌پذیر (iterables) بخوانید.\n\n```js\nconst myObj = { x: 1, y: 2, a: 3, b: 4 };\nconst { x, y, ...z } = myObj; // تجزیه شیء\nconsole.log(x); // 1\nconsole.log(y); // 2\nconsole.log(z); // { a: 3, b: 4 }\n\n// متغیر z حاوی باقی مقادیر حاصل از تجزیهٔ شیء است: شیء myObj منهای مقادیر تجزیه شدهٔ x و y\n\nconst n = { x, y, ...z };\nconsole.log(n); // { x: 1, y: 2, a: 3, b: 4 }\n\n// اینجا z حاوی خاصیت‌های شیء است که در n گسترانده می‌شود.\n```\n\n#### منابع خارجی\n\n- [TC39 - Object rest/spread](https://github.com/tc39/proposal-object-rest-spread)\n- [Spread operator introduction - WesBos](https://github.com/wesbos/es6-articles/blob/master/28%20-%20Spread%20Operator%20Introduction.md)\n- [JavaScript & the spread operator](https://codeburst.io/javascript-the-spread-operator-a867a71668ca)\n- [6 Great uses of the spread operator](https://davidwalsh.name/spread-operator)\n\n### میان‌بر خاصیت شیء\n\nدر زمان نسبت دادن یک متغیری به یک خاصیت شیء، اگر هر دو دارای نام یک‌سان باشند می‌توانیم این کار را انجام دهیم:\n\n```js\nconst x = 10;\nconst myObj = { x };\nconsole.log(myObj.x) // 10\n```\n\n#### توضیح\n\nمعمولا (پیش از ES2015) زمانی که یک *object literal* جدید تعریف می‌کنیم و بخواهیم متغیرها را به عنوان مقادیر خاصیت‌های شیء استفاده کنیم، باید چنین کدی بنویسیم:\n\n```js\nconst x = 10;\nconst y = 20;\n\nconst myObj = {\n  x: x, // ‫نسبت دادن مقدار متغیر x به myObj.x\n  y: y // ‫نسبت دادن مقدار متغیر y به myObj.y\n};\n\nconsole.log(myObj.x) // 10\nconsole.log(myObj.y) // 20\n```\nهمان‌طور که می‌بینید، این کار خیلی تکراری است زیرا نام خاصیت‌های myObj دقیقا همان نام‌های متغیرهایی است که می‌خواهیم نسبت دهیم.\n\nبا معرفی ES2015، اگر نام متغیر همان نامی خاصیت باشد می‌توانیم از این روش میان‌بر استفاده کنیم:\n\n```js\nconst x = 10;\nconst y = 20;\n\nconst myObj = {\n  x,\n  y\n};\n\nconsole.log(myObj.x) // 10\nconsole.log(myObj.y) // 20\n```\n\n#### منابع خارجی\n\n- [Property shorthand - ES6 Features](http://es6-features.org/#PropertyShorthand)\n\n### وعده‌ها (Promises)\n\nوعده یا promise یک شیء است که می‌تواند به صورت هم‌گام از یک تابع ناهم‌گام بازگردانده شود. ([ارجاع](https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-promise-27fc71e77261#3cd0)).\n\nوعده‌ها می‌توانند برای پرهیز از دوزخ callback یا [callback hell](http://callbackhell.com/) استفاده شوند که در پروژه‌های مدرن جاوااسکریپت به کرات بروز می‌کنند.\n\n\n#### نمونه کد\n\n```js\nconst fetchingPosts = new Promise((res, rej) => {\n  $.get(\"/posts\")\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#### توضیح\n\nوقتی که یک *درخواست ای‌جکس* می‌فرستید، پاسخ به‌هنگام یا هم‌گام نیست زیرا زمانی طول می‌کشد تا پاسخ این درخواست دریافت شود. حتی ممکن است به به دلیل دردسترس نبودن خدمت مورد نظر، این پاسخ هرگز به دست ما نرسد.\n\nبرای مدیریت چنین شرایطی، ES2015 *وعده‌ها* یا Promises را به ما هدیه داده است. وعده‌ها می‌توانند یکی از سه حالت وضعیت را داشته باشند:\n\n- معلق (Pending)\n- محقق شده (Fulfilled)\n- رد شده (Rejected)\n\nدر نظر بگیرید که می‌خواهیم از وعده‌ها برای مدیریت یک درخواست ای‌جکس برای واکشی منبع X استفاده کنیم.\n\n##### ساخت یک وعده\n\nابتدا یک وعده را می‌سازیم. از متد get جی‌کوئری برای فرستادن درخواست ای‌جکش به X استفاده خواهیم کرد.\n\n```js\nconst xFetcherPromise = new Promise( // ‫با کلیدواژه new یک وعده می‌سازیم و آن را در یک متغیر ذخیره می‌کنیم\n  function(resolve, reject) { //‫ سازنده وعده یک پارامتر تابع دریافت می‌کند که خودش دو پارامتر resolve و reject دارد\n    $.get(\"X\") // درخواست ای‌جکس را می‌فرستیم\n      .done(function(X) { //‫ وقتی درخواست فرستاده شد...\n        resolve(X); //‫ ...وعده با مقدار X به عنوان پارامتر رفع می‌شود\n      })\n      .fail(function(error) { //‫ اگر درخواست با شکست مواجه شود...\n        reject(error); //‫ ...وعده با خطایی به عنوان پارامتر رد می‌شود\n      });\n  }\n)\n```\n\nهمان طور که در مثال بالا دیده می‌شود، شیء Promise یک تابع *اجراکننده* (executor) دریافت می‌کند که خودش دو پارامتر **resolve** و **reject** می‌گیرد. این پارامترها توابعی هستند که وقتی صدا زده شوند، متناسب با شرایطی که حادث می‌شود وضعیت وعده را به *محقق شده* یا *رد شده* تغییر می‌دهند.\n\nوعده بعد از این جا ساخته می‌شود وارد وضعیت معلق می‌شود و تابع *اجرا کننده* بلادرنگ اجرا می‌شود. به محض صدا زده شدن *resolve* یا *reject* در تابع اجرا کننده، وعده اقدام به فراخوانی گرداننده (handler) مرتبط می‌کند.\n\n##### به‌کارگیری گرداننده وعده\n\nبرای دریافت نتیجه (یا خطای) وعده بایستی به این شکل گرداننده‌ای به آن الصاق کنیم:\n\n```js\nxFetcherPromise\n  .then(function(X) {\n    console.log(X);\n  })\n  .catch(function(err) {\n    console.log(err)\n  })\n```\n\nاگر وعده با موفقیت انجام شود، *resolve* اجرا شده و تابعی به صورت پارامتر ‪`.then`‬ وارد شده است اجرا خواهد شد.\n\nاگر به شکست بخورد، *reject* اجرا شده و تابعی که به صورت پارامتر به ‪`.catch`‬ وارد شده است اجرا خواهد شد.\n\n> **نکته:** اگر وعده پیش از الصاق گرداننده، محقق یا رد شده باشد، گرداننده فراخوانده خواهد شد. مسابقه‌ای بین کامل شدن عملیات ناهم‌گام و الصاق شدن گرداننده‌های آن نیست. [ارجاع](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise#Description)\n\n#### منابع خارجی\n\n- [JavaScript Promises for dummies - Jecelyn Yeen](https://scotch.io/tutorials/javascript-promises-for-dummies)\n- [JavaScript Promise API - David Walsh](https://davidwalsh.name/promises)\n- [Using promises - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises)\n- [What is a promise - Eric Elliott](https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-promise-27fc71e77261)\n- [JavaScript Promises: an Introduction - Jake Archibald](https://developers.google.com/web/fundamentals/getting-started/primers/promises)\n- [Promise documentation - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)\n\n### قالب لفظی (Template literals)\n\nقالب لفظی یک «درج عبارت» یا [*expression interpolation*](https://en.wikipedia.org/wiki/String_interpolation) برای رشته‌های تک یا چندخطی است.\n\nبه عبارت دیگر، یک نحو جدید رشته است که در آن می‌توانید به راحتی هر گونه عبارت (مثلا متغیرها) جاوااسکریپتی را استفاده کنید.\n\n#### نمونه کد\n\n```js\nconst name = \"Nick\";\n`Hello ${name}, the following expression is equal to four : ${2+2}`;\n\n// Hello Nick, the following expression is equal to four: 4\n```\n\n#### منابع خارجی\n\n- [String interpolation - ES6 Features](http://es6-features.org/#StringInterpolation)\n- [ES6 Template Strings - Addy Osmani](https://developers.google.com/web/updates/2015/01/ES6-Template-Strings)\n\n### قالب لفظی برچسب‌دار\n\nبرچسب‌های قالب *توابعی هستند که می‌توانند به صورت پیش‌وند به [قالب‌های لفظی](#قالب-لفظی-template-literals) متصل شوند*. وقتی یک تابع به این روش صدا زده می‌شود اولین پارامتر، یک آرایه از *رشته‌ها* است که بین متغیرهای درج قالب ظاهرا می‌شوند و پارامتر بعدی مقادری است که باید درج شوند. از یک عملگر گسترش `...` برای دستیابی به همه آن‌ها بهره ببرید. [(مرجع)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#Tagged_template_literals).\n\n> **نکته:** کتابخانه معروفی به نام [styled-components](https://www.styled-components.com/) به شدت به این ویژگی متکی است.\n\nاین مثالی است از این که این قابلیت چگونه کار می‌کند:\n\n```js\nfunction highlight(strings, ...values) {\n  const interpolation = strings.reduce((prev, current) => {\n    return prev + current + (values.length ? \"<mark>\" + values.shift() + \"</mark>\" : \"\");\n  }, \"\");\n\n  return interpolation;\n}\n\nconst condiment = \"jam\";\nconst meal = \"toast\";\n\nhighlight`I like ${condiment} on ${meal}.`;\n// \"I like <mark>jam</mark> on <mark>toast</mark>.\"\n```\n\nمثالی جالب‌تر:\n\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// \"I like apples, bananas, cherries to snack on.\"\n```\n\n#### منابع خارجی\n- [Wes Bos on Tagged Template Literals](http://wesbos.com/tagged-template-literals/)\n- [Library of common template tags](https://github.com/declandewet/common-tags)\n\n### درون‌ریزی / برون‌ریزی\n\nپیمانه‌ها (modules) در ES6 این امکان را فراهم می‌آورند که بتوان به متغیرها و توابعی که توسط یک پیمانه صریحا برون‌ریزی شده‌اند از پیمانه‌ای دیگر که آن پیمانه را درون‌ریزی می‌کنند دسترسی داشت.\n\nقویا پیشنهاد می‌کنم به منابع موجود روی MDN درباره درون‌ریزی/برون‌ریزی یا import/export (به منابع خارجی این بخش رجوع کنید) نگاهی داشته باشید که هم سرراست است و هم کامل.\n\n#### توضیح به همراه نمونه کد\n\n##### برون‌ریزی بانام\n\nبرون‌ریزی بانام برای برون ریزی مقادیر از یک پیمانه مورد استفاده قرار می‌گیرد.\n\n> **نکته:** فقط می‌توانید [first-class citizens](https://en.wikipedia.org/wiki/First-class_citizen) که دارای نام هستند را به صورت بانام برون‌ریزی کنید.\n\n```js\n// mathConstants.js\nexport const pi = 3.14;\nexport const exp = 2.7;\nexport const alpha = 0.35;\n\n// -------------\n\n// myFile.js\nimport { pi, exp } from './mathConstants.js'; // درون‌ریزی نام‌دار -- با نحوی مشابه تجزیه کردن\nconsole.log(pi) // 3.14\nconsole.log(exp) // 2.7\n\n// -------------\n\n// mySecondFile.js\nimport * as constants from './mathConstants.js';\n// تزریق همه مقادیر برون‌ریزی شده به متغیر constants\nconsole.log(constants.pi) // 3.14\nconsole.log(constants.exp) // 2.7\n```\n\nدر حالی که درون‌ریزی‌های نام‌دار شبیه به *تجزیه کردن* به نظر می‌رسند، اما دارای نحوی متفاوت بوده و مشابه آن نیستند. آن‌ها نه از مقادیر پیش‌فرض پشتیبانی مي‌کنند و نه از تجزیه کردن *عمیق*.\n\nدر کنار این، شما می‌توانید از مترادف‌ها (alias) استفاده کنید اما قواعد نحوی با آن چه که در تجزیه کردن وجود دارد متفاوت است.\n\n```js\nimport { foo as bar } from 'myFile.js';\n// در این جا foo درون‌ریزی شده و در متغیر جدیدی به نام bar تزریق شده است.\n```\n\n##### درون‌ریزی / برون‌ریزی پیش‌فرض\n\nنظر به برون‌ریزی پیش‌فرض، هر پیمانه تنها می‌تواند یک برون‌ریزی پیش‌فرض داشته باشد. این برون‌ریزی پیش‌فرض می‌تواند یک تابع، یک کلاس، یک شیء و یا هر چیز دیگری باشد. این مقدار مقدار برون‌ریزی اصلی (main) شناخته می‌شود چرا که راحت‌ترین روش برای درون‌ریزی است. [مرجع: MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export#Description)\n\n```js\n// coolNumber.js\nconst ultimateNumber = 42;\nexport default ultimateNumber;\n\n// ------------\n\n// myFile.js\nimport number from './coolNumber.js';\n// برون‌ریزی پیش‌فرض، مستقل از این که چه نامی داشته باشد به طور خودکار متغیر number درون‌ریزی شده است.\nconsole.log(number) // 42\n```\n\nبرون‌ریزی تابع\n\n```js\n// sum.js\nexport default function sum(x, y) {\n  return x + y;\n}\n// -------------\n\n// myFile.js\nimport sum from './sum.js';\nconst result = sum(1, 2);\nconsole.log(result) // 3\n```\n\n#### منابع خارجی\n\n- [ES6 Modules in bulletpoints](https://ponyfoo.com/articles/es6#modules)\n- [Export - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export)\n- [Import - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import)\n- [Understanding ES6 Modules](https://www.sitepoint.com/understanding-es6-modules/)\n- [Destructuring special case - import statements](https://ponyfoo.com/articles/es6-destructuring-in-depth#special-case-import-statements)\n- [Misunderstanding ES6 Modules - Kent C. Dodds](https://medium.com/@kentcdodds/misunderstanding-es6-modules-upgrading-babel-tears-and-a-solution-ad2d5ab93ce0)\n- [Modules in JavaScript](http://exploringjs.com/es6/ch_modules.html#sec_modules-in-javascript)\n\n### مفهوم this در جاوااسکریپت\n\nرفتار عملگر *this* جاوااسکریپت متفاوت است از دیگر زبان‌ها و در بسیاری موارد به این بستگی دارد که چه طور یک تابع فراخوانی شده باشد. ([مرجع: MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this))\n\nاین مفهوم ظرافت‌های بسیاری دارد و تا حدودی دشوار است. شدیدا پیشنهاد می‌کنم که شیرجه عمیقی بزنید به منابع خارجی‌ای که پایین‌تر معرفی شده‌اند. با این حال آن چه را که شخصا از چیستی *this* در ذهنم دارم را اینجا ارائه می‌کنم. این نکته را از [این مقاله به قلم یودا کتز](http://yehudakatz.com/2011/08/11/understanding-javascript-function-invocation-and-this/) فراگرفته‌ام.\n\n```js\nfunction myFunc() {\n  ...\n}\n// پس از هر گزاره، مقدار *this* در تابع myFunc را خواهید دید\n\nmyFunc.call(\"myString\", \"hello\") // \"myString\"\n// مقدار اولین پارامتر ‪.call‬ در *this* تزریق می‌شود\n\n// در حال غیرسخت‌گیرانه (non-strict mode)\nmyFunc(\"hello\") // window\n// در واقع ‪myFunc()‬ نحو راه‌دست‌تر برای myFunc.call(window,\"hello\") است\n\n// در حالت سخت‌گیرانه (strict mode)\nmyFunc(\"hello\") // undefined\nاینجا ‪myFunc()‬ نحو راه‌دست‌تر برای myFunc.call(undefined, \"hello\") است\n```\n\n```js\nvar person = {\n  myFunc: function() { ... }\n}\n\nperson.myFunc.call(person, \"test\") // ‫شیء person\n// اولین پارامتر call در *this* تزریق می‌شود\nperson.myFunc(\"test\") // ‫شیء person\n// اینجا ‪person.myFunc()‬ نحو راه‌دست‌تر برای person.myFunc.call(person, \"test\") است\nvar myBoundFunc = person.myFunc.bind(\"hello\") // ‫تابعی جدید می‌سازد که ما «hello» را در *this* آن تزریق می‌کنیم.\nperson.myFunc(\"test\") // ‫شیء person\n// متد bind تاثیر روی متد اصلی ندارد\nmyBoundFunc(\"test\") // \"hello\"\n//تابع myBoundFunc در واقع همان person.myFunc است که در آن «hello» به *this* بند (bind) زده شده است.\n```\n\n#### منابع خارجی\n\n- [Understanding JavaScript Function Invocation and \"this\" - Yehuda Katz](http://yehudakatz.com/2011/08/11/understanding-javascript-function-invocation-and-this/)\n- [JavaScript this - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this)\n\n### کلاس\n\nجاوااسکریپت یک زبان برنامه‌نویسی بر پایه پیش‌نمونه یا [prototype-based](https://en.wikipedia.org/wiki/Prototype-based_programming) است (در حالی که جاوا یک زبان کلاس محور یا [class-based](https://en.wikipedia.org/wiki/Class-based_programming) است). ES6 کلاس‌های جاوااسکریپت را معرفی کرده است که بیشتر به منظور ارائه نحوی راه‌دست‌تر برای ارث‌بری مبتنی بر پیش‌نمونه است و نه یک مدل ارث‌بری کلاس‌محور ([مرجع](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes)).\n\nاگر با کلاس‌ها در سایر زبان‌ها آشنایی داشته باشید، واژه *class* اینجا در واقع مستعد بروز خطاست. اگر آشنایی دارید، از تصور این که کلاس‌های جاوااسکریپت بر همان اساس کار می‌کنند پرهیز کنید و در نظر بگیرید که مفهومش در اینجا به کلی چیز دیگری است.\n\nاز آن جایی که این سند تلاش ندارد تا زبان را از بیخ آموزش بدهد، فرض خواهم کرد که شما با پیش‌نمونه‌ها (prototypes) و این که چه طور کار می‌کنند آشنایی دارید. اگر آشنایی ندارید به منابع خارجی همین بخش مراجعه کنید.\n\n#### نمونه‌ها\n\nنحو پیش‌نمونه‌ها پیش از ES6:\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\nنحو کلاس پس از ES6:\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) // 23\nconsole.log(myPerson.stringSentence()) // \"Hello, my name is Manu and I'm 23\n```\n\n#### منابع خارجی\n\nبرای فهم پیش‌نمونه:\n\n- [Understanding Prototypes in JS - Yehuda Katz](http://yehudakatz.com/2011/08/12/understanding-prototypes-in-javascript/)\n- [A plain English guide to JS prototypes - Sebastian Porto](http://sporto.github.io/blog/2013/02/22/a-plain-english-guide-to-javascript-prototypes/)\n- [Inheritance and the prototype chain - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain)\n\nبرای فهم کلاس‌ها:\n\n- [ES6 Classes in Depth - Nicolas Bevacqua](https://ponyfoo.com/articles/es6-classes-in-depth)\n- [ES6 Features - Classes](http://es6-features.org/#ClassDefinition)\n- [JavaScript Classes - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes)\n\n### کلیدواژه‌های `Extends` و `super`\n\nکلیدواژه `extends` در اعلان کلاس یا عبارات کلی برای ساخت یک کلاس که فرزند کلاس دیگری است استفاده می‌شود ([مرجع: MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/extends)). زیرکلاس تمام خاصیت‌های فراکلاس را به ارث می‌برد و افزون بر این می‌تواند خاصیت‌های جدید اضافه کند یا خاصیت‌های ارث برده را تغییر دهد.\n\nکلیدواژه `super` برای فراخوانی توابع در والد شیء شامل سازنده (constructor) استفاده می‌شود.\n\n- کلیدواژه `super` بایستی پیش از کلیدواژه `this` در constructor استفاده شود\n- اجرای ‪`super()`‬، سازنده کلاس والد را فرامی‌خواند. برای فرستادن چند آرگومان از سازندهٔ کلاس به سازندهٔ کلاس والد از `super(arguments)` استفاده کنید.\n- اگر کلاس والد متدی (حتی ایستا یا static) به نام `X` دارد می‌توانید از ‪`super.X()`‬ برای فراخوانی‌اش در کلاس فرزند استفاده کنید.\n\n#### نمونه کد\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    // اینجا، سازندهٔ کلاس والد به همراه طول ارائه شده برای\n    // عرض و ارتفاع چندضلعی فراخوانده می‌شود\n    super(length, length);\n    // نکته: در کلاس‌های مشتق شده، ‪super()‬ بایستی پیش از this فراخوانی\n    // شود. در غیر این صورت خطای reference دریافت خواهید کرد.\n    this.name = 'Square';\n    this.length = length;\n  }\n\n  getCustomHelloPhrase() {\n    const polygonPhrase = super.getHelloPhrase();\n    // دسترسی به متد والد با نحو ‪super.X()\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) // 100\nconsole.log(mySquare.getHelloPhrase()) // 'Hi, I am a Square'\n// در واقع Square از Polygon ارث بده و به متدهای آن دسترسی دارد\nconsole.log(mySquare.getCustomHelloPhrase()) // 'Hi, I am a Square with a length of 10'\n```\n\n**نکته:** اگر در کلاس Square پیش از فراخوانی `super()` از `this` استفاده کنید، خطای ReferenceError دریافت خواهید کرد.\n\n```js\nclass Square extends Polygon {\n  constructor(length) {\n    this.height; // ReferenceError, super needs to be called first!\n\n    // اینجا، سازندهٔ کلاس والد همراه با طول‌های ارائه شده\n    // برای طول و عرض چندضلعی فراخوانی می‌شود.\n    super(length, length);\n\n    // توجه: در کلاس‌های مشتق شده، ‪super()‬ باید پیش از this\n    // فراخوانی شود. در غیر این صورت خطا دریافت خواهید کرد.\n    this.name = 'Square';\n  }\n}\n```\n\n#### منابع خارجی\n\n- [Extends - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/extends)\n- [Super operator - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/super)\n- [Inheritance - MDN](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Inheritance)\n\n### استفاده از Async Await\n\nافزون بر [وعده‌ها](#وعدهها-promises) ممکن است با یک نحو جدید دیگر نیز در مواجهه با کدهای ناهم‌گام مواجه شوید به نام *async / await*.\n\nهدف توابع async/await، ساده‌سازی رفتار استفاده از وعده‌ها به صورت هم‌گام و انجام برخی رفتارها روی گروهی از وعده‌هاست. درست همان طور که وعده‌ها مشابه callbackهای ساختاردار هستند، async/await مشابه ترکیب سازنده‌ها (generators) و وعده‌هاست. ([مرجمع: MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function))\n\n> **توجه:** لازم است پیش از تلاش برای فهم async / await بدانید که وعده‌ها چیستند و چگونه کار می‌کنند چرا که شالوده کار همان است.\n\n> **نکته ۲:** [*await* بایستی با یک تابع *async* استفاده شود](https://hackernoon.com/6-reasons-why-javascripts-async-await-blows-promises-away-tutorial-c7ec10518dd9#f3f0) که یعنی نمی‌توانید از await در سطح بالای کدتان استفاده کنید چرا که داخل یک تابع ناهمگام یا async نیست.\n\n#### نمونه کد\n\n```js\nasync function getGithubUser(username) { \n// کلیدواژه asunc اجازه استفاده از await را در تابع می‌دهد که یعنی تابع، یک وعده را باز خواهد گرداند.\n  const response = await fetch(`https://api.github.com/users/${username}`);\n  // اجرای کد در اینجا متوقف می‌شود تا زمانی که وعده بازگردانده شده از fetch رفع شده و یک ‪responce.json()‬ بازگرداند\n}\n\ngetGithubUser('mbeaudru')\n  .then(user => console.log(user)) // logging user response\n  // نمی‌توان از نحو await استفاده کرد چون این کد داخل یک تابع async نیست\n  .catch(err => console.log(err)); // اگر خطایی در تابع ناهم‌گام ما بروز کند اینجا آن را دریافت خواهیم کرد\n```\n\n#### توضیح با نمونه کد\n\nدر واقع *Async / Await* برروی وعده‌ها ساخته شده اما اجازه می‌دهد به سبکی دستوری‌تر (imperative) کدنویسی کنیم.\n\nعملگر *async* یک تابع را به عنوان تابع ناهم‌گام علامت‌گذاری می‌کند و همواره یک *وعده* یا Promise باز می‌گرداند. می‌توانید از عملگر *await* در یک تابع *async* به منظور ایجاد مکث در روند اجرا در آن خط تا زمانی که وعده بازگردانده شود استفاده شود. این وعده می‌تواند محقق یا رد شده باشد.\n\n```js\nasync function myFunc() {\n  // می‌توانیم از عملگر await استفاده کنیم زیرا در یک تابع async هستیم\n  return \"hello world\";\n}\n\nmyFunc().then(msg => console.log(msg)) // \"hello world\"\n// به واسطه عملگر async، مقدار بازگشتی از myFunc به یک وعده تغییر یافته است\n```\n\nوقتی به دستور *return* در یک تابع ناهم‌گام یا async می‌رسیم، وعده با مقداری که بازگشت داده می‌شود محقق شده است. اگر خطایی داخل تابع async بروز کند، وضعیت وعده به *رد شده* تغییر می‌کند. اگر مقداری از تابع async بازگردانده نشود، با اتمام اجرای تابع async همچنان وعده‌ای باز گردانده می‌شود که فاقد مقدار است.\n\nعملگر *await* برای آن استفاده می‌شود که منتظر محقق شدن *وعده* بمانیو و تنها می‌تواند در بدنه یک تابع *async* استفاده شود. به محض رسیدن اجرای برنامه به این خط، چرخه اجرا مکث می‌کند تا زمانی که وعده محقق شود.\n\n> **توجه:** *fatch* تابعی است که وعده‌ای باز می‌گرداند و اجازه می‌دهد که یک درخواست ای‌جکس بفرستیم.\n\nبگذارید ابتدا ببینیم چه طور می‌توانیم یک کاربر گیت‌هاب را با fetch دریافت کنیم:\n\n```js\nfunction getGithubUser(username) {\n  return fetch(`https://api.github.com/users/${username}`).then(response => response.json());\n}\n\ngetGithubUser('mbeaudru')\n  .then(user => console.log(user))\n  .catch(err => console.log(err));\n```\n\nو این، معادلش با استفاده از *async / await* است:\n\n```js\nasync function getGithubUser(username) { // promise + await keyword usage allowed\n  const response = await fetch(`https://api.github.com/users/${username}`); // اجرا در اینجا متوقف می‌شود تا وعده‫ fetch محقق شود\n  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 / await* به خصوص زمانی که می‌خواهید وعده‌های مستقل از هم را به هم زنجیر کنید بسیار راه‌دست است.\n\nبه عنوان مثلا اگر نیاز داشته باشید توکنی را بگیرد که با آن بتوانید یک مطلب وبلاگ را واکشی کنید از پایگاه داده و سپس اطلاعات نویسنده را به دست آورید:\n\n> **توجه:** عبارت‌های *await* نیازمند آن است که داخل پرانتز قرار بگیرد تا بتوان متدها و خاصیت‌های مقدار حاصل شده‌اش در همان خط دست یافت.\n\n```js\nasync function fetchPostById(postId) {\n  const token = (await fetch('token_url')).json().token;\n  const post = (await fetch(`/posts/${postId}?token=${token}`)).json();\n  const author = (await fetch(`/users/${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##### مدیریت خطا\n\nجز در حالتی که عبارت‌های *await* را داخل بلوک‌های *try / catch* قرار داده باشیم، خطاهایی که بروز می‌کنند (فارغ از این که در بدنه تابع *async* حادث شده باشد یا زمانی که حین *await* معلق شده باشد) وعده‌ای که توسط تابع async بازگردانده می‌شود رد خواهد شد. استفاده از دستور `throw` در تابع async درست همانند برگرداندن یک وعده رده‌شده است ([(مرجع: PonyFoo)](https://ponyfoo.com/articles/understanding-javascript-async-await#error-handling)).\n\n> **توجه:** وعده‌ها مثل هم رفتار می‌کنند.\n\nاین جا روشی است که به کمکش می‌توانید خطاهای مرتبط با وعده‌ها را مدیریت کنید:\n\n```js\nfunction getUser() { // ‫این وعده رد خواهد شد!\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)); // \"User not found !\"\n```\n\nمعادل آن با *async / await*:\n\n```js\nasync function getUser() { // وعده بازگردانده‌شده رد خواهد شد\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)); // \"User not found !\"\n```\n\n#### منابع خارجی\n\n- [Async/Await - JavaScript.Info](https://javascript.info/async-await)\n- [ES7 Async/Await](http://rossboucher.com/await/#/)\n- [6 Reasons Why JavaScript’s Async/Await Blows Promises Away](https://hackernoon.com/6-reasons-why-javascripts-async-await-blows-promises-away-tutorial-c7ec10518dd9)\n- [JavaScript awaits](https://dev.to/kayis/javascript-awaits)\n- [Using Async Await in Express with Node 8](https://medium.com/@Abazhenov/using-async-await-in-express-with-node-8-b8af872c0016)\n- [Async Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)\n- [Await](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await)\n- [Using async / await in express with node 8](https://medium.com/@Abazhenov/using-async-await-in-express-with-node-8-b8af872c0016)\n\n### درستی / غلطی\n\nدر جاوااسکریپت، مقدار صحیح و غلط (true و false) مقداری است که در زمان ارزیابی در زمینه بولی، به مقدار بولی تبدیل می‌شود. به عنوان مثالی از زمینه بولی می‌توان به ارزیابی شرط `if` اشاره کرد.\n\nهر مقداری به مقدار صحیح یا ‍`true` تبدیل می‌شود مگر آن که برابر باشد با یکی از موارد زیر:\n\n- ```false```\n- ```0```\n- ```\"\"``` (empty string)\n- ```null```\n- ```undefined```\n- ```NaN```\n\nاین‌ها مثال‌هایی هستند از *مزینه بولی*:\n\n- ارزیابی شرط `if`\n\n```js\nif (myVar) {}\n```\n\nمقدار `myVar` می‌تواند هر یک از شهروندان درجه یک یا [first-class citizen](https://en.wikipedia.org/wiki/First-class_citizen) (متغیر، تابع، بولی) باشد اما به مقدار بولی تبدیل می‌شود زیرا در یک زمینه بولی درحال ارزیابی شدن است.\n\n- بعد از عملگر منطقی **NOT** یعنی `!`\n\nاگر گزاره‌ای که این عملگر روی اعمال می‌شود قابل تبدیل شدن به true باشد، این عملگر باعث می‌شود که مقدار false برگردانده شود در غیر این صورت مقدار بازگشتی، true خواهد بود.\n\n```js\n!0 // true -- 0 is falsy so it returns true\n!!0 // false -- 0 is falsy so !0 returns true so !(!0) returns false\n!!\"\" // false -- empty string is falsy so NOT (NOT false) equals false\n```\n\n- با سازنده شیٔ بولی\n\n```js\nnew Boolean(0) // false\nnew Boolean(1) // true\n```\n\n- در یک ارزیابی سه بخشی\n\n```js\nmyVar ? \"truthy\" : \"falsy\"\n```\n\nاینجا myVar در حال ارزیابی شدن در یک زمینه بولی است.\n\nزمانی که در حال مقایسه دو مقدار هستید مراقب باشید. مقادیر شیء (که باید تبدیل به true شوند) به مقدار بولی تبدیل **نمی‌شود* بلکه قهرا به واسطه [ToPrimitives specification](http://javascript.info/object-toprimitive) به مقدار اولیهٔ یک تبدیل می‌شوند. در اصل زمانی که یک شیء با یک مقدار بولی مانند ‬‪`[] == true`‬ مقایسه می‌شود، این عملیات رح مي‌دهد: ‪`[].toString() == true`\n\n```js\nlet a = [] == true // a is false since [].toString() give \"\" back.\nlet b = [1] == true // b is true since [1].toString() give \"1\" back.\nlet c = [2] == true // c is false since [2].toString() give \"2\" back.\n```\n\n#### منابع خارجی\n\n- [Truthy (MDN)](https://developer.mozilla.org/en-US/docs/Glossary/Truthy)\n- [Falsy (MDN)](https://developer.mozilla.org/en-US/docs/Glossary/Falsy)\n- [Truthy and Falsy values in JS - Josh Clanton](http://adripofjavascript.com/blog/drips/truthy-and-falsy-values-in-javascript.html)\n\n### توابع Anamorphisms و Catamorphisms\n\n#### تابع Anamorphisms\n\n‫Anamorphisms توابع هستند که از برخشی اشیاء به ساختارهای پیچیده‌تری شامل نوع شیء نگاشت می‌شوند. فرایند گسترش یا *unfolding* یک ساختار ساده به یک ساختار پیچیده‌تر هستند. گسترش دادن یک عدد صحیح به فهرستی (list) از اعداد صحیح را در نظر بگیرید. عدد صحیح، شیء اولیه ماست و فهرست اعداد صحیح، آن ساختار پیچیده‌تر.\n\n\n##### نمونه کد\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  //=> [ 5, 4, 3, 2, 1 ]\n```\n\n#### تابع Catamorphisms\n\n‫Catamorphisms نقطه مقابل Anamorphisms است و یک شیء با ساختاری پیچیده‌تر را به ساختاری ساده‌تر می‌کاهند. مثای بعدی را در نظر بگیرید که در آن، تابع `product` فهرستی از اعداد صحیح را گرفته و تنها یک عدد صحیح باز می‌گرداند.\n\n##### نمونه کد\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)) // 120\n```\n\n#### منابع خارجی\n\n* [Anamorphisms in JavaScript](http://raganwald.com/2016/11/30/anamorphisms-in-javascript.html)\n* [Anamorphism](https://en.wikipedia.org/wiki/Anamorphism)\n* [Catamorphism](https://en.wikipedia.org/wiki/Catamorphism)\n\n### تولیدکننده‌ها\n\nراه دیگر نوشتن تابع `downToOne` استفاده از تولیدکننده‌ها یا Generatorهاست. برای برپاسازی یک شیء `Generator` می‌بایست از اعلان ‪`function *`‬ استفاده کنیم. تولیدکننده‌ها توابعی هستند که می‌شود از آن‌ها خارج و سپس وارد زمینه‌شان (متغیر گره‌خورده به‌شان) شد که در طول ورودها حفظ می‌شود.\n\nبه عنوان مثال می‌توانیم تابع `downToOne` را این گونه بازنویسی کنیم:\n\n```js\nfunction * downToOne(n) {\n  for (let i = n; i > 0; --i) {\n    yield i;\n  }\n}\n\n[...downToOne(5)] // [ 5, 4, 3, 2, 1 ]\n```\n\nتابع تولیدکننده، یک شیء شمارش‌گر از بازمی‌گرداند. وقتی تابع ‪`Next()`‬ شمارش‌گر صدا زده می‌شود، تا رسیدن به عبارت `yield` (که مقدار مورد نظر برای بازگردانده شدن از آن شمارش به خصوص را تعیین می‌کند) و یا با ‪`yield*`‬ که به تابع تولید کننده دیگری اشاره می‌کند اجرا می‌شود. وقتی که عبارت `return` در تولیدکننده صدا زده می‌شود، تولیدکننده برچسب انجام شده دریافت می‌کند و مقدار تولید شده در آن شمارش بازگردانده می‌شود. فراخوانی‌های بعدی ‪`next()`‬ منجر به بازگرداندن مقادیر جدیدی نمی‌شود.\n \n#### نمونه کد\n\n```js\n// Yield Example\nfunction * idMaker() {\n  var index = 0;\n  while (index < 2) {\n    yield index;\n    index = index + 1;\n  }\n}\n\nvar gen = idMaker();\n\ngen.next().value; // 0\ngen.next().value; // 1\ngen.next().value; // undefined\n```\n\nعبارت `yield` یک تولیدکننده را قادر می‌سازد تا در خلال شمارش، تابع تولیدکننده دیگری را فراخوانی کند.\n\n```js\n// 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; // 10\ngen.next().value; // 11\ngen.next().value; // 12\ngen.next().value; // 13\ngen.next().value; // 20\n```\n\n```js\n// Generator Return Example\nfunction* yieldAndReturn() {\n  yield \"Y\";\n  return \"R\";\n  yield \"unreachable\";\n}\n\nvar gen = yieldAndReturn()\ngen.next(); // { value: \"Y\", done: false }\ngen.next(); // { value: \"R\", done: true }\ngen.next(); // { value: undefined, done: true }\n```\n\n#### منابع خارجی\n\n* [Mozilla MDN Web Docs, Iterators and Generators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators#Generators)\n\n### متدهای ایستا\n\n#### توضیح کوتاه\n\nدر کلاس‌ها، کلیدواژه `static` برای اعلان متدهای ایستا استفاده می‌شود. متدهای ایستا، توابعی در کلاس هستند که به شیء کلاس تعلق داشته و در دسترس هیچ یک از نمونه‌های آن کلاس نیستند.\n\n##### نمونه کد\n\n```js\nclass Repo {\n  static getName() {\n    return \"Repo name is modern-js-cheatsheet\"\n  }\n}\n\nconsole.log(Repo.getName()) // Repo name is modern-js-cheatsheet\n\n// توجه کنید که ما نیازی به ایجاد نمونه‌ای از کلاس Repo نداریم.\n\nlet r = new Repo();\nconsole.log(r.getName()) // Uncaught TypeError: r.getName is not a function\n```\n\n#### توضیح مبسوط\n\nمتدهای ایستا می‌توانند توسط دیگر متدهای ایستا و با کمک کلیدواژه `this` فراخوانی شوند. این کار توسط سایر متدهای غیرایستا قابل انجام نیست. متدهای غیرایستا نمی‌توانند با کمک کلیدواژه `this` مستقیما به متدهای ایستا دسترسی پیدا کنند.\n\n##### فراخوانی متد ایستا توسط متد ایستای دیگر\n\nبه منظور فراخوانی یک متد ایستا دیگر توسط یک متد ایستای دیگر کافی است از کلیدواژه `this` به این شکل استفاده کنیم:\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()) // Repo name is modern-js-cheatsheet-added-this\n```\n\n##### فراخوانی متدهای ایستا توسط متدهای غیرایستا\n\nاین کار به دو روش قابل انجام است:\n\n1. ###### استفاده از نام کلاس\n\nبرای دسترسی به متد ایستا از داخل یک متد غیر ایستا، از نام کلاس استفاده کرده و آن متد را مانند یک خاصیت مثل `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// برای استفاده از متدهای غیرایستا لازم است نمونه‌ای از کلاس ساخته شود\nlet r = new Repo()\nconsole.log(r.useName()) // Repo name is modern-js-cheatsheet and it contains some really important stuff\n```\n\n2. ###### استفاده از سازنده\n\nمتدهای ایستا می‌توانند به عنوان خاصیت در شیء سازنده (constructor) صدا زده شوند.\n\n```js\nclass Repo {\n  static getName() {\n    return \"Repo name is modern-js-cheatsheet\"\n  }\n\n  useName() {\n    // متد ایستا را به عنوان یک خاصیت سازنده فرا می‌خوانیم\n    return this.constructor.getName() + ' and it contains some really important stuff'\n}\n  }\n\n// برای استفاده از متدهای غیرایستا لازم است نمونه‌ای از کلاس ساخته شود\nlet r = new Repo()\nconsole.log(r.useName()) // Repo name is modern-js-cheatsheet and it contains some really important stuff\n```\n\n#### منابع خارجی\n- [static keyword- MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/static)\n- [Static Methods- Javascript.info](https://javascript.info/class#static-methods)\n- [Static Members in ES6- OdeToCode](http://odetocode.com/blogs/scott/archive/2015/02/02/static-members-in-es6.aspx)\n\n## واژه‌نامه\n\n### قلمرو\n\nزمینه‌ای که در ان مقادیر و عبارات «نمایان» هستند یا می‌توانند مورد ارجاع داده شوند. اگر یک متغیر یا عبارت دیگر در «قلمروی جاری» نیست برای استفاده قابل دسترس نخواهد بود.\n\nمنبع: [MDN](https://developer.mozilla.org/en-US/docs/Glossary/Scope)\n\n### تغییر متغیر\n\nیک متغیر را تغییریافته می‌خوانیم اگر مقدار اولیه آن در ادامه کار تغییر کند.\n\n```js\nvar myArray = [];\nmyArray.push(\"firstEl\") // آرایه ما تغییر یافته است\n```\n\nیک متغیر یا غیرقابل تغییر یا *immutable* می‌نامیم اگر نتوان آن را تغییر داد.\n\n[مقاله تغییرپذیری در MDN](https://developer.mozilla.org/en-US/docs/Glossary/Mutable) را برای جزئیات بیشتر ببینید.\n"
  },
  {
    "path": "translations/fr-FR.md",
    "content": "# Modern JavaScript Cheatsheet\n\n![Modern JavaScript cheatsheet](https://i.imgur.com/aexPxMb.png)\n<small>Crédits de l’image: [Ahmad Awais ⚡️](https://github.com/ahmadawais)</small>\n\n## Introduction\n\n### Motivation\n\nCe document est un condensé de tout ce que vous devriez savoir sur le JavaScript que vous allez rencontrer dans des projets modernes.\n\nCe guide n’a pas été conçu pour vous apprendre JavaScript à partir de rien, mais pour aider les développeurs ayant des connaissances basiques qui ont des problèmes avec les codebases modernes (ou pour apprendre React, par exemple) à cause des concepts JavaScript utilisés.\n\nDe plus, je vous donnerai parfois des conseils personnels qui pourraient porter à débat, mais je prendrai le soin de le mentionner lorsque je le ferai.\n\n> **Note :** La plupart des concepts introduits ici viennent d’une mise à jour du langage JavaScript (ES2015, souvent appelé ES6. Vous pouvez trouver les nouvelles fonctionnalités. ajoutées par cette mise à jour [ici](http://es6-features.org) (ce site est vraiment bien fait !).\n\n### Ressources complémentaires\n\nLorsque vous avez de la peine à comprendre une notion, je vous suggère de chercher des réponses dans les ressources suivantes :\n\n- [MDN (Mozilla Developer Network)](https://developer.mozilla.org/en-US/search?q=)\n- [You don't know JS (livre)](https://github.com/getify/You-Dont-Know-JS)\n- [ES6 Features with examples](http://es6-features.org)\n- [WesBos blog (ES6)](http://wesbos.com/category/es6/)\n- [Javascript Basics for Beginners](https://www.udacity.com/course/javascript-basics--ud804) - a free Udacity course\n- [Reddit (JavaScript)](https://www.reddit.com/r/javascript/)\n- [Google](https://www.google.com/) pour trouver des blogs et des ressources spécifiques\n- [StackOverflow](https://stackoverflow.com/questions/tagged/javascript)\n\n> **Note :** Presque toutes les ressources externes listées dans ce document sont en anglais, à l’exception des liens menant vers le Mozilla Developer Network (MDN) qui lui est traduit en français.\n\n## Table des matières\n* [Modern JavaScript Cheatsheet](#modern-javascript-cheatsheet)\n   * [Introduction](#introduction)\n      * [Motivation](#motivation)\n      * [Ressources complémentaires](#ressources-complémentaires)\n   * [Table des matières](#table-des-matières)\n   * [Notions](#notions)\n      * [Déclaration des variables : var, const, let](#déclaration-des-variables--var-const-let)\n         * [Explication brève](#explication-brève)\n         * [Code d’exemple](#code-dexemple)\n         * [Explication détaillée](#explication-détaillée)\n            * [var](#var)\n            * [let](#let)\n            * [const](#const)\n         * [Ressources externes](#ressources-externes)\n      * [<a name=\"user-content-arrow_func_concept\"></a> Fonction fléchée](#-fonction-fléchée)\n         * [Code d'exemple](#code-dexemple-1)\n         * [Explication détaillée](#explication-détaillée-1)\n            * [Concision](#concision)\n            * [Référence de <em>this</em>](#référence-de-this)\n         * [Ressources utiles](#ressources-utiles)\n      * [Valeur par défaut d'un paramètre dans une fonction](#valeur-par-défaut-dun-paramètre-dans-une-fonction)\n         * [External resource](#external-resource)\n      * [Déstructurer des objets et des tableaux](#déstructurer-des-objets-et-des-tableaux)\n         * [Explication avec du code](#explication-avec-du-code)\n         * [Ressources utiles](#ressources-utiles-1)\n      * [Méthodes de tableau : map / filter / reduce](#méthodes-de-tableau--map--filter--reduce)\n         * [Code d'exemple](#code-dexemple-2)\n         * [Explication](#explication)\n            * [Array.prototype.map()](#arrayprototypemap)\n            * [Array.prototype.filter()](#arrayprototypefilter)\n            * [Array.prototype.reduce()](#arrayprototypereduce)\n               * [À la première étape d'itération](#À-la-première-étape-ditération)\n               * [À la deuxième étape d'itération](#À-la-deuxième-étape-ditération)\n               * [À la troisième étape d'itération](#À-la-troisième-étape-ditération)\n               * [À la quatrième étape d'itération](#À-la-quatrième-étape-ditération)\n               * [[...] À la dernière étape d'itération](#-À-la-dernière-étape-ditération)\n         * [Ressource externe](#ressource-externe)\n      * [Opérateur de décomposition \"...\"](#opérateur-de-décomposition-)\n         * [Code d'exemple](#code-dexemple-3)\n         * [Explication](#explication-1)\n            * [Dans des tableaux (comme des tableaux)](#dans-des-tableaux-comme-des-tableaux)\n            * [Paramètre de reste d'une fonction](#paramètre-de-reste-dune-fonction)\n            * [Décomposition des propriétés d'un objet](#décomposition-des-propriétés-dun-objet)\n         * [Ressources externes](#ressources-externes-1)\n      * [Raccourci pour les propriétés d'objet](#raccourci-pour-les-propriétés-dobjet)\n         * [Explication](#explication-2)\n         * [Ressources externes](#ressources-externes-2)\n      * [Promesses](#promesses)\n         * [Code d'exemple](#code-dexemple-4)\n         * [Explication](#explication-3)\n            * [Créer la promesse](#créer-la-promesse)\n            * [Utilisation des déclencheurs de promesse](#utilisation-des-déclencheurs-de-promesse)\n         * [Ressources externes](#ressources-externes-3)\n      * [Littéraux de modèle](#littéraux-de-modèle)\n         * [Code d'exemple](#code-dexemple-5)\n         * [Ressources externes](#ressources-externes-4)\n      * [Littéraux de modèle étiquetés](#littéraux-de-modèle-étiquetés)\n         * [Ressources externes](#ressources-externes-5)\n      * [Imports / exports](#imports--exports)\n         * [Explication avec un code d'exemple](#explication-avec-un-code-dexemple)\n            * [Exports nommés](#exports-nommés)\n            * [Import/export par défaut](#importexport-par-défaut)\n         * [Ressources externes](#ressources-externes-6)\n      * [<em>this</em> en JavaScript](#-this-en-javascript)\n         * [Ressources externes](#ressources-externes-7)\n      * [Classe](#classe)\n         * [Exemples](#exemples)\n         * [Ressources externes](#ressources-externes-8)\n      * [Mots clés extends et <code>super</code>](#mots-clés-extends-et-super)\n         * [Code d’exemple](#code-dexemple-6)\n         * [Ressources](#ressources)\n      * [Async Await](#async-await)\n         * [Code d’exemple](#code-dexemple-7)\n         * [Explication avec un code d’exemple](#explication-avec-un-code-dexemple-1)\n            * [Gestion d’erreur](#gestion-derreur)\n         * [Ressources externes](#ressources-externes-9)\n      * [Vérité / fausseté](#vérité--fausseté)\n         * [Ressources externes](#ressources-externes-10)\n      * [Méthodes statiques](#méthodes-statiques)\n         * [Explication courte](#explication-courte)\n         * [Code d’exemple](#code-dexemple-8)\n         * [Explication détaillée](#explication-détaillée-2)\n            * [Appeler d’autres méthodes statiques depuis une méthode statique](#appeler-dautres-méthodes-statiques-depuis-une-méthode-statique)\n            * [Appeler des méthodes statiques depuis des méthodes non statiques](#appeler-des-méthodes-statiques-depuis-des-méthodes-non-statiques)\n               * [En utilisant le nom de la classe](#en-utilisant-le-nom-de-la-classe)\n               * [Avec le constructeur](#avec-le-constructeur)\n         * [Ressources externes](#ressources-externes-11)\n   * [Glossaire](#glossaire)\n      * [Portée (<em>scope</em>)](#-portée-scope)\n      * [Mutation de variable](#-mutation-de-variable)\n\n## Notions\n\n### Déclaration des variables : var, const, let\n\nEn JavaScript, il y a trois mots-clés disponibles pour déclarer une variable, et chacun a ses différences. Ces mots-clés sont ```var```, ```let``` et ```const```.\n\n#### Explication brève\n\nLes variables déclarées avec le mot-clé ```const``` ne peuvent pas être réassignées, alors que celles déclarées avec ```let``` et ```var``` le peuvent.\n\nJe vous recommande de toujours déclarer vos variables avec ```const``` par défaut, et avec ```let``` si vous avez besoin de la *muter* ou de la réassigner plus tard.\n\n<table>\n  <tr>\n    <th></th>\n    <th>Portée</th>\n    <th>Réassignable</th>\n    <th>Mutable</th>\n   <th><a href=\"#tdz_sample\">Temporal Dead Zone</a></th>\n  </tr>\n  <tr>\n    <th>const</th>\n    <td>Bloc</td>\n    <td>Non</td>\n    <td><a href=\"#const_mutable_sample\">Oui</a></td>\n    <td>Oui</td>\n  </tr>\n  <tr>\n    <th>let</th>\n    <td>Bloc</td>\n    <td>Oui</td>\n    <td>Oui</td>\n    <td>Oui</td>\n  </tr>\n   <tr>\n    <th>var</th>\n    <td>Fonction</td>\n    <td>Oui</td>\n    <td>Oui</td>\n    <td>Non</td>\n  </tr>\n</table>\n\n#### Code d’exemple\n\n```javascript\nconst person = \"Nick\";\nperson = \"John\" // Déclenchera une erreur, person ne pouvant pas être réassigné\n```\n\n```javascript\nlet person = \"Nick\";\nperson = \"John\";\nconsole.log(person) // \"John\", le réassignement est permis avec let\n```\n\n#### Explication détaillée\n\nLa [*portée*](#scope_def) d’une variable définit \"où la variable est disponible dans le code\".\n\n##### var\n\nLa portée des variables déclarées avec ```var``` s’étend à la fonction qui la contient, ce qui signifie que lorsqu‘une variable est créée dans une fonction, tout dans cette fonction peut y accéder. De plus, on ne pourra pas accéder à cette variable de l’extérieur de cette fonction. \n\n```javascript\nfunction myFunction() {\n  var myVar = \"Nick\";\n  console.log(myVar); // \"Nick\" - myVar est accessible à l'intérieur de la fonction\n}\nconsole.log(myVar); // Émet une ReferenceError, myVar n'est pas accessible en dehors de la fonction\n```\n\nVoici un exemple plus subtil, toujours sur la portée des variables :\n\n```javascript\nfunction myFunction() {\n  var myVar = \"Nick\";\n  if (true) {\n    var myVar = \"John\";\n    console.log(myVar); // \"John\"\n    // La portée de myVar s'étendant à toute la fonction, nous venons d'écraser la valeur précédente de myVar (\"Nick\"), qui est devenue \"John\"\n  }\n  console.log(myVar); // \"John\" - les instructions dans le bloc if ont affecté cette valeur\n}\nconsole.log(myVar); // Produit une ReferenceError, myVar n'étant pas disponible en dehors de la fonction\n```\n\nDe plus, les variables déclarées avec *var* sont déplacées tout en haut de leur portée à l'exécution. Ce comportement est appelé [var hoisting](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Instructions/var#La_remontée_de_variables_(hoisting)).\n\nCe bout de code :\n\n```js\nconsole.log(myVar) // undefined -- aucune erreur produite\nvar myVar = 2;\n```\n\nest compris à l'exécution comme :\n\n```js\nvar myVar;\nconsole.log(myVar) // undefined -- aucune erreur produite\nmyVar = 2;\n```\n\n##### let\n\n```var``` et ```let ``` sont presque identiques, mais les variables déclarées avec ```let```\n\n- ont leur portée qui est limitée au bloc qui les entoure\n- ne sont **pas** accessibles avant d'être assignées\n- ne peuvent pas être redéclarées dans la même portée\n\nObservons l'impact de la nouvelle portée dans l'exemple précédent :\n\n```javascript\nfunction myFunction() {\n  let myVar = \"Nick\";\n  if (true) {\n    let myVar = \"John\";\n    console.log(myVar); // \"John\"\n    // la portée de myVar étant limitée au bloc if, nous venons de crééer une nouvelle variable myVar.\n    // cette variable n'est pas accessible en dehors du bloc if\n    // et est totalement indépendante du premier myVar créé.\n  }\n  console.log(myVar); // \"Nick\" - les instructions dans le bloc if n'ont PAS affecté cette valeur\n}\nconsole.log(myVar); // Produit une ReferenceError, myVar n'étant pas disponible en dehors de la fonction\n```\n\n<a name=\"tdz_sample\"></a> Maintenant, observons ce que signifie pour les variables créées avec *let* (et *const*) de ne pas être accessibles avant d'avoir été assignées :\n\n```js\nconsole.log(myVar) // déclenche une ReferenceError !\nlet myVar = 2;\n```\n\nContrairement aux variables *var*, si vous essayez de lire ou d'écrire dans une variable *let* ou *const* avant d'être assignées une erreur se produira. Ce phénomène est souvent appelé [*Temporal dead zone*](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let#Temporal_Dead_Zone_and_errors_with_let) ou *TDZ*.\n\n> **Note :** Techniquement, les déclarations de variables *let* and *const*sont aussi affectées par le *var hoisting*, mais pas leur assignation. Vu qu'elles sont faite pour ne pas pouvoir être utilisées avant l'assignation, on a l'impression qu'il n'y a pas de *hoisting*, mais il y en a un. Si vous voulez en savoir plus, vous pouvez lire cette [explication très détaillée](http://jsrocks.org/2015/01/temporal-dead-zone-tdz-demystified).\n\nPar ailleurs, vous ne pouvez pas re-déclarer une variable *let* :\n\n```js\nlet myVar = 2;\nlet myVar = 3; // Produit une SyntaxError\n```\n\n##### const\n\nLes variables déclarées avec```const``` se comportent comme des variables *let*, mais elles ne peuvent pas être réassignées.\n\nPour résumer, les variables *const* :\n\n- ont leur portée qui est limitée au bloc qui les entoure\n- ne sont pas accessibles avant leur assignation\n- ne peuvent pas être redéclarées dans la même portée\n- ne peuvent pas être réassignées\n\n```js\nconst myVar = \"Nick\";\nmyVar = \"John\" // cause une erreur, le réassignement n'est pas permis\n```\n\n```js\nconst myVar = \"Nick\";\nconst myVar = \"John\" // cause une erreur, la redéclaration n'est pas permise\n```\n\n<a name=\"const_mutable_sample\"></a> Mais il y a une subtilité : les variables ```const``` ne sont pas [**immutables**](#mutation_def) ! Concrètement, cela signifie que les *objets* et *tableaux* ```const``` **peuvent** être mutées.\n\nPour les objets :\n```js\nconst person = {\n  name: 'Nick'\n};\nperson.name = 'John' // ceci fonctionnera ! la variable person n'est pas complètement réassignée, mais mutée\nconsole.log(person.name) // \"John\"\nperson = \"Sandra\" // cause une erreur, car le réassignement n'est pas autorisé avec les variables déclarées avec const\n```\n\nPour les tableaux :\n```js\nconst person = [];\nperson.push('John'); // ceci fonctionnera ! la variable person n'est pas complètement réassignée, mais mutée\nconsole.log(person[0]) // \"John\"\nperson = [\"Nick\"]  // cause une erreur, car le réassignement n'est pas autorisé avec les variables déclarées avec const\n```\n\n#### Ressources externes\n\n- [How let and const are scoped in JavaScript - WesBos](http://wesbos.com/javascript-scoping/)\n- [Temporal Dead Zone (TDZ) Demystified](http://jsrocks.org/2015/01/temporal-dead-zone-tdz-demystified)\n\n### <a name=\"arrow_func_concept\"></a> Fonction fléchée\n\nAvec la mise à jour ES6 de JavaScript, nous pouvons utiliser des *fonctions fléchées*, qui sont un autre moyen de déclarer et d'utiliser des fonctions. Voici les bénéfices qu'elles apportent :\n\n- Plus concis\n- *this* se réfère à l'extérieur de la fonction fléchée\n- ```return``` implicite\n\n#### Code d'exemple\n\n- Concision et retour implicite\n\n```js\nfunction double(x) { return x * 2; } // Manière traditionnelle\nconsole.log(double(2)) // 4\n```\n\n```js\nconst double = x => x * 2; // Même fonction écrite sous forme de fonction fléchée avec un retour implicite\nconsole.log(double(2)) // 4\n```\n\n- Référence de *this*\n\nDans une fonction fléchée, *this* est égal à la valeur de *this* dans le contexte d'exécution alentour. Basiquement, avec les fonctions fléchées, vous n'êtes plus obligé d'utiliser l'astuce \"that = this\" avant d'appeler une fonction à l'intérieur d'une fonction.\n\n```js\nfunction myFunc() {\n  this.myVar = 0;\n  setTimeout(() => {\n    this.myVar++;\n    console.log(this.myVar) // 1\n  }, 0);\n}\n```\n\n#### Explication détaillée\n\n##### Concision\n\nLes fonctions fléchées sont plus concises que les fonctions traditionnelles par plusieurs aspects. Voyons tous les cas possibles :\n\n- Retour implicite VS explicite\n\nUn **retour explicite** est une fonction où le mot-clé ```return``` est utilisé dans son corps.\n\n```js\n  function double(x) {\n    return x * 2; // cette fonction retourne explicitement x * 2, le mot-clé return est utilisé\n  }\n```\n\nDans l'écriture de foncitons traditionnelle, le retour était toujours explicite. Mais avec les fonctions fléchées, vous pouvez faire un *retour implicite* ce qui signifie que vous n'êtes pas obligés d'utiliser le mot-clé *return* pour retourner une valeur.\n\nPour faire un retour implicite, le code doit être écrit en une ligne.\n\n```js\n  const double = (x) => {\n    return x * 2; // Ce retour est explicite\n  }\n```\n\nComme il n'y a qu'un retour de valeur ici, nous pouvons utiliser un retour implicite.\n\n```js\n  const double = (x) => x * 2;\n```\n\nPour ce faire, il nous suffit de **supprimer les accolades** et le mot-clé **return**. C'est pour cette raison qu'on qualifie ce retour d'*implicite* : le mot-clé *return* n'est pas là. mais la fonction va bien retourner ```x * 2```.\n\n> **Note :** Si votre fonction ne retourne aucune valeur (avec des *effets secondaires*), elle ne fait ni retour implicite ni explicite.\n\nDe plus, si vous voulez retourner un *objet* vous **devez mettre des parenthèses autour** pour éviter un conflit avec les accolades de bloc :\n\n```js\nconst getPerson = () => ({ name: \"Nick\", age: 24 })\nconsole.log(getPerson()) // { name: \"Nick\", age: 24 } -- l'objet est implicitement retourné par la fonction fléchée\n```\n\n- Uniquement un argument\n\nSi votre fonction ne prend qu'un paramètre, vous pouvez omettre les parenthèses autour. En reprenant un exemple au dessus :\n\n```js\n  const double = (x) => x * 2; // cette fonction fléchée ne prend qu'un paramètre\n```\n\nLes parenthèses autour du paramètre peuvent être évitées :\n\n```js\n  const double = x => x * 2; // cette fonction fléchée ne prend qu'un paramètre\n```\n\n- Pas de paramètres\n\nLorsqu'une fonction fléchée ne prend aucun paramètre, vous devez obligatoirement mettre des parenthèses pour que la syntaxe soit valide :\n\n```js\n  () => { // avec des parenthèses, tout fonctionne\n    const x = 2;\n    return x;\n  }\n```\n\n```js\n  => { // pas de parenthèses, ceci ne fonctionnera pas !\n    const x = 2;\n    return x;\n  }\n```\n\n##### Référence de *this*\n\nPour comprendre cette subtilité des fonctions fléchées, vous devez savoir comment [this](#this_def) fonctionne en JavaScript.\n\nDans une fonction fléchée, *this* est égal à la valeur de *this* dans le contexte d'exécution alentour. Cela signifie qu'une fonction fléchée ne créée pas de nouveau *this*, mais le prend autour à la place.\n\nSans une fonction fléchée, pour accéder à une variable présente dans *this* dans une fonction à l'intérieur d'une fonction, vous deviez utiliser l'astuce de *that = this* ou *self = this*.\n\nPar exemple, voici comment utiliser setTimeout à l'intérieur de myFunc :\n\n```js\nfunction myFunc() {\n  this.myVar = 0;\n  var that = this; // astuce that = this\n  setTimeout(\n    function() { // Un nouveau *this* est créé dans la portée de cette fonction\n      that.myVar++;\n      console.log(that.myVar) // 1\n\n      console.log(this.myVar) // undefined -- voir la déclaration de fonction au-dessus\n    },\n    0\n  );\n}\n```\n\nMais avec une fonction fléchée, *this* est pris de l'extérieur :\n\n```js\nfunction myFunc() {\n  this.myVar = 0;\n  setTimeout(\n    () => { // this pris de l'extérieur, signifiant myFunc ici\n      this.myVar++;\n      console.log(this.myVar) // 1\n    },\n    0\n  );\n}\n```\n\n#### Ressources utiles\n\n- [Arrow functions introduction - WesBos](http://wesbos.com/arrow-functions/)\n- [Fonction fléchées - MDN](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Fonctions/Fonctions_fl%C3%A9ch%C3%A9es)\n- [Arrow function and lexical *this*](https://hackernoon.com/javascript-es6-arrow-functions-and-lexical-this-f2a3e2a5e8c4)\n\n### Valeur par défaut d'un paramètre dans une fonction\n\nÀ partir de la mise à jour de JavaScript ES2015, vous pouvez assigner une valeur par défaut à un paramètre de fonction en utilisant la syntaxe suivante\n\n```js\nfunction myFunc(x = 10) {\n  return x;\n}\nconsole.log(myFunc()) // 10 -- aucune valeur n'étant donnée, la valeur par défaut est utilisée\nconsole.log(myFunc(5)) // 5 -- une valeur est donnée donc x est égal à 5 dans myFunc\n\nconsole.log(myFunc(undefined)) // 10 -- la valeur undefined est donnée, donc x est assigné à la valeur par défaut\nconsole.log(myFunc(null)) // null -- une valeur (null) étant donnée, voir plus bas pour plus de détails\n```\n\nLe paramètre par défaut est utilisé dans deux et uniquement deux situations :\n\n- Aucun paramètre n'est fourni\n- Le paramèter *undefined* est fourni\n\nAutrement dit, si vous passez *null* le paramètre par défaut **ne sera pas appliqué**.\n\n> **Note :** Un assignement de valeur par défaut peut être utilisé avec des paramètres déstructurés également (voyez la notion suivante pour avoir un exemple).\n\n#### External resource\n\n- [Default parameter value - ES6 Features](http://es6-features.org/#DefaultParameterValues)\n- [Valeurs par défaut des arguments - MDN](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Fonctions/Valeurs_par_d%C3%A9faut_des_arguments)\n\n### Déstructurer des objets et des tableaux\n\nLa *déstructuration* un moyen pratique de créer de nouvelles variables en extrayant des valeurs des données enregistrées dans des objets ou des tableaux.\n\nPour nommer quelque cas d'utilisation, la *déstructuration* peut être utilisée pour déstructurer des paramètres de fonction ou *this.props* dans des projets React par exemple.\n\n#### Explication avec du code\n\n- Objet\n\nPrenons l'objet suivant pour tous les exemples\n\n```js\nconst person = {\n  firstName: \"Nick\",\n  lastName: \"Anderson\",\n  age: 35,\n  sex: \"M\"\n}\n```\n\nSans déstructuration :\n\n```js\nconst first = person.firstName;\nconst age = person.age;\nconst city = person.city || \"Paris\";\n```\n\nAvec la déstructuration, tout en une ligne :\n\n```js\nconst { firstName: first, age, city = \"Paris\" } = person; // Et voilà !\n\nconsole.log(age) // 35 -- Une nouvelle variable age est créée et est égale à person.age\nconsole.log(first) // \"Nick\" -- Une nouvelle variable first est créée et est égale à person.firstName\nconsole.log(firstName) // ReferenceError -- person.firstName existe MAIS la nouvelle variable créée est nommée first\nconsole.log(city) // \"Paris\" -- Une nouvelle variable city est créée et comme person.city n'est pas défini, city est égal à la valeur par défaut donnée, à savoir \"Paris\"\n```\n\n**Note :** Dans ```const { age } = person;```, les accolades après le mot-clé *const* ne sont pas utilisées pour déclarer un objet ou un bloc, mais font partie de la syntaxe de *déstructuration*.\n\n- Paramètres de fonction\n\nLa *destructuring* est souvent utilisée pour déstructurer les paramètres de fonction sous la forme d'objets.\n\nSans déstructuration :\n\n```js\nfunction joinFirstLastName(person) {\n  const firstName = person.firstName;\n  const lastName = person.lastName;\n  return firstName + '-' + lastName;\n}\n\njoinFirstLastName(person); // \"Nick-Anderson\"\n```\n\nEn déstructurant le paramètre objet *person*, nous obtenons une fonction plus concise :\n\n```js\nfunction joinFirstLastName({ firstName, lastName }) { // nous crééons les variables firstName et lastName en déstructurant le paramètre person\n  return firstName + '-' + lastName;\n}\n\njoinFirstLastName(person); // \"Nick-Anderson\"\n```\n\nLa déstructuration est encore plus agréable à utiliser avec les [fonctions fléchées](#arrow_func_concept) :\n\n```js\nconst joinFirstLastName = ({ firstName, lastName }) => firstName + '-' + lastName;\n\njoinFirstLastName(person); // \"Nick-Anderson\"\n```\n\n- Tableau\n\nUtilisons le tableau suivant :\n\n```js\nconst myArray = [\"a\", \"b\", \"c\"];\n```\n\nSans la destructuration :\n\n```js\nconst x = myArray[0];\nconst y = myArray[1];\n```\n\nAvec :\n\n```js\nconst [x, y] = myArray; // Et voilà !\n\nconsole.log(x) // \"a\"\nconsole.log(y) // \"b\"\n```\n\n#### Ressources utiles\n\n- [ES6 Features - Destructuring Assignment](http://es6-features.org/#ArrayMatching)\n- [Destructuring Objects - WesBos](http://wesbos.com/destructuring-objects/)\n- [ExploringJS - Destructuring](http://exploringjs.com/es6/ch_destructuring.html)\n\n### Méthodes de tableau : map / filter / reduce\n\n*Map*, *filter* et *reduce* sont des méthodes de tableau qui viennent avec un paradigme de programmation appelé la [*programmation fonctionnelle*](https://medium.com/javascript-scene/master-the-javascript-interview-what-is-functional-programming-7f218c68b3a0).\n\nPour résumer :\n\n- **Array.prototype.map()** prend un tableau, fait quelque chose sur ses éléments et retourne un tableau contenant les éléments transformés.\n- **Array.prototype.filter()** prend un tableau, décide élément par élément s'il faut le garder ou non et retourne un tableau contenant uniquement les éléments conservés.\n- **Array.prototype.reduce()** prend un tableau et agrège ses éléments en une seule valeur (qui est retournée).\n\nJe recommande de les utiliser autant que possibles pour suivre les principes de la programmation fonctionelle car ils sont composables, concis et élégants.\n\nAvec toutes ces méthodes, vous pouvez éviter l'utilisation des boucles *for* et *forEach* dans la plupart des situations. Vous pouvez avoir de la peine au début à les utiliser car ils vous obligent à apprendre une nouvelle façon de penser, mais une fois que vous avez compris comment cela fonctionne tout devient plus facile.\n\n#### Code d'exemple\n\n```js\nconst numbers = [0, 1, 2, 3, 4, 5, 6];\nconst doubledNumbers = numbers.map(n => n * 2); // [0, 2, 4, 6, 8, 10, 12]\nconst evenNumbers = numbers.filter(n => n % 2 === 0); // [0, 2, 4, 6]\nconst sum = numbers.reduce((prev, next) => prev + next, 0); // 21\n```\n\nCalculer la somme des notes (```grades```) des étudiants ayant eu plus que 10 en utilisant map, filter et reduce :\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) // nous transformons le tableau students en un tableau contenant leurs notes\n  .filter(grade => grade >= 10) // nous filtrons le tableau des notes pour ne conserver que celles supérieures ou égales à 10\n  .reduce((prev, next) => prev + next, 0); // nous additionnons toutes les notes au dessus de 10 une par une\n\nconsole.log(aboveTenSum) // 44 -- 10 (Nick) + 15 (John) + 19 (Julia), Nathalie étant ignorée car sa note est inférieure à 10\n```\n\n#### Explication\n\nPrenons le tableau de nombres pour nos exemples :\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); // [0, 2, 4, 6, 8, 10, 12]\n```\n\nQue se passe-t-il ici ? Nous utilisons .map sur le tableau *numbers*, le map itère sur chaque élément du tableau et le passe à notre fonction. Le but de la fonction est de produire et de retourner une nouvelle valeur pour chaque valeur donnée pour que le map puisse la remplacer.\n\nExtrayons cette fonction pour la rendre plus claire, juste pour cette fois-ci :\n\n```js\nconst doubleN = function(n) { return n * 2; };\nconst doubledNumbers = numbers.map(doubleN);\nconsole.log(doubledNumbers); // [0, 2, 4, 6, 8, 10, 12]\n```\n\n```numbers.map(doubleN)``` produit ```[doubleN(0), doubleN(1), doubleN(2), doubleN(3), doubleN(4), doubleN(5), doubleN(6)]``` ce qui est égal à ```[0, 2, 4, 6, 8, 10, 12]```.\n\n> **Note :** Si vous n'avez pas besoin d'un nouveau tableau et que vous voulant juste avoir une boucle ayant des effets secondaires, vous pourriez juste avoir besoin d'une boucle for / forEach à la place d'un map.\n\n##### Array.prototype.filter()\n\n```js\nconst evenNumbers = numbers.filter(function(n) {\n  return n % 2 === 0; // true si \"n\" est pair, false si \"n\" est impair\n});\nconsole.log(evenNumbers); // [0, 2, 4, 6]\n```\n\nNous utilisons .filter sur le tableau *numbers* : filter itère sur chaque élément du tableau et le passe à notre fonction. Le but de la fonction est de retourner un booléen qui déterminera si la valeur actuelle sera conservée. Filter retourne ensuite le tableau avec uniquement les valeurs conservées.\n\n##### Array.prototype.reduce()\n\nLe but de la méthode reduce est de réduire tous les éléments du tableau sur lequel elle itère à une seule valeur. Vous décidez de la manière dont les éléments sont agrégés.\n\n```js\nconst sum = numbers.reduce(\n  function(acc, n) {\n    return acc + n;\n  },\n  0 // valeur de l'accumulateur à la première itération\n);\n\nconsole.log(sum) //21\n```\n\nTout comme pour les méthodes .map et .filter, .reduce est appliqué sur un tableau et prend une fonction en premier paramètre.\n\nCette fois cependant, il y a des changements :\n\n- .reduce prend deux paramètres\n\nLe premier paramètre est une fonction qui sera appelée à chaque étape d'itéraiton.\n\nLe second paramètre est la valeur de la variable d'accumulation (*acc* ici) à la première étape d'itération (lisez le point suivant pour comprendre).\n\n- Paramèters de fonction\n\nLa fonction que vous passez comme premier paramètre de .reduce prend deux paramètres. Le premier (*acc* ici) est la variable d'accumulateur, tandis que le second paramètre (*n*) est l'élément actuel.\n\nLa variable d'accumulateur est égale à la valeur retournée par votre fonction à l'étape d'itération **précédente**. À la première étape de l'itération, *acc* est égale à la valeur que vous avez passé au second paramètre de .reduce.\n\n###### À la première étape d'itération\n\n```acc = 0``` car nous avons passé 0 comme second paramètre à reduce.\n\n```n = 0``` premier élément du tableau *number*\n\nLa fonction retourne *acc* + *n* --> 0 + 0 --> 0\n\n###### À la deuxième étape d'itération\n\n```acc = 0``` car c'est la valeur retournée par la fonction à l'étape d'itération précédente\n\n```n = 1``` deuxième élément du tableau *number*\n\nLa fonction retourne *acc* + *n* --> 0 + 1 --> 1\n\n###### À la troisième étape d'itération\n\n```acc = 1``` car c'est la valeur retournée par la fonction à l'étape d'itération précédente\n\n```n = 2``` troisième élément du tableau *number*\n\nLa fonction retourne *acc* + *n* --> 1 + 2 --> 3\n\n###### À la quatrième étape d'itération\n\n```acc = 3``` car c'est la valeur retournée par la fonction à l'étape d'itération précédente\n\n```n = 3``` quatrième élément du tableau *number*\n\nLa fonction retourne *acc* + *n* --> 3 + 3 --> 6\n\n###### [...] À la dernière étape d'itération\n\n```acc = 15``` car c'est la valeur retournée par la fonction à l'étape d'itération précédente\n\n```n = 6``` dernier élément du tableau *number*\n\nLa fonction retourne *acc* + *n* --> 15 + 6 --> 21\n\nComme c'est la dernière étape d'itération, **.reduce** retourne 21.\n\n#### Ressource externe\n\n- [Understanding map / filter / reduce in JS](https://hackernoon.com/understanding-map-filter-and-reduce-in-javascript-5df1c7eee464)\n\n### Opérateur de décomposition \"...\"\n\nL'opérateur de décomposition ```...``` existe depuis ES2015 et est utilisé pour décomposer les éléments d'un itérable (comme un tableau) dans des emplacements qui peuvent contenir plusieurs éléments.\n\n#### Code d'exemple\n\n```js\nconst arr1 = [\"a\", \"b\", \"c\"];\nconst arr2 = [...arr1, \"d\", \"e\", \"f\"]; // [\"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// \"a\"\n// \"b\"\n// [\"c\", \"d\", \"e\", \"f\"]\n```\n\n```js\nconst { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };\nconsole.log(x); // 1\nconsole.log(y); // 2\nconsole.log(z); // { a: 3, b: 4 }\n\nconst n = { x, y, ...z };\nconsole.log(n); // { x: 1, y: 2, a: 3, b: 4 }\n```\n\n#### Explication\n\n##### Dans des tableaux (comme des tableaux)\n\nSi nous avons les deux tableaux suivants :\n\n```js\nconst arr1 = [\"a\", \"b\", \"c\"];\nconst arr2 = [arr1, \"d\", \"e\", \"f\"]; // [[\"a\", \"b\", \"c\"], \"d\", \"e\", \"f\"]\n```\n\nLe premier élément d'*arr2* est un tableau, car *arr1* est injecté tel quel dans *arr2*. Cependant, nous voulons que *arr2* soit un tableau de lettres. Pour ce faire, nous pouvons *décomposer* les éléments d'*arr1* dans *arr2*.\n\nAvec l'opérateur de décomposition :\n\n```js\nconst arr1 = [\"a\", \"b\", \"c\"];\nconst arr2 = [...arr1, \"d\", \"e\", \"f\"]; // [\"a\", \"b\", \"c\", \"d\", \"e\", \"f\"]\n```\n\n##### Paramètre de reste d'une fonction\n\nDans les paramètres d'une fonction, nous pouvons utiliser l'opérateur de reste pour injecter les paramètres dans un tableau dans lequel nous pouvons faire une bocle. Il existe déjà un objet **arguments** lié à chaque fonction, qui est un tableau contenant tous les paramètres passés à la fonction.\n\n```js\nfunction myFunc() {\n  for (var i = 0; i < arguments.length; i++) {\n    console.log(arguments[i]);\n  }\n}\n\nmyFunc(\"Nick\", \"Anderson\", 10, 12, 6);\n// \"Nick\"\n// \"Anderson\"\n// 10\n// 12\n// 6\n```\n\nMais imaginons que nous voulons que cette fonction créée un nouvel édudiant avec ses notes et sa note moyenne. Ne serait-il pas plus pratique d'extraire les deux premiers paramètres dans deux variables séparées, et d'avoir les notes dans un tableau sur lequel nous pourrions effectuer une boucle ?\n\nC'est exactement ce que l'opérateur de reste nous permet de faire !\n\n```js\nfunction createStudent(firstName, lastName, ...grades) {\n  // firstName = \"Nick\"\n  // lastName = \"Anderson\"\n  // [10, 12, 6] -- \"...\" prend tous les autres paramètres passés, créée une variable grades qui contient un tableau contenant les paramètres\n\n  const avgGrade = grades.reduce((acc, curr) => acc + curr, 0) / grades.length; // calculer la note moyenne à partir des notes\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// {\n//   firstName: \"Nick\",\n//   lastName: \"Anderson\",\n//   grades: [10, 12, 6],\n//   avgGrade: 9,33\n// }\n```\n\n> **Note :** la fonction createStudent est mauvaise car nous ne vérifions pas si grades.length existe ou est différent de 0. Cependant, je n'ai pas prévu ce cas pour rendre l'exemple plus facile à lire.\n\n##### Décomposition des propriétés d'un objet\n\nPour celui-ci, je vous recommande de lire les explications précédentes concernant l'opérateur de reste sur les itérables et les paramètres de fonction auparavant.\n\n```js\nconst myObj = { x: 1, y: 2, a: 3, b: 4 };\nconst { x, y, ...z } = myObj; // l'objet est déstructuré ici\nconsole.log(x); // 1\nconsole.log(y); // 2\nconsole.log(z); // { a: 3, b: 4 }\n\n// z est le reste de l'objet déstructuré : c'est myObj sans les propriétés x et y qui ont été déstructurées\n\nconst n = { x, y, ...z };\nconsole.log(n); // { x: 1, y: 2, a: 3, b: 4 }\n\n// Ici, les propriétés de l'objet z sont étendues dans n\n```\n\n#### Ressources externes\n\n- [TC39 - Object rest/spread](https://github.com/tc39/proposal-object-rest-spread)\n- [Spread operator introduction - WesBos](https://github.com/wesbos/es6-articles/blob/master/28%20-%20Spread%20Operator%20Introduction.md)\n- [JavaScript & the spread operator](https://codeburst.io/javascript-the-spread-operator-a867a71668ca)\n- [6 Great uses of the spread operator](https://davidwalsh.name/spread-operator)\n\n### Raccourci pour les propriétés d'objet\n\nLorsque l'on assigne une variable à la propriété d'un objet, si le nom de la variable est le même que le nom de la propriété, vous pouvez faire la chose suivante :\n\n```js\nconst x = 10;\nconst myObj = { x };\nconsole.log(myObj.x) // 10\n```\n\n#### Explication\n\nD'habitude (avant ES2015), lorsque l'on déclare un *litéral d'objet* et que l'on veut utiliser des variables comme propriétés de l'objet, on écrit ce genre de code :\n\n```js\nconst x = 10;\nconst y = 20;\n\nconst myObj = {\n  x: x, // on assigne le contenu de la variable x à myObj.x\n  y: y // on assigne le contenu de la variable y à myObj.y\n};\n\nconsole.log(myObj.x) // 10\nconsole.log(myObj.y) // 20\n```\n\nComme vous pouvez le voir, c'est assez répétitif car les noms des propriétés de myObj sont identiques aux noms des variables que vous voulez assigner à ces propriétés.\n\nAvec ES2015, quand le nom de la variable est identique au nom de la propriété, vous pouvez utiliser ce raccourci :\n\n```js\nconst x = 10;\nconst y = 20;\n\nconst myObj = {\n  x,\n  y\n};\n\nconsole.log(myObj.x) // 10\nconsole.log(myObj.y) // 20\n```\n\n#### Ressources externes\n\n- [Property shorthand - ES6 Features](http://es6-features.org/#PropertyShorthand)\n\n### Promesses\n\nUne promesse est un objet qui peut être retourné de manière synchrone depuis une fonction asynchrone ([ref](https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-promise-27fc71e77261#3cd0)).\n\nLes promesses peuvent être utilisées pour éviter un [enfer de callbacks](http://callbackhell.com/), et elles sont rencontrées de plus en plus fréquemment dans les projets JavaScript modernes.\n\n#### Code d'exemple\n\n```js\nconst fetchingPosts = new Promise((res, rej) => {\n  $.get(\"/posts\")\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#### Explication\n\nQuand vous faites une *requête AJAX*, la réponse n'est pas synchrone car vous voulez une ressource qui prend du temps à venir. Elle ne pourriat même jamais arriver si la ressource que vous avez demandée est indisponible pour une raison quelconque (404).\n\nPour gérer ce type de situations, ES2015 nous a offert les *promesses*. Les promesses peuvent avoir trois états différents :\n\n- En attente\n- Complété\n- Rejeté\n\nImagions que nous voulions utiliser les promesses pour gérer une requête AJAX pour récupérer la ressource *X*.\n\n##### Créer la promesse\n\nNous allons commencer par crééer une promesse. Nous allons utiliser la méthode ```$.get()``` de jQuery pour faire notre requête AJAX vers *X*.\n\n```js\nconst xFetcherPromise = new Promise( // Créer une promesse avec le mot-clé new et la stocker dans une variable\n  function(resolve, reject) { // Le constructeur de Promise prend une fonction comme paramètre qui a elle-même deux paramètres, resolve et reject\n    $.get(\"X\") // Démarrer la requête AJAX\n      .done(function(X) { // Quand la requête est terminée...\n        resolve(X); // ...résoudre la promesse avec la valeur X comme paramètre\n      })\n      .fail(function(error) { // Si la requête a échoué...\n        reject(error); // ...rejeter la promesse avec l'erreur comme paramètre\n      });\n  }\n)\n```\n\nComme vu dans l'exemple ci-dessus, l'objet Promise prend une fonction *exécuteur* qui prend les deux paramètres **resolve** et **reject**. Ces paramètres sont des fonctions qui lorsqu'elles sont appelées, vont modifier l'état de la promesse d'*en attente* à respectivement l'état *complété* et *résolu*.\n\nLa promesse est dans l'état *en attente* à sa création et sa fonction *éxécuteur* est appelée immédiatement. Quand une des deux fonctions *resolve* ou *reject* est appelée depuis la fonction *éxécuteur*, la promesse appelera les déclencheurs associés.\n\n##### Utilisation des déclencheurs de promesse\n\nPour obtenir le résultat (ou l'erreur) de la promesse, nous devons y attacher des déclencheurs en faisant la chose suivante :\n\n```js\nxFetcherPromise\n  .then(function(X) {\n    console.log(X);\n  })\n  .catch(function(err) {\n    console.log(err)\n  })\n```\n\nSi la promesse réussit, ```resolve()``` sera exécuté et la fonction passée à ```.then``` est appelée.\n\nSi elle échoue, ```reject()``` sera exécuté et la fonction passée à ```.catch``` est appelée.\n\n> **Note : ** Si la promesse a déjà été accomplie ou rejetée lorsqu'un déclencheur y est attaché, le déclencheur sera appelé, afin de ne pas avoir une course entre une opération asynchrone se complétant et ses déclencheurs s'y faisant attacher [(référence: MDN)](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Promise#Description).\n\n#### Ressources externes\n\n- [JavaScript Promises for dummies - Jecelyn Yeen](https://scotch.io/tutorials/javascript-promises-for-dummies)\n- [JavaScript Promise API - David Walsh](https://davidwalsh.name/promises)\n- [Utiliser les promesses - MDN](https://developer.mozilla.org/fr/docs/Web/JavaScript/Guide/Utiliser_les_promesses)\n- [What is a promise - Eric Elliott](https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-promise-27fc71e77261)\n- [JavaScript Promises: an Introduction - Jake Archibald](https://developers.google.com/web/fundamentals/getting-started/primers/promises)\n- [Documentation sur l'objet Promise - MDN](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Promise)\n\n### Littéraux de modèle\n\nLes littéraux de modèle (*template literals*) sont une [*interpolation d'expression*](https://en.wikipedia.org/wiki/String_interpolation) pour les chaînes de caractère d'une ligne ou multilignes.\n\nAutrement dit, c'est une nouvelle syntaxe de chaîne de caractère qui est particulièrement pratique pour y utiliser des expressions JavaScript (des variables, par exemple).\n\n#### Code d'exemple\n\n```js\nconst name = \"Nick\";\n`Bonjour ${name}, l'expression suivante vaut 4 : ${2+2}`;\n\n// Bonjour Nick, l'expression suivante vaut 4 : 4\n```\n\n#### Ressources externes\n\n- [String interpolation - ES6 Features](http://es6-features.org/#StringInterpolation)\n- [ES6 Template Strings - Addy Osmani](https://developers.google.com/web/updates/2015/01/ES6-Template-Strings)\n\n### Littéraux de modèle étiquetés\n\nLes étiquettes de modèle sont des *fonctions qui peuvent être préfixées à un [littéral de modèle](#litteraux-de-modele)*.  Quand une fonction est appelée ainsi, le premier paramètre est un tableau des *chaînes de caractère* qui apparaissent entre les variables interpolées du modèle, et les paramètres suivants sont les valeurs interpolées. Vous pouuvez utiliser l'opérateur de décomposition `...` pour les récupérer. [(Références: MDN)](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Litt%C3%A9raux_gabarits#Les_littéraux_de_modèle_étiquetés).\n\n> **Note :** Certaines librairies, comme [styled-components](https://www.styled-components.com/), se basent entièrement sur cette fonctionnalité.\n\nVoici un petit exemple de leur fonctionnement :\n```js\nfunction highlight(strings, ...values) {\n  const interpolation = strings.reduce((prev, current) => {\n    return prev + current + (values.length ? \"<mark>\" + values.shift() + \"</mark>\" : \"\");\n  }, \"\");\n\n  return interpolation;\n}\n\nconst condiment = \"confiture\";\nconst meal = \"toast\";\n\nhighlight`J'aime mettre de la ${condiment} sur mon ${meal}.`;\n// \"J'aime mettre de la <mark>confiture</mark> sur mon <mark>toast</mark>.\"\n```\n\nUn autre exemple plus intéressant :\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 = ['pommes', 'bananes', 'cerises'];\ncomma`J'aime grignoter des ${snacks}.`;\n// \"J'aime grignoter des pommes, bananes, cerises.\"\n```\n\n#### Ressources externes\n- [Wes Bos on Tagged Template Literals](http://wesbos.com/tagged-template-literals/)\n- [Library of common template tags](https://github.com/declandewet/common-tags)\n\n### Imports / exports\n\nLes modules ES6 sont utilisés pour accéder à des variables et à des fonctions explicitement exportées depuis les modules importés.\n\nJe vous recommande de regardes la documentation sur MDN concernant import/export (voir les ressources externes plus bas), elles sont à la fois simples et complètes.\n\n#### Explication avec un code d'exemple\n\n##### Exports nommés\n\nLes exports nommés sont utilisés pour exporter plusieurs valeurs d'un module.\n\n> **Note :** Vous ne pouvez exporter avec un nom que des [objets de première classe](https://fr.wikipedia.org/wiki/Objet_de_premi%C3%A8re_classe) qui ont un nom.\n\n```js\n// mathConstants.js\nexport const pi = 3.14;\nexport const exp = 2.7;\nexport const alpha = 0.35;\n\n// -------------\n\n// myFile.js\nimport { pi, exp } from './mathConstants.js'; // Import nommé -- syntaxe ressemblant à la destructuration\nconsole.log(pi) // 3.14\nconsole.log(exp) // 2.7\n\n// -------------\n\n// mySecondFile.js\nimport * as constants from './mathConstants.js'; // Injecter toutes les valeurs exportées dans la variable constants\nconsole.log(constants.pi) // 3.14\nconsole.log(constants.exp) // 2.7\n```\n\nBien que les imports nommés ressemblent à une *destructuration*, ils ont une syntaxe différente et ne sont pas identiques. Ils ne supportent ni les valeurs par défaut ni la destructuration *profonde*.\n\nDe plus, vous pouvez créer des alias mais la syntaxe est différente de celle utilisée avec la destructuration :\n\n```js\nimport { foo as bar } from 'myFile.js'; // foo est importé et injecté dans une nouvelle variable bar\n```\n\n##### Import/export par défaut\n\nConcernant l'export par défaut, il ne peut y en avoir qu'un seul par module. Un export par défaut peut être une fonction, une classe, un objet, ou quoi que ce soit d'autre. Cette valeur est considérée comme étant la valeur exportée \"principale\" car elle sera la plus simple à importer.\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. [Référence: MDN](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Instructions/export#Description)\n\n```js\n// coolNumber.js\nconst ultimateNumber = 42;\nexport default ultimateNumber;\n\n// ------------\n\n// myFile.js\nimport number from './coolNumber.js';\n// L'export par défaut, peu importe son nom, est automatiquement injecté dans la variable number\nconsole.log(number) // 42\n```\n\nExporter une fonction :\n\n```js\n// sum.js\nexport default function sum(x, y) {\n  return x + y;\n}\n// -------------\n\n// myFile.js\nimport sum from './sum.js';\nconst result = sum(1, 2);\nconsole.log(result) // 3\n```\n\n#### Ressources externes\n\n- [ES6 Modules in bulletpoints](https://ponyfoo.com/articles/es6#modules)\n- [Export - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export)\n- [Import - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import)\n- [Understanding ES6 Modules](https://www.sitepoint.com/understanding-es6-modules/)\n- [Destructuring special case - import statements](https://ponyfoo.com/articles/es6-destructuring-in-depth#special-case-import-statements)\n- [Misunderstanding ES6 Modules - Kent C. Dodds](https://medium.com/@kentcdodds/misunderstanding-es6-modules-upgrading-babel-tears-and-a-solution-ad2d5ab93ce0)\n- [Modules in JavaScript](http://exploringjs.com/es6/ch_modules.html#sec_modules-in-javascript)\n\n### <a name=\"this_def\"></a> *this* en JavaScript\n\nL'opérateur *this* se comporte différemment que dans d'autres langages et est dans la plupart des cas déterminé par la manière dont une fonction est appelée. ([Ref: MDN](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Op%C3%A9rateurs/L_op%C3%A9rateur_this)).\n\nCette notion a beaucoup de subtilités et comme elle est assez complexe, je vous recommande donc fortement de lire avec attention les ressources externes ci-dessous. Par conséquent, je vais utiliser l’idée personnelle que j’ai en tête pour déterminer ce qu’est *this*. J’ai appris cette astuce de [cet article écrit par Yehuda Katz](http://yehudakatz.com/2011/08/11/understanding-javascript-function-invocation-and-this/).\n\n```js\nfunction myFunc() {\n  ...\n}\n\n// Après chaque ligne, vous trouverez la valeur de *this* dans myFunc\n\nmyFunc.call(\"myString\", \"hello\") // \"myString\" -- la valeur du premier paramètre de .call est injectée dans *this*\n\n// En mode non-strict\nmyFunc(\"hello\") // window -- myFunc() est un sucre syntaxique pour myFunc.call(window, \"hello\")\n\n// En mode strict\nmyFunc(\"hello\") // undefined -- myFunc() est un sucre syntaxique pour myFunc.call(undefined, \"hello\")\n```\n\n```js\nvar person = {\n  myFunc: function() { ... }\n}\n\nperson.myFunc.call(person, \"test\") // objet person -- le premier paramètre de call est injecté dans *this*\nperson.myFunc(\"test\") // objet person -- person.myFunc() est un sucre syntaxique pour person.myFunc.call(person, \"test\")\n\nvar myBoundFunc = person.myFunc.bind(\"hello\") // Créée une nouvelle fonction dans laquelle nous injectons “hello” comme valeur de *this*\nperson.myFunc(\"test\") // objet Person -- La méthode bind n’a aucun effet sur la méthode originale\nmyBoundFunc(\"test\") // \"hello\" -- myBoundFunc est person.myFunc avec “hello” comme valeur de *this*\n```\n\n#### Ressources externes\n\n- [Understanding JavaScript Function Invocation and \"this\" - Yehuda Katz](http://yehudakatz.com/2011/08/11/understanding-javascript-function-invocation-and-this/)\n- [L’opérateur this - MDN](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Opérateurs/L_opérateur_this)\n\n### Classe\n\nJavaScript est un language [basé sur les prototypes](https://fr.wikipedia.org/wiki/Programmation_orientée_prototype) (alors que Java, par exemple, est [basé sur les classes]((https://en.wikipedia.org/wiki/Prototype-based_programming))). ES6 a introduit les classes JavaScript qui sont un sucre syntaxique pour de l’héritage et **non** un nouveau modèle d’héritage basé sur des classes \n\nJavaScript is a [prototype-based](https://en.wikipedia.org/wiki/Prototype-based_programming) language (whereas Java is [class-based](https://en.wikipedia.org/wiki/Class-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 ([référence : MDN](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Classes)).\n\nLe mot *classe* est évidemment source de confusion si vous êtes habitué aux classes dans d’autres langages. Dans ce cas, évitez de penser que les classes JavaScript fonctionnent de la même manière et considérez-les comme une notion totalement différente.\n\nComme ce document n’est pas fait pour vous apprendre le langage à partir de zéro, je vais partir du fait que vous savez déjà ce que sont les prototypes et comment ils se comportement. Dans le cas contraire, voyez les ressources externes listées en dessous des exemples.\n\n#### Exemples\n\nAvant ES6, la syntaxe de prototype :\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\nAvec la syntaxe ES6 de classe :\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'm \" + this.age;\n  }\n}\n\nconst myPerson = new Person(\"Manu\", 23);\nconsole.log(myPerson.age) // 23\nconsole.log(myPerson.stringSentence()) // \"Hello, my name is Manu and I'm 23\n```\n\n#### Ressources externes\n\nPour comprendre les prototypes :\n\n- [Understanding Prototypes in JS - Yehuda Katz](http://yehudakatz.com/2011/08/12/understanding-prototypes-in-javascript/)\n- [A plain English guide to JS prototypes - Sebastian Porto](http://sporto.github.io/blog/2013/02/22/a-plain-english-guide-to-javascript-prototypes/)\n- [Héritage et chaîne de prototypes - MDN](https://developer.mozilla.org/fr/docs/Web/JavaScript/Héritage_et_chaîne_de_prototypes)\n\nPour comprendre les classes\n\n- [ES6 Classes in Depth - Nicolas Bevacqua](https://ponyfoo.com/articles/es6-classes-in-depth)\n- [ES6 Features - Classes](http://es6-features.org/#ClassDefinition)\n- [Classes - MDN](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Classes)\n\n### Mots clés `extends` et `super`\n\nLe mot-clé `extends` est utilisé dans les déclarations de classe ou les expressions de classe pour créer une classe qui est une fille d’une autre classe ([référence: MDN](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Classes/extends)). La sous-classe hérite de toutes les propriétés de la classe supérieure et peut aussi ajouter de nouvelles propriétés ou modifier celles héritées.\n\nLe mot-clé `super` est utilisé pour appeler des fonctions sur le parent d’un objet, y compris son constructeur.\n\n- Le mot-clé `super` doit être utilisé avant que le mot-clé `this` soit utilisé dans le constructeur\n- Invoquer `super()` appelle le constructeur de la classe parente. Si vous voulez passer des arguments au constructeur de la classe parente, vous pouvez l’appeler avec `super(arguments)`.\n- Si la classe parente a une méthode (même statique) appelée `X`, vous pouvez utiliser `super.X()` pour l’appeler depuis la classe fille.\n\n#### Code d’exemple\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    // Ici, le constructeur de la classe parente est appelé avec\n    // les longueurs données pour la hauteur et largeur du Polygon\n    super(length, length);\n    // Note : dans les classes dérivées, super() doit être appelé avant que vous ne\n    // puissiez utiliser 'this'. Ne pas respecter cette règle causera une ReferenceError.\n    this.name = 'Square';\n    this.length = length;\n  }\n\n  getCustomHelloPhrase() {\n    const polygonPhrase = super.getHelloPhrase(); // accéder à une méthode de la classe parente avec la syntaxe super.X()\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) // 100\nconsole.log(mySquare.getHelloPhrase()) // 'Hi, I am a Square' -- Square hérite de Polygon et a accès à ses méthodes\nconsole.log(mySquare.getCustomHelloPhrase()) // 'Hi, I am a Square with a length of 10'\n```\n\n**Note :** Si nous avions essayé d’utiliser `this`avant d’appeler `super()` dans la classe Square, une ReferenceError aurait été déclenchée :\n\n```js\nclass Square extends Polygon {\n  constructor(length) {\n    this.height; // ReferenceError, super doit être appelé d’abord !\n\n    // Ici, le constructeur de la classe parente est appelé avec\n    // les longueurs données pour la hauteur et largeur du Polygon\n    super(length, length);\n    \n    // Note : dans les classes dérivées, super() doit être appelé avant que vous ne\n    // puissiez utiliser 'this'. Ne pas respecter cette règle causera une ReferenceError.\n    this.name = 'Square';\n  }\n}\n```\n\n#### Ressources\n\n- [extends - MDN](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Classes/extends)\n- [super - MDN](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Opérateurs/super)\n- [L’héritage au sein de JavaScript - MDN](https://developer.mozilla.org/fr/docs/Learn/JavaScript/Objects/Heritage)\n\n### Async Await\n\nEn plus des [Promises](#promesses), il y a une nouvelle syntaxe que vous pourriez rencontrer pour gérer le code asynchrone nommée *async / await*.\n\nLe but des fonctions async/await est de simplifier le comportement de l’utilisation des promesses de manière synchrone et d’exécuter un comportemnet sur un groupe de promesses. Tout comme les promesses sont similaires aux callbacks structurés, asnyc/await est similaire à la combinaison de générateurs et de promesses. Les fonctions asynchrones renvoient *toujours* une Promise. ([référence: MDN](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Instructions/async_function))\n\n> **Note :** Vous devez comprendre ce que sont les promesses et comment elles fonctionnent avant d’essayer de comprendre async/await car elles dépendent dessus.\n\n> **Note 2:** [*await* doit être utilisé dans une fonction *async*](https://hackernoon.com/6-reasons-why-javascripts-async-await-blows-promises-away-tutorial-c7ec10518dd9#f3f0), ce qui signifie que vous ne pouvez pas utiliser await dans le premier niveau de votre code car ce n’est pas une fonction async.\n\n#### Code d’exemple\n\n```js\nasync function getGithubUser(username) { // le mot-clé async autorise l’utilisation de await dans la fonction et signifie que la fonction retourne une promesse\n  const response = await fetch(`https://api.github.com/users/${username}`); // L’exécution est mise en pause ici jusqu’à ce que la Promise retournée par fetch soit résolue\n  return response.json();\n}\n\ngetGithubUser('mbeaudru')\n  .then(user => console.log(user)) // afficher dans la console la réponse - on ne peut pas utiliser la syntaxe await car ce code n’est pas une fonction async\n  .catch(err => console.log(err)); // si notre fonction async lève une erreur, nous la récupérons ici\n```\n\n#### Explication avec un code d’exemple\n\n*Async / Await* fonctionnent avec les promises mais ils permettent d’utiliser un style de code plus impératif.\n\nL’opérateur *async* marque une fonction comme étant asynchrone et retournera toujours une *Promise*. Vous pouvez utiliser l’opérateur *await* dans une fonction *async* pour mettre en pause l’exécution sur cette ligne jusqu’à ce que la promise retournée par l’expression se fasse résoudre ou rejeter.\n\n```js\nasync function myFunc() {\n  // nous pouvons utiliser l’opérateur await car cette fonction est asynchrone\n  return \"hello world\";\n}\n\nmyFunc().then(msg => console.log(msg)) // \"hello world\" -- la valeur de retour de myFunc se fait transformer en promesse à cause de l’opérateur async\n```\n\nLorsque l’expression *return* d’une fonction async est atteint, la Promise est remplie avec la valeur retournée. Si une erreur est levée à l’intérieur de la fonction async, la l’état de la promesse passera à *rejeté*. Si aucune valeur n’est retournée par une fonction async, une promesse est quand même retournée et sera résolue sans valeur lorsque l’exécution de la fonction async est terminée.\n\nL’opérateur *await* est utilisé pour attendre qu’une primesse se fasse résoudre et ne peut être utilisé qu’à l’intérieur du corps d’une fonction async. Lorsqu’il est rencontré, l’exécution du code est mise en pause jusqu’à ce que la promise se fasse résoudre.\n\n> **Note :** *fetch* est une fonction qui retourne une Promise qui nous permet de faire une requête AJAX\n\nVoyons d’abord comment nous pourrions récupérer un utilisateur sur GitHub avec des promesses.\n\n```js\nfunction getGithubUser(username) {\n  return fetch(`https://api.github.com/users/${username}`).then(response => response.json());\n}\n\ngetGithubUser('mbeaudru')\n  .then(user => console.log(user))\n  .catch(err => console.log(err));\n```\n\nVoici l’équivalent avec async/await\n\n```js\nasync function getGithubUser(username) { // utilisation d’une promesse + du mot-clé await autorisé\n  const response = await fetch(`https://api.github.com/users/${username}`); // L’exécution s’arrête ici jusqu’à ce que la promesse fetch soit résolue\n  return response.json();\n}\n\ngetGithubUser('mbeaudru')\n  .then(user => console.log(user))\n  .catch(err => console.log(err));\n```\n\nLa syntaxe *async/await* est particulièrement utile lorsque vous avez besoin d’enchaîner des promesses qui sont mutuellement dépendantes.\n\nPar exemple, si vous avez besoin d’obtenir un jeton d’accps pour pouvoir récupérer un post de blog sur une base de données puis les informations sur l’auteur :\n\n> **Note :** les expressions *await* ont besoin d’êtres entourées de parenthèses pour appeler leur valeur résolue et leurs propriétés sur la même ligne.\n\n```js\nasync function fetchPostById(postId) {\n  const token = (await fetch('token_url')).json().token;\n  const post = (await fetch(`/posts/${postId}?token=${token}`)).json();\n  const author = (await fetch(`/users/${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##### Gestion d’erreur\n\nÀ moins d’ajouter des blocs *try / catch* autour des expressions *await*, les exceptions non gérées – peu importe de si elles ont été levées dans le corps de votre fonction *async* ou lorsque le code est en pause pendant *await* – vont rejeter la promesse retournée par la fonction *async*. Utiliser l’expression `thrown` dans une fonction asynchrone donne le même résultat que retourner une promesse qui se fait rejeter [(référence : PonyFoo)](https://ponyfoo.com/articles/understanding-javascript-async-await#error-handling).\n\n> **Note :** Les promesses se comportent de la même manière !\n\nAvec les promesses, voici comment on gérerait la chaîne d’erreur :\n\n```js\nfunction getUser() { // Cette promesse se fera rejeter !\n  return new Promise((res, rej) => rej(\"Utilisateur non trouvé !\"));\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)); // \"Utilisateur non trouvé !\"\n```\n\nÉquivalent avec *async / await*:\n\n```js\nasync function getUser() { // La promesse retournée se fera rejeter\n  throw \"Utilisateur non trouvé !\";\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)); // \"Utilisateur non trouvé !\"\n```\n\n#### Ressources externes\n\n- [Async/Await - JavaScript.Info](https://javascript.info/async-await)\n- [ES7 Async/Await](http://rossboucher.com/await/#/)\n- [6 Reasons Why JavaScript’s Async/Await Blows Promises Away](https://hackernoon.com/6-reasons-why-javascripts-async-await-blows-promises-away-tutorial-c7ec10518dd9)\n- [JavaScript awaits](https://dev.to/kayis/javascript-awaits)\n- [Using Async Await in Express with Node 8](https://medium.com/@Abazhenov/using-async-await-in-express-with-node-8-b8af872c0016)\n- [Async Function](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Statements/async_function)\n- [Await](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Operators/await)\n- [Using async / await in express with node 8](https://medium.com/@Abazhenov/using-async-await-in-express-with-node-8-b8af872c0016)\n\n### Vérité / fausseté\n\nEn JavaScript, une valeur `truthy` ou `falsy` est une valeur qui se fait caster en un booléen lorsqu’elle est évaluée dans un contexte booléen. Un exemple de contexte booléen serait l’évaluation d’une condition ```if```.\n\nChaque valeur sera transformée en ```true```, à part si elles sont égales à :\n\n- ```false```\n- ```0```\n- ```\"\"``` (chaîne de caractères vide)\n- ```null```\n- ```undefined```\n- ```NaN```\n\nVoici des exemples de *contexte booléen* :\n\n- Évaluation de condition ```if```\n\n```js\nif (myVar) {}\n```\n\n```myVar``` peut être n’importe quel [objets de première classe](https://fr.wikipedia.org/wiki/Objet_de_premi%C3%A8re_classe) (variable, fonction, booléen) mais il sera transformé en booléen car il est évalué dans un contexte booléen.\n\n- Après l’opérateur logique **NOT** ```!```\n\nCet opérateur retourne ```false``` si son opérande peut être converti à ```true``` ; dans le cas contraire, il retourne ```true```\n\n```js\n!0 // true -- 0 est falsy, donc retourne true\n!!0 // false -- 0 est falsy, donc !0 retourne true, et donc !(!0) retourne false\n!!\"\" // false -- une chaîne vide est falsy donc NOT (NOT false) est égal à false\n```\n\n- Avec le constructeur d’objet *Boolean*\n\n```js\nnew Boolean(0) // false\nnew Boolean(1) // true\n```\n\n- Dans une expression ternaire\n\n```js\nmyVar ? \"truthy\" : \"falsy\"\n```\n\nmyVar se fait évaluer dans un contexte booléen.\n\n#### Ressources externes\n\n- [Truthy (MDN)](https://developer.mozilla.org/fr/docs/Glossary/Truthy)\n- [Falsy (MDN)](https://developer.mozilla.org/fr/docs/Glossary/Falsy)\n- [Truthy and Falsy values in JS - Josh Clanton](http://adripofjavascript.com/blog/drips/truthy-and-falsy-values-in-javascript.html)\n\n### Méthodes statiques\n\n#### Explication courte\n\nLe mot-clé `static` est utilisé dans les classes pour déclarer des méthodes statiques. Les méthodes statiques sont des fonctions dans une classe qui appartiennent à l’objet classe et ne sont pas disponible dans les instances de la classe.\n\n#### Code d’exemple\n\n```js\nclass Repo {\n  static getName() {\n    return \"Le nom du repo est modern-js-cheatsheet\"\n  }\n}\n\n// Notez que nous n’avons pas créé d’instance de la classe Repo\nconsole.log(Repo.getName()) // \"Le nom du repo est modern-js-cheatsheet\"\n\nlet r = new Repo();\nconsole.log(r.getName()) // Uncaught TypeError: repo.getName is not a function\n```\n\n#### Explication détaillée\n\nLes méthodes statiques peuvent être appelées à l’intérieur d’une autre méthode statique en utilisant le mot-clé `this`. Ceci ne fonctionne pas avec les méthodes non statiques, qui ne peuvent pas y accéder directement en utilisant le mot-clé `this`.\n\n##### Appeler d’autres méthodes statiques depuis une méthode statique\n\nPour appeler une méthode statique depuis une autre méthode statique, le mot-clé `this` peut être utilisé comme ceci :\n\n```js\nclass Repo {\n  static getName() {\n    return \"Le nom du repo est modern-js-cheatsheet\"\n  }\n\n  static modifyName(){\n    return this.getName() + '-ajout'\n  }\n}\n\nconsole.log(Repo.modifyName()) // Le nom du repo est modern-js-cheatsheet-ajout\n```\n\n##### Appeler des méthodes statiques depuis des méthodes non statiques\n\nLes méthodes non statiques peuvent appeler des méthodes statiques de deux façons :\n1. ###### En utilisant le nom de la classe\n\nPour accéder à une méthode statique depuis une méthode non statique, nous pouvons utiliser le nom de la classe et appeler la méthode statique comme une propriété, par exemple `NomClasse.NomMethodeStatique()`\n\n```js\nclass Repo {\n  static getName() {\n    return \"Le nom du repo est modern-js-cheatsheet\"\n  }\n\n  useName() {\n    return Repo.getName() + ' et il contient des trucs vraiment importants'\n  }\n}\n\n// Nous devons instancier la classe pour utiliser les méthodes non statiques\nlet r = new Repo()\nconsole.log(r.useName()) // Le nom du repo est modern-js-cheatsheet et il contient des trucs vraiment importants\n```\n\n2. ###### Avec le constructeur\n\nLes méthodes statiques peuvent être appelées en tant que propriétés sur l’objet constructor\n\n```js\nclass Repo {\n  static getName() {\n    return \"Repo name is modern-js-cheatsheet\"\n  }\n\n  useName() {\n    // Appelle la méthode statique comme une propriété du constructeur\n    return this.constructor.getName() + ' et il contient des trucs vraiment importants'\n  }\n}\n\n// Nous devons instancier la classe pour utiliser les méthodes non statiques\nlet r = new Repo()\nconsole.log(r.useName()) // Le nom du repo est modern-js-cheatsheet et il contient des trucs vraiment importants\n```\n\n#### Ressources externes\n- [static - MDN](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Classes/static)\n- [Static Methods - Javascript.info](https://javascript.info/class#static-methods)\n- [Static Members in ES6 - OdeToCode](http://odetocode.com/blogs/scott/archive/2015/02/02/static-members-in-es6.aspx)\n\n## Glossaire\n\n### <a name=\"scope_def\"></a> Portée (*scope*)\n\nLe contexte dans lequel les valeurs et expressions sont “visibles”, ou peuvent être référencées. Si une variable ou une autre expression n’est pas “dans la portée actuelle”, alors son utilisation ne sera pas possible.\n\nSource : [MDN](https://developer.mozilla.org/fr/docs/Glossaire/Portée)\n\n### <a name=\"mutation_def\"></a> Mutation de variable\n\nOn dit d’une variable qu’elle a été *mutée* lorsque sa valeur initiale a été changée après coup.\n\n```js\nvar myArray = [];\nmyArray.push(\"firstEl\") // myArray s’est fait muter\n```\n\nUne variable est dite *immutable* si elle ne peut être mutée.\n\nVous pouvez lire [l’article Mutable de MDN](https://developer.mozilla.org/fr/docs/Glossary/Mutable) pour plus de détails.\n"
  },
  {
    "path": "translations/ja-JP.md",
    "content": "# <a name=\"modern-javascript-cheatsheet\"></a> モダン JavaScript チートシート\n\n![モダン JavaScript チートシート](https://i.imgur.com/aexPxMb.png)\n<small>画像クレジット: [Ahmad Awais ⚡️](https://github.com/ahmadawais)</small>\n\n## <a name=\"introduction\"></a> イントロダクション\n\n### <a name=\"motivation\"></a> 動機\n\nこのドキュメントはモダンなプロジェクトでよく見られる JavaScript のチートシートと最新のサンプルコードです。\n\nこのガイドは読者に JavaScript をゼロから教えるものではありません。\n基礎知識は持っていて、モダンなコードベースに慣れる（例えば React を学ぶ）のに苦労している開発者を助けるためのものです。\n説明の中で JavaScript の諸概念が使われています。\n\nまた、議論の余地のあるポイントについてときどき個人的な tips を載せますが、その際はあくまでも個人的なおすすめであることを述べるように気をつけます。\n\n> **メモ:** ここで紹介されている概念のほとんどは JavaScript 言語のアップデート（ ES2015 、しばしば ES6 と呼ばれるもの）によるものです。そのアップデートで追加された新しい機能の説明は[こちらのページ](http://es6-features.org)で見つけることができます。このページはとてもわかりやすく書かれています。\n\n### <a name=\"complementary-resources\"></a> 補完的なリソース\n\n概念がうまく理解できない場合は、以下のリソースで答えを探すことをおすすめします:\n\n- [MDN (Mozilla Developer Network)](https://developer.mozilla.org/en-US/search?q=)\n- [You don't know JS (book)](https://github.com/getify/You-Dont-Know-JS)\n- [ES6 Features with examples](http://es6-features.org)\n- [WesBos blog (ES6)](http://wesbos.com/category/es6/)\n- [Javascript Basics for Beginners](https://www.udacity.com/course/javascript-basics--ud804) - Udacity の無料コース\n- [Reddit (JavaScript)](https://www.reddit.com/r/javascript/)\n- [Google](https://www.google.com/) （ブログとリソースを見つけるために）\n- [StackOverflow](https://stackoverflow.com/questions/tagged/javascript)\n\n## <a name=\"table-of-contents\"></a> 目次\n\n- [モダン JavaScript チートシート](#modern-javascript-cheatsheet)\n  * [イントロダクション](#introduction)\n    + [動機](#motivation)\n    + [補完的なリソース](#complementary-resources)\n  * [目次](#table-of-contents)\n  * [各種概念](#notions)\n    + [変数宣言: `var` / `const` / `let`](#variable-declaration-var-const-let)\n      - [短い説明](#short-explanation)\n      - [サンプルコード](#sample-code)\n      - [詳細な説明](#detailed-explanation)\n      - [外部のリソース](#external-resource)\n    + [アロー関数](#-arrow-function)\n      - [サンプルコード](#sample-code-1)\n      - [詳細な説明](#detailed-explanation-1)\n        * [簡潔さ](#concision)\n        * [*`this`* 参照](#this-reference)\n      - [有用なリソース](#useful-resources)\n    + [関数の引数のデフォルト値](#function-default-parameter-value)\n      - [外部のリソース](#external-resource-1)\n    + [オブジェクトや配列の分割](#destructuring-objects-and-arrays)\n      - [サンプルコード付きの説明](#explanation-with-sample-code)\n      - [有用なリソース](#useful-resources-1)\n    + [配列のメソッド - `map` / `filter` / `reduce`](#array-methods---map--filter--reduce)\n      - [サンプルコード](#sample-code-2)\n      - [説明](#explanation)\n        * [`Array.prototype.map()`](#arrayprototypemap)\n        * [`Array.prototype.filter()`](#arrayprototypefilter)\n        * [`Array.prototype.reduce()`](#arrayprototypereduce)\n      - [外部のリソース](#external-resource-2)\n    + [スプレッド演算子「 `...` 」](#spread-operator-)\n      - [サンプルコード](#sample-code-3)\n      - [説明](#explanation-1)\n        * [イテラブル（配列など）の中での使用](#in-iterables-like-arrays)\n        * [関数のレスト引数](#function-rest-parameter)\n        * [オブジェクトプロパティのスプレッディング](#object-properties-spreading)\n      - [外部のリソース](#external-resources)\n    + [オブジェクトプロパティの省略形](#object-property-shorthand)\n      - [説明](#explanation-2)\n      - [外部のリソース](#external-resources-1)\n    + [プロミス](#promises)\n      - [サンプルコード](#sample-code-4)\n      - [説明](#explanation-3)\n        * [プロミスの作成](#create-the-promise)\n        * [プロミスハンドラーの使用](#promise-handlers-usage)\n      - [外部のリソース](#external-resources-2)\n    + [テンプレートリテラル](#template-literals)\n      - [サンプルコード](#sample-code-5)\n      - [外部のリソース](#external-resources-3)\n    + [タグ付きテンプレートリテラル](#tagged-template-literals)\n      - [外部のリソース](#external-resources-4)\n    + [インポート / エクスポート](#imports--exports)\n      - [サンプルコード付きの説明](#explanation-with-sample-code-1)\n        * [名前付きエクスポート](#named-exports)\n        * [デフォルトインポート / エクスポート](#default-import--export)\n      - [外部のリソース](#external-resources-5)\n    + [JavaScript の *`this`*](#-javascript-this)\n      - [外部のリソース](#external-resources-6)\n    + [クラス](#class)\n      - [サンプルコード](#samples)\n      - [外部のリソース](#external-resources-7)\n    + [`extends` キーワードと `super` キーワード](#extends-and-super-keywords)\n      - [サンプルコード](#sample-code-6)\n      - [外部のリソース](#external-resources-8)\n    + [Async Await](#async-await)\n      - [サンプルコード](#sample-code-7)\n      - [サンプルコード付きの説明](#explanation-with-sample-code-2)\n      - [エラーハンドリング](#error-handling)\n      - [外部のリソース](#external-resources-9)\n    + [True になるもの / False になるもの](#truthy--falsy)\n      - [外部のリソース](#external-resources-10)\n    + [アナモルフィズム / カタモルフィズム](#anamorphisms-and-catamorphisms)\n      - [アナモルフィズム](#anamorphisms)\n      - [カタモルフィズム](#catamorphisms)\n      - [外部のリソース](#external-resources-11)\n    + [ジェネレーター](#generators)\n      - [外部のリソース](#external-resources-12)\n    + [スタティックメソッド](#static-methods)\n      - [短い説明](#short-explanation-1)\n      - [サンプルコード](#sample-code-8)\n      - [詳細な説明](#detailed-explanation-2)\n        * [スタティックメソッドから別のスタティックメソッドを呼ぶ](#calling-other-static-methods-from-a-static-method)\n        * [スタティックでないメソッドからスタティックメソッドを呼ぶ](#calling-static-methods-from-non-static-methods)\n      - [外部のリソース](#external-resources-13)\n  * [用語集](#glossary)\n    + [スコープ](#-scope)\n    + [変数ミューテーション](#-variable-mutation)\n\n## <a name=\"notions\"></a> 各種概念\n\n### <a name=\"variable-declaration-var-const-let\"></a> 変数宣言: `var` / `const` / `let`\n\nJavaScript には、変数の宣言に利用できるキーワードが 3 つあり、それぞれ違いがあります。\nその 3 つのキーワードとは、 ```var``` と ```let``` と ```const``` です。\n\n#### <a name=\"short-explanation\"></a> 短い説明\n\n```const``` キーワードで宣言された変数は再代入ができません。\n```let``` と ```var``` は再代入ができます。\n\n基本的に、変数はいつも ```const``` で宣言するようにして、変数を *変更* したり（訳注: 原文では「 mutate 」です）後から再代入したりする必要がある場合に ```let``` を使うことをおすすめします。\n\n<table>\n  <tr>\n    <th></th>\n    <th>スコープ</th>\n    <th>再代入可能</th>\n    <th>ミュータブル</th>\n   <th><a href=\"#tdz_sample\">テンポラルデッドゾーン</a></th>\n  </tr>\n  <tr>\n    <th>`const`</th>\n    <td>ブロック</td>\n    <td>×</td>\n    <td><a href=\"#const_mutable_sample\">○</a></td>\n    <td>○</td>\n  </tr>\n  <tr>\n    <th>`let`</th>\n    <td>ブロック</td>\n    <td>○</td>\n    <td>○</td>\n    <td>○</td>\n  </tr>\n   <tr>\n    <th>`var`</th>\n    <td>関数</td>\n    <td>○</td>\n    <td>○</td>\n    <td>×</td>\n  </tr>\n</table>\n\n#### <a name=\"sample-code\"></a> サンプルコード\n\n```javascript\nconst person = \"Nick\";\nperson = \"John\" // Will raise an error, person can't be reassigned\n```\n\n```javascript\nlet person = \"Nick\";\nperson = \"John\";\nconsole.log(person) // \"John\", reassignment is allowed with let\n```\n\n#### <a name=\"detailed-explanation\"></a> 詳細な説明\n\n変数の [*スコープ*](#scope_def) とは、ざっくり言うと、「コードの中でその変数が利用できる範囲」のことです。\n\n##### <a name=\"\"></a> `var`\n\n```var``` で宣言された変数のスコープは *関数スコープ* になります。\nこれは、ある変数が関数の中で作成されているとき、その関数の中のすべてのパーツがその変数にアクセスできることを意味します。\n加えて、ある関数の中で作成された *関数スコープ* の変数はその関数の外側ではアクセスすることができません。\n\n*X スコープ* 変数ということばの意味は、その変数が X のプロパティであるような感じでイメージすることをおすすめします。\n\n```javascript\nfunction myFunction() {\n  var myVar = \"Nick\";\n  console.log(myVar); // \"Nick\" - myVar is accessible inside the function\n}\nconsole.log(myVar); // Throws a ReferenceError, myVar is not accessible outside the function.\n```\n\n変数のスコープに引き続き着目し、もう少しわかりづらい例を見てみましょう:\n\n```javascript\nfunction myFunction() {\n  var myVar = \"Nick\";\n  if (true) {\n    var myVar = \"John\";\n    console.log(myVar); // \"John\"\n    // actually, myVar being function scoped, we just erased the previous myVar value \"Nick\" for \"John\"\n  }\n  console.log(myVar); // \"John\" - see how the instructions in the if block affected this value\n}\nconsole.log(myVar); // Throws a ReferenceError, myVar is not accessible outside the function.\n```\n\n加えて、 *`var`* で宣言された変数は実行時にスコープの一番上に移動されます。\nこの処理のことを [`var` ホイスティング](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var#var_hoisting) と呼びます。\n\n次のコードは\n\n```js\nconsole.log(myVar) // undefined -- no error raised\nvar myVar = 2;\n```\n\n実行時に次のように解釈されます。\n\n```js\nvar myVar;\nconsole.log(myVar) // undefined -- no error raised\nmyVar = 2;\n```\n\n##### <a name=\"\"></a> `let`\n\n```var``` と ```let``` は大体同じですが、 ```let``` で宣言された変数には次の特徴があります。\n\n- *ブロックスコープ* である\n- 代入の前にアクセスすることが *できない*\n- 同じスコープの中で再宣言できない\n\n上の例を使ってブロックスコープのインパクトを見てみましょう:\n\n```javascript\nfunction myFunction() {\n  let myVar = \"Nick\";\n  if (true) {\n    let myVar = \"John\";\n    console.log(myVar); // \"John\"\n    // actually, myVar being block scoped, we just created a new variable myVar.\n    // this variable is not accessible outside this block and totally independent\n    // from the first myVar created !\n  }\n  console.log(myVar); // \"Nick\", see how the instructions in the if block DID NOT affect this value\n}\nconsole.log(myVar); // Throws a ReferenceError, myVar is not accessible outside the function.\n```\n\n<a name=\"tdz_sample\"></a> ここで、 *`let`* （と *`const`* ）で宣言された変数に関して、代入前にアクセスできないというのは次のコードに示すとおりの意味です:\n\n```js\nconsole.log(myVar) // raises a ReferenceError !\nlet myVar = 2;\n```\n\n*`var`* とは対照的に、 *`let`* や *`const`* の変数では代入前に読み込みあるいは書き込みをしようとするとエラーが上がります。\nこの現象はしばしば [*テンポラルデッドゾーン*](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let#Temporal_Dead_Zone_and_errors_with_let) あるいは *TDZ* と呼ばれます。\n\n> **メモ:** 技術的には、 *`let`* と *`const`* の変数宣言もホイストされています。\nこれらは代入前に使用されないように作られているため、直感的にはホスティングが起こっていないように感じられますが、実際には起こっています。\n詳しく知りたい場合は[こちらの非常に詳しい説明](http://jsrocks.org/2015/01/temporal-dead-zone-tdz-demystified)をご覧ください。\n\n加えて、 *`let`* 変数は再宣言することができません:\n\n```js\nlet myVar = 2;\nlet myVar = 3; // Raises a SyntaxError\n```\n\n##### <a name=\"\"></a> `const`\n\n```const``` で宣言された変数は *`let`* 変数のように振る舞いますが、再代入ができません。\n\nまとめると、 *`const`* 変数には次の特徴があります:\n\n- *ブロックスコープ* である\n- 代入前にアクセスすることができない\n- 同じスコープの中で再宣言できない\n- 再代入できない\n\n```js\nconst myVar = \"Nick\";\nmyVar = \"John\" // raises an error, reassignment is not allowed\n```\n\n```js\nconst myVar = \"Nick\";\nconst myVar = \"John\" // raises an error, re-declaration is not allowed\n```\n\n<a name=\"const_mutable_sample\"></a> しかし、微妙なポイントがあります: ```const``` 変数は [**イミュータブル**](#mutation_def) ではありません！\n具体的に言うと、 ```const``` で宣言された *オブジェクト* と *配列* は変更することが **できます** 。\n\nオブジェクトの場合:\n\n```js\nconst person = {\n  name: 'Nick'\n};\nperson.name = 'John' // this will work ! person variable is not completely reassigned, but mutated\nconsole.log(person.name) // \"John\"\nperson = \"Sandra\" // raises an error, because reassignment is not allowed with const declared variables\n```\n\n配列の場合:\n\n```js\nconst person = [];\nperson.push('John'); // this will work ! person variable is not completely reassigned, but mutated\nconsole.log(person[0]) // \"John\"\nperson = [\"Nick\"] // raises an error, because reassignment is not allowed with const declared variables\n```\n\n#### <a name=\"external-resource\"></a> 外部のリソース\n\n- [How let and const are scoped in JavaScript - WesBos](http://wesbos.com/javascript-scoping/)\n- [Temporal Dead Zone (TDZ) Demystified](http://jsrocks.org/2015/01/temporal-dead-zone-tdz-demystified)\n\n### <a name=\"-arrow-function\"></a> <a name=\"arrow_func_concept\"></a> アロー関数\n\nES6 JavaScript のアップデートで *アロー関数* が導入されました。\nこれは、変数を宣言し利用するもうひとつの方法です。\nアロー関数がもたらすメリットは次のとおりです:\n\n- より簡潔である\n- *`this`* が周辺のスコープからピックアップされる\n- 暗黙的な `return`\n\n#### <a name=\"sample-code-1\"></a> サンプルコード\n\n- 簡潔さと暗黙的な `return`\n\n```js\nfunction double(x) { return x * 2; } // Traditional way\nconsole.log(double(2)) // 4\n```\n\n```js\nconst double = x => x * 2; // Same function written as an arrow function with implicit return\nconsole.log(double(2)) // 4\n```\n\n- *`this`* 参照\n\nアロー関数の中では、 *`this`* はその周りにある実行コンテキストの *`this`* と同じものになります。\nアロー関数を使えば、基本的に、関数の中で関数を呼び出す前に `that = this` とするトリックを使う必要がありません。\n\n```js\nfunction myFunc() {\n  this.myVar = 0;\n  setTimeout(() => {\n    this.myVar++;\n    console.log(this.myVar) // 1\n  }, 0);\n}\n```\n\n#### <a name=\"detailed-explanation-1\"></a> 詳細な説明\n\n##### <a name=\"concision\"></a> 簡潔さ\n\nアロー関数は、従来の関数よりも多くの点において簡潔です。\nすべての起こりうるケースを見てみましょう:\n\n- 暗黙的な `return`  vs. 明示的な `return`\n\n**明示的な `return`** は、 *`return`* キーワードがボディの中で使われている関数のことです。\n\n```js\n  function double(x) {\n    return x * 2; // this function explicitly returns x * 2, *return* keyword is used\n  }\n```\n\n関数を書く従来の方法では、 `return` は常に明示的に書く形になります。\nしかし、アロー関数では、 *暗黙的な `return`* を使うことができます。\nこれは、値を返すのに *`return`* キーワードを使う必要がないという意味です。\n\n```js\n  const double = (x) => {\n    return x * 2; // Explicit return here\n  }\n```\n\nこの関数は何かを返すだけのものなので（ *`return`* キーワードの前に他の処理が無いので）、暗黙的な `return` を使うことができます。\n\n```js\n  const double = (x) => x * 2; // Correct, returns x*2\n```\n\nこうするためには、 **かっこと `return` キーワードを削除** しさえすれば OK です。\nそのため、これは *暗黙的な* `return` と呼ばれています。\n*`return`* キーワードは書かれていませんが、この関数は実際には ```x * 2``` を返します。\n\n> **メモ:** もしある関数が値を返さなければ、それは暗黙的な `return` も明示的な `return` も行っていません。\n\n加えて、 *オブジェクト* を暗黙的に返したい場合は、ブロックのかっことの衝突を防ぐために **その周りにかっこを付ける必要があります**:\n\n```js\nconst getPerson = () => ({ name: \"Nick\", age: 24 })\nconsole.log(getPerson()) // { name: \"Nick\", age: 24 } -- object implicitly returned by arrow function\n```\n\n- 引数が 1 つだけの場合\n\n引数を 1 つだけ受け取る関数の場合は、引数の周りのかっこを省略することができます\n上の *`double`* のコードをもう一度取り上げましょう:\n\n```js\n  const double = (x) => x * 2; // this arrow function only takes one parameter\n```\n\n引数のかっこは省略できます:\n\n```js\n  const double = x => x * 2; // this arrow function only takes one parameter\n```\n\n- 引数が無い場合\n\nアロー関数が引数を取らない場合、かっこを付ける必要があります。\nかっこをつけないと正しいシンタックスではなくなります。\n\n```js\n  () => { // parentheses are provided, everything is fine\n    const x = 2;\n    return x;\n  }\n```\n\n```js\n  => { // No parentheses, this won't work!\n    const x = 2;\n    return x;\n  }\n```\n\n##### <a name=\"this-reference\"></a> *`this`* 参照\n\nアロー関数といっしょに導入されたこの微妙なポイントを理解するためには、 JavaScript における [`this`](#this_def) の振る舞いを知っておく必要があります。\n\nアロー関数では、 *`this`* はひとつ外側にある実行コンテキストの *`this`* の値に等しくなります。\nこれはつまり、アロー関数は新しい *`this`* を作成せず代わりに周囲の環境から *`this`* を取得します。\n\nアロー関数がなかった頃は、関数内の関数で *`this`* の値にアクセスしたい場合は、 *`that = this`* または *`self = this`* のトリックを使う必要がありました。\n\n例えば、 `setTimeout` 関数を `myFunc` の中で利用する場合は次のようにする必要がありました:\n\n```js\nfunction myFunc() {\n  this.myVar = 0;\n  var that = this; // that = this trick\n  setTimeout(\n    function() { // A new *this* is created in this function scope\n      that.myVar++;\n      console.log(that.myVar) // 1\n\n      console.log(this.myVar) // undefined -- see function declaration above\n    },\n    0\n  );\n}\n```\n\nアロー関数があれば、 *`this`* はその外部の環境から取得されます:\n\n```js\nfunction myFunc() {\n  this.myVar = 0;\n  setTimeout(\n    () => { // this taken from surrounding, meaning myFunc here\n      this.myVar++;\n      console.log(this.myVar) // 1\n    },\n    0\n  );\n}\n```\n\n#### <a name=\"useful-resources\"></a> 有用なリソース\n\n- [Arrow functions introduction - WesBos](http://wesbos.com/arrow-functions/)\n- [JavaScript arrow function - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions)\n- [Arrow function and lexical *this*](https://hackernoon.com/javascript-es6-arrow-functions-and-lexical-this-f2a3e2a5e8c4)\n\n### <a name=\"function-default-parameter-value\"></a> 関数の引数のデフォルト値\n\nES2015 の JavaScript アップデート以降、関数の引数のデフォルト値を次のシンタックスでセットできます:\n\n```js\nfunction myFunc(x = 10) {\n  return x;\n}\nconsole.log(myFunc()) // 10 -- no value is provided so x default value 10 is assigned to x in myFunc\nconsole.log(myFunc(5)) // 5 -- a value is provided so x is equal to 5 in myFunc\n\nconsole.log(myFunc(undefined)) // 10 -- undefined value is provided so default value is assigned to x\nconsole.log(myFunc(null)) // null -- a value (null) is provided, see below for more details\n```\n\nデフォルト引数は次の 2 つの状況でのみ適用されます:\n\n- 引数が渡されなかった\n- *`undefined`* 引数が渡された\n\n言い換えると、 *`null`* を渡した場合はデフォルト引数は **適用されません** 。\n\n> **メモ:** デフォルト値の代入は、分割引数（訳注: 原文では「 destructured parameters 」です）でも使用することができます（例は、次の概念をご覧ください）\n\n#### <a name=\"external-resource-1\"></a> 外部のリソース\n\n- [Default parameter value - ES6 Features](http://es6-features.org/#DefaultParameterValues)\n- [Default parameters - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters)\n\n### <a name=\"destructuring-objects-and-arrays\"></a> オブジェクトや配列の分割\n\n*分割* （訳注: 原文では「 destructuring 」です）はオブジェクトまたは配列に格納されたデータから値を抽出して新しい変数を作成する便利な方法です。\n\nいくつかユースケースをあげるなら、 *分割* は関数の引数を分割するために使用することもできますし、 React プロジェクトの *`this.props`* で使用することもできます。\n\n#### <a name=\"explanation-with-sample-code\"></a> サンプルコード付きの説明\n\n- オブジェクト\n\n以下すべてのサンプルに対して次のオブジェクトについて考えてみましょう:\n\n```js\nconst person = {\n  firstName: \"Nick\",\n  lastName: \"Anderson\",\n  age: 35,\n  sex: \"M\"\n}\n```\n\n分割がない場合、次のようになります。\n\n```js\nconst first = person.firstName;\nconst age = person.age;\nconst city = person.city || \"Paris\";\n```\n\n分割がある場合は、ワンラインで書くことができます:\n\n```js\nconst { firstName: first, age, city = \"Paris\" } = person; // That's it !\n\nconsole.log(age) // 35 -- A new variable age is created and is equal to person.age\nconsole.log(first) // \"Nick\" -- A new variable first is created and is equal to person.firstName\nconsole.log(firstName) // ReferenceError -- person.firstName exists BUT the new variable created is named first\nconsole.log(city) // \"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**メモ:** ```const { age } = person;``` において、 *`const`* キーワードの後のかっこは、オブジェクトやブロックの宣言として使用されるのではなく、 *分割* のシンタックスとなります。\n\n- 関数の引数\n\n*分割* は関数のオブジェクト引数を分割するためにしばしば使用されます。\n\n分割を使わない場合、次のようになります。\n\n```js\nfunction joinFirstLastName(person) {\n  const firstName = person.firstName;\n  const lastName = person.lastName;\n  return firstName + '-' + lastName;\n}\n\njoinFirstLastName(person); // \"Nick-Anderson\"\n```\n\nオブジェクト引数 *`person`* を分割すれば、より簡潔な関数を書くことができます:\n\n```js\nfunction joinFirstLastName({ firstName, lastName }) { // we create firstName and lastName variables by destructuring person parameter\n  return firstName + '-' + lastName;\n}\n\njoinFirstLastName(person); // \"Nick-Anderson\"\n```\n\n分割は[アロー関数](#arrow_func_concept)といっしょに使うとぐっといい感じになります:\n\n```js\nconst joinFirstLastName = ({ firstName, lastName }) => firstName + '-' + lastName;\n\njoinFirstLastName(person); // \"Nick-Anderson\"\n```\n\n- 配列\n\n次の配列について考えてみましょう:\n\n```js\nconst myArray = [\"a\", \"b\", \"c\"];\n```\n\n分割を使わない場合、次のようになります。\n\n```js\nconst x = myArray[0];\nconst y = myArray[1];\n```\n\n分割を使うと、次のように書けます。\n\n```js\nconst [x, y] = myArray; // That's it !\n\nconsole.log(x) // \"a\"\nconsole.log(y) // \"b\"\n```\n\n#### <a name=\"useful-resources-1\"></a> 有用なリソース\n\n- [ES6 Features - Destructuring Assignment](http://es6-features.org/#ArrayMatching)\n- [Destructuring Objects - WesBos](http://wesbos.com/destructuring-objects/)\n- [ExploringJS - Destructuring](http://exploringjs.com/es6/ch_destructuring.html)\n\n### <a name=\"array-methods---map--filter--reduce\"></a> 配列のメソッド - `map` / `filter` / `reduce`\n\n*`map`* 、 *`filter`* 、 *`reduce`* は [*関数プログラミング*](https://medium.com/javascript-scene/master-the-javascript-interview-what-is-functional-programming-7f218c68b3a0) という名前のプログラミングパラダイムに由来する配列のメソッドです。\n\nまとめ:\n\n- **Array.prototype.map()** 配列を受け取り、各要素に対して何かをして、変更された要素を持つ配列を返す。\n- **Array.prototype.filter()** 配列を受け取り、要素ごとに保持するかどうかを決めて、保持する要素のみからなる配列を返す。\n- **Array.prototype.reduce()** 配列を受け取り、要素を 1 つの値に集約する（その値が返される）。\n\nこれらは組み合わせ可能で、簡潔でエレガントなので、関数プログラミングは原則に則ってできるかぎりこれらを使用することをおすすめします。\n\nこれら 3 つのメソッドを使えば、ほとんどの状況で *`for`* ループと *`forEach`* ループを使用しなくてよくなります。\n*`for`* ループが使いたい場合は、 *`map`* と *`filter`* と *`reduce`* を組み合わせて処理を実現することを試みてください。\n新しい考え方を身につける必要があるので最初は苦労するかもしれませんが、一度馴れればものごとはよりかんたんになります。\n\n#### <a name=\"sample-code-2\"></a> サンプルコード\n\n```js\nconst numbers = [0, 1, 2, 3, 4, 5, 6];\nconst doubledNumbers = numbers.map(n => n * 2); // [0, 2, 4, 6, 8, 10, 12]\nconst evenNumbers = numbers.filter(n => n % 2 === 0); // [0, 2, 4, 6]\nconst sum = numbers.reduce((prev, next) => prev + next, 0); // 21\n```\n\n`map` 、 `filter` 、 `reduce` を使って、グレードが 10 以上の学生のグレードの合計値を計算してみます:\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) // we map the students array to an array of their grades\n  .filter(grade => grade >= 10) // we filter the grades array to keep those 10 or above\n  .reduce((prev, next) => prev + next, 0); // we sum all the grades 10 or above one by one\n\nconsole.log(aboveTenSum) // 44 -- 10 (Nick) + 15 (John) + 19 (Julia), Nathalie below 10 is ignored\n```\n\n#### <a name=\"explanation\"></a> 説明\n\n例として、数値からなる次の配列について考えてみましょう:\n\n```js\nconst numbers = [0, 1, 2, 3, 4, 5, 6];\n```\n\n##### <a name=\"arrayprototypemap\"></a> `Array.prototype.map()`\n\n```js\nconst doubledNumbers = numbers.map(function(n) {\n  return n * 2;\n});\nconsole.log(doubledNumbers); // [0, 2, 4, 6, 8, 10, 12]\n```\n\nここでは何が起こっているのでしょうか。\n`.map` を配列 *`numbers`* に対して使用しています。\n`map` は渡された関数を配列の各要素に適用します。\nこの関数のゴールは、 `map` が利用できるように、渡された値から新しい値を生成して返すことです。\n\nわかりやすくするために、今回は特別にこの関数を抽出しましょう:\n\n```js\nconst doubleN = function(n) { return n * 2; };\nconst doubledNumbers = numbers.map(doubleN);\nconsole.log(doubledNumbers); // [0, 2, 4, 6, 8, 10, 12]\n```\n\n```numbers.map(doubleN)``` は ```[doubleN(0), doubleN(1), doubleN(2), doubleN(3), doubleN(4), doubleN(5), doubleN(6)]``` を生成します。\nそしてこれは ```[0, 2, 4, 6, 8, 10, 12]``` になります。\n\n> **メモ:** 新しい配列を返すのではなく副作用のあるループを回したいだけの場合は、 `map` の代わりの `for` / `forEach` ループを使いたくなるかもしれません。\n\n##### <a name=\"arrayprototypefilter\"></a> `Array.prototype.filter()`\n\n```js\nconst evenNumbers = numbers.filter(function(n) {\n  return n % 2 === 0; // true if \"n\" is par, false if \"n\" isn't\n});\nconsole.log(evenNumbers); // [0, 2, 4, 6]\n```\n\n配列 *`numbers`* に対して `.filter()` を使用しています。\n`filter` は指定された関数に配列の各要素を渡します。\nこの関数のゴールは、現在の値を保持すべきかどうかを決める真偽値を返すことです。\n`filter` は保持すべき値のみを格納した配列を返します。\n\n##### <a name=\"arrayprototypereduce\"></a> `Array.prototype.reduce()`\n\n`reduce` メソッドのゴールは、配列のすべての要素を走査してひとつの値に *縮減* することです。\nどのように集約するかのロジックはあなた次第です。\n\n```js\nconst sum = numbers.reduce(\n  function(acc, n) {\n    return acc + n;\n  },\n  0 // accumulator variable value at first iteration step\n);\n\nconsole.log(sum) //21\n```\n\n`.map` メソッドと `.filter` メソッドのように、 `.reduce` は配列に対して適用されるもので、第 1 引数に関数を受け取ります。\n\nただしこの場合は違いがあります:\n\n- `.reduce` は 2 つの引数を受け取ります\n\n第 1 引数は、ループの各ステップで呼び出される関数です。\n\n第 2 引数は、ループの最初のステップにおける蓄積用の変数（訳注: 原文では「 accumulator variable 」です）の値です（これを理解するには次のポイントを読んでください）。\n\n- 関数引数\n\n`.reduce` の第 1 引数として渡す関数は、 2 つの引数を受け取ります。\n1 つめの引数（ここでは *`acc`* ）は、蓄積用の変数で、 2 つめの引数（ *`n`* ）は現在の要素です。\n\n蓄積用の変数は、 **ひとつ前の** ループのステップにおける関数の戻り値と等しいものです。\nループの最初のステップでは *`acc`* は `.reduce` の第 2 引数に渡された値に等しくなります。\n\n###### <a name=\"\"></a> ループの最初のステップ\n\n`reduce` の第 2 引数に `0` を渡しているので、 ```acc = 0``` となります。\n\n*`numbers`* 配列の最初の要素を取るので、 ```n = 0``` となります。\n\n関数は *`acc + n`* を返すので、これは `0 + 0` で `0` になります。\n\n###### <a name=\"\"></a> ループの第 2 ステップ\n\nひとつ前のループのステップで関数が返した値が使われるので、 ```acc = 0``` となります。\n\n*`numbers`* 配列の 2 番目の要素を取るので、 ```n = 1``` となります。\n\n関数は *`acc + n`* を返すので、これは `0 + 1` で `1` になります。\n\n###### <a name=\"\"></a> ループの第 3 ステップ\n\nひとつ前のループのステップで関数が返した値が使われるので、 ```acc = 1``` となります。\n\n*`numbers`* 配列の 2 番目の要素を取るので、 ```n = 2``` となります。\n\n関数は *`acc + n`* を返すので、これは `1 + 2` で `3` になります。\n\n###### <a name=\"\"></a> ループの第 4 ステップ\n\nひとつ前のループのステップで関数が返した値が使われるので、 ```acc = 3``` となります。\n\n*`numbers`* 配列の 2 番目の要素を取るので、 ```n = 3``` となります。\n\n関数は *`acc + n`* を返すので、これは `3 + 3` で `6` になります。\n\n###### <a name=\"\"></a> ループの最後のステップ\n\nひとつ前のループのステップで関数が返した値が使われるので、 ```acc = 15``` となります。\n\n*`numbers`* 配列の最後の要素を取るので、 ```n = 6``` となります。\n\n関数は *`acc + n`* を返すので、これは `15 + 6` で `21` になります。\n\nこれがループの最後のステップなので、 **`.reduce`** は `21` を返します。\n\n#### <a name=\"external-resource-2\"></a> 外部のリソース\n\n- [Understanding map / filter / reduce in JS](https://hackernoon.com/understanding-map-filter-and-reduce-in-javascript-5df1c7eee464)\n\n### <a name=\"spread-operator-\"></a> スプレッド演算子「 `...` 」\n\nスプレッド演算子（訳注: 原文では「 spread operator 」です）は ES2015 で導入されました。\nイテラブルなオブジェクト（訳注: 原文では「 iterable 」です）（配列など）の要素を、複数の要素が来るべきところに展開するために使用されます。\n\n#### <a name=\"sample-code-3\"></a> サンプルコード\n\n```js\nconst arr1 = [\"a\", \"b\", \"c\"];\nconst arr2 = [...arr1, \"d\", \"e\", \"f\"]; // [\"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// \"a\"\n// \"b\"\n// [\"c\", \"d\", \"e\", \"f\"]\n```\n\n```js\nconst { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };\nconsole.log(x); // 1\nconsole.log(y); // 2\nconsole.log(z); // { a: 3, b: 4 }\n\nconst n = { x, y, ...z };\nconsole.log(n); // { x: 1, y: 2, a: 3, b: 4 }\n```\n\n#### <a name=\"explanation-1\"></a> 説明\n\n##### <a name=\"in-iterables-like-arrays\"></a> イテラブル（配列など）の中での使用\n\n次の 2 つの配列があるものとします:\n\n```js\nconst arr1 = [\"a\", \"b\", \"c\"];\nconst arr2 = [arr1, \"d\", \"e\", \"f\"]; // [[\"a\", \"b\", \"c\"], \"d\", \"e\", \"f\"]\n```\n\n*`arr1`* がそのまま *`arr2`* にインジェクトされたので、 *`arr2`* の第 1 要素は配列です。\nしかし、実際は *`arr2`* をすべて文字からなる配列にしたいものとしましょう。\nそうしたい場合は、 *`arr1`* の要素を *スプレッド* して *`arr2`* に入れることができます。\n\nスプレッド演算子を使うと、次のように書けます。\n\n```js\nconst arr1 = [\"a\", \"b\", \"c\"];\nconst arr2 = [...arr1, \"d\", \"e\", \"f\"]; // [\"a\", \"b\", \"c\", \"d\", \"e\", \"f\"]\n```\n\n##### <a name=\"function-rest-parameter\"></a> 関数のレスト引数\n\n関数の引数において、レスト演算子（訳注: 原文では「 rest operator 」です）を使って引数をまとめて、ループ可能なひとつの配列に入れ込むことができます。\nすでに、関数に渡されたすべての引数を格納した配列に等しい **`arguments`** オブジェクトが関数にはバインドされています。\n\n```js\nfunction myFunc() {\n  for (var i = 0; i < arguments.length; i++) {\n    console.log(arguments[i]);\n  }\n}\n\nmyFunc(\"Nick\", \"Anderson\", 10, 12, 6);\n// \"Nick\"\n// \"Anderson\"\n// 10\n// 12\n// 6\n```\n\nしかし、仮に、この関数に、グレードと平均グレードを持つ新しい学生のオブジェクトを作成させたい場合を考えましょう。\n最初の 2 つの引数を個別の 2 つの変数に抽出しておいて、すべてのグレードを格納したループ可能な配列が取得できるなら、便利ですよね。\n\nまさにこれがレスト演算子でできることなのです！\n\n```js\nfunction createStudent(firstName, lastName, ...grades) {\n  // firstName = \"Nick\"\n  // lastName = \"Anderson\"\n  // [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) / grades.length; // 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// {\n//   firstName: \"Nick\",\n//   lastName: \"Anderson\",\n//   grades: [10, 12, 6],\n//   avgGrade: 9,33\n// }\n```\n\n> **メモ:** `grades.length` が存在するかどうか、あるいは `0` と異なるかどうかをチェックしていないので、 `createStudent` 関数はよくありません。\nしかし、この形だと読みやすいので、そのケースは処理していません。\n\n##### <a name=\"object-properties-spreading\"></a> オブジェクトプロパティのスプレッディング\n\nここを読む場合は、イテラブルオブジェクトに対するレスト演算子と関数の引数に関するひとつ前の説明を先に読むことをおすすめします。\n\n```js\nconst myObj = { x: 1, y: 2, a: 3, b: 4 };\nconst { x, y, ...z } = myObj; // object destructuring here\nconsole.log(x); // 1\nconsole.log(y); // 2\nconsole.log(z); // { a: 3, b: 4 }\n\n// 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); // { x: 1, y: 2, a: 3, b: 4 }\n\n// Here z object properties are spread into n\n```\n\n#### <a name=\"external-resources\"></a> 外部のリソース\n\n- [TC39 - Object rest/spread](https://github.com/tc39/proposal-object-rest-spread)\n- [Spread operator introduction - WesBos](https://github.com/wesbos/es6-articles/blob/master/28%20-%20Spread%20Operator%20Introduction.md)\n- [JavaScript & the spread operator](https://codeburst.io/javascript-the-spread-operator-a867a71668ca)\n- [6 Great uses of the spread operator](https://davidwalsh.name/spread-operator)\n\n### <a name=\"object-property-shorthand\"></a> オブジェクトプロパティの省略形\n\n変数をオブジェクトのプロパティに代入するとき、変数名がプロパティ名と同じ場合は、次の形で書くことができます:\n\n```js\nconst x = 10;\nconst myObj = { x };\nconsole.log(myObj.x) // 10\n```\n\n#### <a name=\"explanation-2\"></a> 説明\n\n新しい *オブジェクトリテラル* を宣言して、プロパティの値として変数を使用したい場合は、（ ES2015 以前は）たいてい次のようなコードを書いたことでしょう:\n\n```js\nconst x = 10;\nconst y = 20;\n\nconst myObj = {\n  x: x, // assigning x variable value to myObj.x\n  y: y // assigning y variable value to myObj.y\n};\n\nconsole.log(myObj.x) // 10\nconsole.log(myObj.y) // 20\n```\n\nご覧のとおり、 `myObj` のプロパティ名はそこに値を割り当てたい変数の名前と同じなので、非常にくどい感じになります。\n\nES2015 では、変数名がプロパティ名と同じ場合は、次の省略形を使うことができます:\n\n```js\nconst x = 10;\nconst y = 20;\n\nconst myObj = {\n  x,\n  y\n};\n\nconsole.log(myObj.x) // 10\nconsole.log(myObj.y) // 20\n```\n\n#### <a name=\"external-resources-1\"></a> 外部のリソース\n\n- [Property shorthand - ES6 Features](http://es6-features.org/#PropertyShorthand)\n\n### <a name=\"promises\"></a> プロミス\n\nプロミスとは、非同期的な関数（訳注: 原文では「 asynchronous function 」です）から同期的に（訳注: 原文では「 synchronously 」です）返すことができるオブジェクトです（[参考](https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-promise-27fc71e77261#3cd0))）。\n\nプロミスは[コールバック地獄](http://callbackhell.com/)（訳注: 原文では「 callback hell 」です）を避けるために使用することができます。\nモダンな JavaScript プロジェクトで出会うますます頻繁に使われるようになっています。\n\n#### <a name=\"sample-code-4\"></a> サンプルコード\n\n```js\nconst fetchingPosts = new Promise((res, rej) => {\n  $.get(\"/posts\")\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#### <a name=\"explanation-3\"></a> 説明\n\n*Ajax リクエスト* を行う場合は、時間のかかるリソースが求められることもあるので、レスポンスは同期的ではありません。\nリクエストされたリソースが何らかの理由で利用不可の場合（ 404 の場合）、レスポンスが戻ってこないこともあります。\n\nこのような状況を扱うために、 ES2015 は *プロミス* を提供しました。\nプロミスは異なる 3 つの状態を持つことができます:\n\n- ペンディング（訳注: 原文では「 Pending 」です）\n- フルフィルド（訳注: 原文では「 Fulfilled 」です）\n- リジェクテッド（訳注: 原文では「 Rejected 」です）\n\nプロミスを使って、リソース X をフェッチするために Ajax リクエストを扱う場合を考えてみましょう。\n\n##### <a name=\"create-the-promise\"></a> プロミスの作成\n\n最初にプロミスを作成します。\nX への Ajax リクエストを行うために jQuery の `get` メソッドを使います。\n\n```js\nconst xFetcherPromise = new Promise( // Create promise using \"new\" keyword and store it into a variable\n  function(resolve, reject) { // Promise constructor takes a function parameter which has resolve and reject parameters itself\n    $.get(\"X\") // Launch the Ajax request\n      .done(function(X) { // Once the request is done...\n        resolve(X); // ... resolve the promise with the X value as parameter\n      })\n      .fail(function(error) { // If the request has failed...\n        reject(error); // ... reject the promise with the error as parameter\n      });\n  }\n)\n```\n\n上の例のとおり、プロミスオブジェクトは、 2 つの引数 **`resolve`** と **`reject`** を受け取る *エクセキューター* 関数（訳注: 原文では「 executor function 」です）を受け取ります。\nこれらの引数は、プロミスの *ペンディング* ステートを *フルフィルド* ステートと *リジェクテッド* ステートのそれぞれに移行させるときに呼び出されます。\n\nプロミスはインスタンスが作成された後はペンディングステートになっており、 *エクセキューター* 関数が即座に実行されます。\n*エクセキューター* 関数の中で *`resolve`* か *`reject`* の一方が呼び出されたら、プロミスは関連づけられたハンドラーを呼び出します。\n\n##### <a name=\"promise-handlers-usage\"></a> プロミスハンドラーの使用\n\nプロミスの結果（もしくはエラー）を取得するには、次のようにしてハンドラーをアタッチする必要があります:\n\n```js\nxFetcherPromise\n  .then(function(X) {\n    console.log(X);\n  })\n  .catch(function(err) {\n    console.log(err)\n  })\n```\n\nプロミスが成功すれば、 *`resolve`* が実行され ```.then``` の引数として渡された関数が実行されます。\n\nプロミスが失敗すれば、 *`reject`* が実行され、 ```.catch``` の引数として渡された関数が実行されます。\n\n> **メモ:** もし、対応するハンドラーがアタッチされたときにプロミスがすでにフルフィルドやリジェクテッドの状態になっていれば、そのハンドラーは呼び出されます。非同期の操作の完了とアタッチされるハンドラの間で競合状態は発生しません。（[参考: MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise#Description)）\n\n#### <a name=\"external-resources-2\"></a> 外部のリソース\n\n- [JavaScript Promises for dummies - Jecelyn Yeen](https://scotch.io/tutorials/javascript-promises-for-dummies)\n- [JavaScript Promise API - David Walsh](https://davidwalsh.name/promises)\n- [Using promises - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises)\n- [What is a promise - Eric Elliott](https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-promise-27fc71e77261)\n- [JavaScript Promises: an Introduction - Jake Archibald](https://developers.google.com/web/fundamentals/getting-started/primers/promises)\n- [Promise documentation - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)\n\n### <a name=\"template-literals\"></a> テンプレートリテラル\n\nテンプレートリテラルとは、単一行・複数行の文字列に対する [*式補完*](https://en.wikipedia.org/wiki/String_interpolation) （訳注: 原文は「 expression interpolation 」です）です。\n\n言い換えると、テンプレートリテラルは、 JavaScript の式（例えば変数）をその中で使える新しい文字列シンタックスです。\n\n#### <a name=\"sample-code-5\"></a> サンプルコード\n\n```js\nconst name = \"Nick\";\n`Hello ${name}, the following expression is equal to four : ${2+2}`;\n\n// Hello Nick, the following expression is equal to four: 4\n```\n\n#### <a name=\"external-resources-3\"></a> 外部のリソース\n\n- [String interpolation - ES6 Features](http://es6-features.org/#StringInterpolation)\n- [ES6 Template Strings - Addy Osmani](https://developers.google.com/web/updates/2015/01/ES6-Template-Strings)\n\n### <a name=\"tagged-template-literals\"></a> タグ付きテンプレートリテラル\n\nテンプレートタグは *[テンプレートリテラル](#template-literals)にプリフィックスされる関数* です。\n関数がこの形で呼び出されたとき、第 1 引数はテンプレートの補完を行う変数と変数の間に現れる *文字列* からなる配列で、その後の引数は補完に使われる値です。\nこれをすべて捉えるにはスプレッド演算子を使用します。\n（[参考: MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#Tagged_template_literals)）\n\n> **メモ:** [styled-components](https://www.styled-components.com/) という有名なライブラリはこの機能を多用しています。\n\n次のコードは、タグ付きテンプレートリテラルがどのように動作するかを示す遊びのサンプルです。\n\n```js\nfunction highlight(strings, ...values) {\n  const interpolation = strings.reduce((prev, current) => {\n    return prev + current + (values.length ? \"<mark>\" + values.shift() + \"</mark>\" : \"\");\n  }, \"\");\n\n  return interpolation;\n}\n\nconst condiment = \"jam\";\nconst meal = \"toast\";\n\nhighlight`I like ${condiment} on ${meal}.`;\n// \"I like <mark>jam</mark> on <mark>toast</mark>.\"\n```\n\n次はもっとおもしろいサンプルです:\n\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// \"I like apples, bananas, cherries to snack on.\"\n```\n\n#### <a name=\"external-resources-4\"></a> 外部のリソース\n\n- [Wes Bos on Tagged Template Literals](http://wesbos.com/tagged-template-literals/)\n- [Library of common template tags](https://github.com/declandewet/common-tags)\n\n### <a name=\"imports--exports\"></a> インポート / エクスポート\n\nES6 モジュールは、他のモジュールが明示的にエクスポートした変数や関数にモジュールがアクセスするために使用するための方法です。\n\nインポート / エクスポートに関する MDN のリソース（下の外部のリソースのところをご覧ください）を見ることを強くおすすめします。\nそのリソースはわかりやすいと同時に、ポイントが網羅されています。\n\n#### <a name=\"explanation-with-sample-code-1\"></a> サンプルコード付きの説明\n\n##### <a name=\"named-exports\"></a> 名前付きエクスポート\n\n名前付きエクスポート（訳注: 原文では「 named exports 」です）は、モジュールから複数の値をエクスポートするための方法です。\n\n> **メモ:** 名前付きエクスポートは、名前の付いた[第一級オブジェクト](https://en.wikipedia.org/wiki/First-class_citizen)に対してのみ可能です。\n\n```js\n// mathConstants.js\nexport const pi = 3.14;\nexport const exp = 2.7;\nexport const alpha = 0.35;\n\n// -------------\n\n// myFile.js\nimport { pi, exp } from './mathConstants.js'; // Named import -- destructuring-like syntax\nconsole.log(pi) // 3.14\nconsole.log(exp) // 2.7\n\n// -------------\n\n// mySecondFile.js\nimport * as constants from './mathConstants.js'; // Inject all exported values into constants variable\nconsole.log(constants.pi) // 3.14\nconsole.log(constants.exp) // 2.7\n```\n\n名前付きインポートは *分割* に似ていますが、シンタックスが異なり、分割と同じものではありません。\n名前付きインポートは、デフォルト値や *深い* （訳注: 原文では「 deep 」です）分割をサポートしていません。\n\n加えて、エイリアスを使うことができますが、そのシンタックスは分割のものとは異なります:\n\n```js\nimport { foo as bar } from 'myFile.js'; // foo is imported and injected into a new bar variable\n```\n\n##### <a name=\"default-import--export\"></a> デフォルトインポート / エクスポート\n\nデフォルトエクスポートに関しては、モジュールごとにひとつだけデフォルトエクスポートがあります。\nデフォルトエクスポートは、関数、クラス、オブジェクトその他どんなものにもすることができます。\nデフォルトエクスポートはインポートするときの最もシンプルな形なので、その値は「メイン」のエクスポート値とみなされます。\n（[参考: MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export#Description)）\n\n```js\n// coolNumber.js\nconst ultimateNumber = 42;\nexport default ultimateNumber;\n\n// ------------\n\n// myFile.js\nimport number from './coolNumber.js';\n// Default export, independently from its name, is automatically injected into number variable;\nconsole.log(number) // 42\n```\n\n関数のエクスポート:\n\n```js\n// sum.js\nexport default function sum(x, y) {\n  return x + y;\n}\n// -------------\n\n// myFile.js\nimport sum from './sum.js';\nconst result = sum(1, 2);\nconsole.log(result) // 3\n```\n\n#### <a name=\"external-resources-5\"></a> 外部のリソース\n\n- [ES6 Modules in bulletpoints](https://ponyfoo.com/articles/es6#modules)\n- [Export - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export)\n- [Import - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import)\n- [Understanding ES6 Modules](https://www.sitepoint.com/understanding-es6-modules/)\n- [Destructuring special case - import statements](https://ponyfoo.com/articles/es6-destructuring-in-depth#special-case-import-statements)\n- [Misunderstanding ES6 Modules - Kent C. Dodds](https://medium.com/@kentcdodds/misunderstanding-es6-modules-upgrading-babel-tears-and-a-solution-ad2d5ab93ce0)\n- [Modules in JavaScript](http://exploringjs.com/es6/ch_modules.html#sec_modules-in-javascript)\n\n### <a name=\"-javascript-this\"></a> <a name=\"this_def\"></a>  JavaScript の *`this`*\n\n*`this`* 演算子の振る舞いは他の言語とは異なり、ほとんどの場合、関数の呼び出し方によって決まります。\n（[参考: MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this)）\n\nこの概念にはややこしいポイントがたくさんあり非常に難しいので、以下にあげる外部のリソースを深く読むことを強くおすすめします。\nそのため、ここでは *`this`* の中身が何になるかを理解するための個人的なアイデアを紹介することにします。\nこの考え方は [Yehuda Katz が書いた記事](http://yehudakatz.com/2011/08/11/understanding-javascript-function-invocation-and-this/) からのものです。\n\n```js\nfunction myFunc() {\n  ...\n}\n\n// After each statement, you find the value of *this* in myFunc\n\nmyFunc.call(\"myString\", \"hello\") // \"myString\" -- first .call parameter value is injected into *this*\n\n// In non-strict-mode\nmyFunc(\"hello\") // window -- myFunc() is syntax sugar for myFunc.call(window, \"hello\")\n\n// In strict-mode\nmyFunc(\"hello\") // 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\") // person Object -- first call parameter is injected into *this*\nperson.myFunc(\"test\") // person Object -- person.myFunc() is syntax sugar for person.myFunc.call(person, \"test\")\n\nvar myBoundFunc = person.myFunc.bind(\"hello\") // Creates a new function in which we inject \"hello\" in *this* value\nperson.myFunc(\"test\") // person Object -- The bind method has no effect on the original method\nmyBoundFunc(\"test\") // \"hello\" -- myBoundFunc is person.myFunc with \"hello\" bound to *this*\n```\n\n#### <a name=\"external-resources-6\"></a> 外部のリソース\n\n- [Understanding JavaScript Function Invocation and \"this\" - Yehuda Katz](http://yehudakatz.com/2011/08/11/understanding-javascript-function-invocation-and-this/)\n- [JavaScript this - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this)\n\n### <a name=\"class\"></a> クラス\n\nJavaScript は [プロトタイプベース](https://en.wikipedia.org/wiki/Prototype-based_programming) の言語です（例えば、 Java は [クラスベース](https://en.wikipedia.org/wiki/Class-based_programming) の言語です）。\nES6 は、プロトタイプベースの継承に対するシンタックスシュガー（訳注: 原文では「 syntactic sugar 」です）としての JavaScript のクラスを導入しました。\nこれは新しいクラスベースの継承モデルでは **ありません** 。\n\nもしあなたが他の言語のクラスに馴れていれば、 *クラス* ということばは混乱を招く可能性があります。\nもし他の言語のクラスに馴れているなら、 JavaScript のクラスも同じようなものだと考えたりはせず、まったく別物の概念だと考えましょう。\n\nこのドキュメントは JavaScript についてゼロから教えようとするものではないため、読者は、プロトタイプが何であって、どのように振る舞うかを知っているものとします。\nもしプロトタイプについてよく知らなければ、次のサンプルコードの下に記載された外部のリソースをご覧ください。\n\n#### <a name=\"samples\"></a> サンプルコード\n\nES6 以前のプロトタイプ構文:\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\nES6 のクラス構文:\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'm \" + this.age;\n  }\n}\n\nconst myPerson = new Person(\"Manu\", 23);\nconsole.log(myPerson.age) // 23\nconsole.log(myPerson.stringSentence()) // \"Hello, my name is Manu and I'm 23\n```\n\n#### <a name=\"external-resources-7\"></a> 外部のリソース\n\nプロトタイプの理解のためのリソース:\n\n- [Understanding Prototypes in JS - Yehuda Katz](http://yehudakatz.com/2011/08/12/understanding-prototypes-in-javascript/)\n- [A plain English guide to JS prototypes - Sebastian Porto](http://sporto.github.io/blog/2013/02/22/a-plain-english-guide-to-javascript-prototypes/)\n- [Inheritance and the prototype chain - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain)\n\nクラスの理解のためのリソース:\n\n- [ES6 Classes in Depth - Nicolas Bevacqua](https://ponyfoo.com/articles/es6-classes-in-depth)\n- [ES6 Features - Classes](http://es6-features.org/#ClassDefinition)\n- [JavaScript Classes - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes)\n\n### <a name=\"extends-and-super-keywords\"></a> `extends` キーワードと `super` キーワード\n\n`extends` キーワードは、他のクラスの子どもとなるクラスを作成するために、クラス宣言あるいはクラス式に使われます（[参考: MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/extends)）。\nサブクラスはスーパークラスのすべてのプロパティを継承し、追加で新しいプロパティを追加したり継承したプロパティを変更したりすることができます。\n\n`super` キーワードはオブジェクトの親の関数を呼び出すために使用します。\nこれにはコンストラクターも含まれます。\n\n- コンストラクターの中では、 `super` キーワードは `this` キーワードが使われる前に使わなくてはなりません。\n- `super()` を呼び出すと親クラスのコンストラクターが呼ばれます。クラスのコンストラクターに引数を渡したいときは、 `super(arguments)` という形で呼び出します。\n- 親クラスが `X` というメソッドを持つ場合は（スタティックメソッドでもよい）、子クラスの中で `super.X()` とすればそれを呼び出すことができます。\n\n#### <a name=\"sample-code-6\"></a> サンプルコード\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    // Here, it calls the parent class' constructor with lengths\n    // provided for the Polygon's width and height\n    super(length, length);\n    // Note: In derived classes, super() must be called before you\n    // 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(); // 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) // 100\nconsole.log(mySquare.getHelloPhrase()) // 'Hi, I am a Square' -- Square inherits from Polygon and has access to its methods\nconsole.log(mySquare.getCustomHelloPhrase()) // 'Hi, I am a Square with a length of 10'\n```\n\n**メモ:** `Square` クラスの中で `super()` を呼ぶ前に `this` を使おうとすると、 `ReferenceError` が発生します:\n\n```js\nclass Square extends Polygon {\n  constructor(length) {\n    this.height; // ReferenceError, super needs to be called first!\n\n    // Here, it calls the parent class' constructor with lengths\n    // provided for the Polygon's width and height\n    super(length, length);\n\n    // Note: In derived classes, super() must be called before you\n    // can use 'this'. Leaving this out will cause a reference error.\n    this.name = 'Square';\n  }\n}\n```\n\n#### <a name=\"external-resources-8\"></a> 外部のリソース\n\n- [Extends - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/extends)\n- [Super operator - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/super)\n- [Inheritance - MDN](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Inheritance)\n\n### <a name=\"async-await\"></a> Async Await\n\n[プロミス](#promises) に加えて、 *`async`* / *`await`* という非同期なコードを扱うための新しい構文を見ることがあるかもしれません。\n\n`async` / `await` 関数の目的は、プロミスを同期的に利用する振る舞いをシンプルにすることです。\nそして、プロミスのグループを扱うことです。\nプロミスが構造化されたコールバックに似ているのと同じように、 `async` / `await` もジェネレーターとプロミスの組み合わせに似ています。\n`async` 関数は *常に* プロミスを返します。\n（[参考: MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)）\n\n> **メモ:** `async` / `await` はプロミスをベースにしているため、 `async` / `await` を理解しようとする前に、プロミスがどんなもので、どのように動作するのかを理解する必要があります。\n\n> **メモ 2:** [*`await`* は *`async`* 関数の中で使わなくてはなりません](https://hackernoon.com/6-reasons-why-javascripts-async-await-blows-promises-away-tutorial-c7ec10518dd9#f3f0) 。これは、 `await` はコードのトップレベルでは使えない（コードのトップレベルは `async` 関数の中に入っていないので）、という意味です。\n\n#### <a name=\"sample-code-7\"></a> サンプルコード\n\n```js\nasync function getGithubUser(username) { // async keyword allows usage of await in the function and means function returns a promise\n  const response = await fetch(`https://api.github.com/users/${username}`); // 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)) // logging user response - cannot use await syntax since this code isn't in async function\n  .catch(err => console.log(err)); // if an error is thrown in our async function, we will catch it here\n```\n\n#### <a name=\"explanation-with-sample-code-2\"></a> サンプルコード付きの説明\n\n*`async`* / *`await`* はプロミスの上に構築されていますが、これらを使うとより命令型のスタイルでコードを書くことができます。\n\n*`async`* 演算子は関数に非同期のマークを付けて、常に *プロミス* を返す形にします。\n *`async`* 関数の中で *`await`* 演算子を使うことで、その式の戻り値のプロミスがリゾルブかリジェクトのどちらかをするまで（原文では「 until the returned Promise from the expression either resolves or rejects 」です）その行で処理を一時停止することができます。\n\n```js\nasync function myFunc() {\n  // we can use await operator because this function is async\n  return \"hello world\";\n}\n\nmyFunc().then(msg => console.log(msg)) // \"hello world\" -- myFunc's return value is turned into a promise because of async operator\n```\n\n`async` 関数の *`return`* 文に到達したときに、プロミスは戻り値を持ってフルフィルされます（訳注: 原文では「 is fullfilled with the value returned 」）。\n`async` 関数の中でエラーが発生したら、プロミスのステートは *リジェクテッド* に変わります。\n`async` 関数に戻り値が無い場合も、 `async` 関数の実行が完了したときにはプロミスが返され、値を持たずにリゾルブが発生します。\n\n*`await`* 演算子は *プロミス* がフルフィルドになるのを待つために使用するものであり、 *`async`* 関数のボディの中でのみ使用することができます。\n処理が *`await`* のところに来たら、プロミスがフルフィルされるまで処理が一時停止されます。\n\n> **メモ:** *`fetch`* は Ajax リクエストができるプロミスを返す関数です。\n\nまず、プロミスを使うと GitHub ユーザー情報の取得がどのようにできたかを見てみましょう:\n\n```js\nfunction getGithubUser(username) {\n  return fetch(`https://api.github.com/users/${username}`).then(response => response.json());\n}\n\ngetGithubUser('mbeaudru')\n  .then(user => console.log(user))\n  .catch(err => console.log(err));\n```\n\n*`async`* / *`await`* で同じことをすると次のようになります:\n\n```js\nasync function getGithubUser(username) { // promise + await keyword usage allowed\n  const response = await fetch(`https://api.github.com/users/${username}`); // 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`* / *`await`* 構文は依存関係のある複数のプロミスをチェインするときに特に便利です。\n\n例えば、データベースにあるブログ投稿と作成者情報をフェッチするためのトークンを取得する必要がある場合は次のようになります:\n\n> **メモ:** リゾルブされた値のメソッドやプロパティを同一行で利用する場合、 *`await`* 式はかっこで囲う必要があります。\n\n```js\nasync function fetchPostById(postId) {\n  const token = (await fetch('token_url')).json().token;\n  const post = (await fetch(`/posts/${postId}?token=${token}`)).json();\n  const author = (await fetch(`/users/${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##### <a name=\"error-handling\"></a> エラーハンドリング\n\n*`await`* 式の周りに *`try`* / *`catch`* のブロックを追加しておかないと、キャッチされない例外がーー *`async`* 関数のボディの中で投げられたかどうかにかかわらず、また、 *`await`* でサスペンドされていても ーー *`async`* 関数が返したプロミスをリジェクトします。\n`async` 関数の中で `throw` 文を使うことは、リジェクトするプロミスを返すことと同じ意味です。\n（[(参考: PonyFoo)](https://ponyfoo.com/articles/understanding-javascript-async-await#error-handling)）\n\n> **メモ:** プロミスは同じように振る舞います！\n\nプロミスを使った場合、エラーチェインの処理は次のようにしていました:\n\n```js\nfunction getUser() { // 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)); // \"User not found !\"\n```\n\n*`async`* / *`await`* で同じことをすると次のようになります:\n\n```js\nasync function getUser() { // 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)); // \"User not found !\"\n```\n\n#### <a name=\"external-resources-9\"></a> 外部のリソース\n\n- [Async/Await - JavaScript.Info](https://javascript.info/async-await)\n- [ES7 Async/Await](http://rossboucher.com/await/#/)\n- [6 Reasons Why JavaScript’s Async/Await Blows Promises Away](https://hackernoon.com/6-reasons-why-javascripts-async-await-blows-promises-away-tutorial-c7ec10518dd9)\n- [JavaScript awaits](https://dev.to/kayis/javascript-awaits)\n- [Using Async Await in Express with Node 8](https://medium.com/@Abazhenov/using-async-await-in-express-with-node-8-b8af872c0016)\n- [Async Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)\n- [Await](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await)\n- [Using async / await in express with node 8](https://medium.com/@Abazhenov/using-async-await-in-express-with-node-8-b8af872c0016)\n\n### <a name=\"truthy--falsy\"></a> True になるもの / False になるもの\n\nJavaScript では、 `true` になる値と `false` になる値は、真偽判定のコンテキストで評価されたとき（訳注: 原文では「 when evaluated in a boolean context 」です）に真偽値にキャストされます。\n真偽判定のコンテキストの例は、 ```if``` 条件での判定です。\n\n次の値に等しくない値はすべて ```true``` にキャストされます:\n\n- ```false```\n- ```0```\n- ```\"\"``` （空文字列）\n- ```null```\n- ```undefined```\n- ```NaN```\n\n*真偽判定のコンテキスト* の例は次のとおりです:\n\n- ```if``` 条件評価\n\n```js\nif (myVar) {}\n```\n\n```myVar``` にはどんな[第一級市民](https://en.wikipedia.org/wiki/First-class_citizen)（変数、関数、真偽値）を置くこともできますが、真偽判定のコンテキストで評価されているため真偽値にキャストされます。\n\n- 論理 **否定** 演算子 ```!``` の後\n\nこの演算子はそのオペランドが `true` に変換できる場合は `false` を返します。\n逆の場合は `true` を返します。\n\n```js\n!0 // true -- 0 is falsy so it returns true\n!!0 // false -- 0 is falsy so !0 returns true so !(!0) returns false\n!!\"\" // false -- empty string is falsy so NOT (NOT false) equals false\n```\n\n- *真偽値* オブジェクトコンストラクターでの使用\n\n```js\nnew Boolean(0) // false\nnew Boolean(1) // true\n```\n\n- 三項演算子の評価部分（訳注: 原文では「 In a ternary evaluation 」です）\n\n```js\nmyVar ? \"truthy\" : \"falsy\"\n```\n\n`myVar` は真偽判定コンテキストで評価されます。\n\n2 つの値の比較には注意が必要です。\n\n（最終的に真偽値にキャストされる）比較対象のオブジェクトの値は、真偽値にキャストされるのでは **なく** 、 [プリミティブへの変換仕様](http://javascript.info/object-toprimitive) に基いて、プリミティブ値に変換されます。\n内部的には、 `[] == true` のようにオブジェクトが真偽値と比較された場合、 `[].toString() == true` という比較が行われます。\n\n```js\nlet a = [] == true // a is false since [].toString() give \"\" back.\nlet b = [1] == true // b is true since [1].toString() give \"1\" back.\nlet c = [2] == true // c is false since [2].toString() give \"2\" back.\n```\n\n#### <a name=\"external-resources-10\"></a> 外部のリソース\n\n- [Truthy (MDN)](https://developer.mozilla.org/en-US/docs/Glossary/Truthy)\n- [Falsy (MDN)](https://developer.mozilla.org/en-US/docs/Glossary/Falsy)\n- [Truthy and Falsy values in JS - Josh Clanton](http://adripofjavascript.com/blog/drips/truthy-and-falsy-values-in-javascript.html)\n\n### <a name=\"anamorphisms-and-catamorphisms\"></a> アナモルフィズム / カタモルフィズム\n\n#### <a name=\"anamorphisms\"></a> アナモルフィズム\n\nアナモルフィズム（訳注: 原文では「 anamorphisms 」です）とは、あるオブジェクトを、オブジェクト型を含むより複雑な構造体にマップする関数のことです。\nそれは、シンプルな構造体を複雑な構造体に *アンフォールド* する（訳注: 原文では「 unfolding 」です）処理です。\n整数を、整数のリストにアンフォールドする場合を考えてみましょう。\nこの場合、整数が最初のオブジェクトで、整数のリストがより複雑な構造体です。\n\n**サンプルコード**\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  //=> [ 5, 4, 3, 2, 1 ]\n```\n\n#### <a name=\"catamorphisms\"></a> カタモルフィズム\n\nカタモルフィズム（訳注: 原文では「 catamorphisms 」です）とは、アナモルフィズムの逆で、複雑な構造体であるオブジェクトをよりシンプルな構造体に *フォールド* する（訳注: 原文では「 fold 」です）ことです。\n次の `product` のサンプルを見てください。\n`product` は整数のリストを受け取り単一の整数を返します。\n\n**サンプルコード**\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)) // 120\n```\n\n#### <a name=\"external-resources-11\"></a> 外部のリソース\n\n* [Anamorphisms in JavaScript](http://raganwald.com/2016/11/30/anamorphisms-in-javascript.html)\n* [Anamorphism](https://en.wikipedia.org/wiki/Anamorphism)\n* [Catamorphism](https://en.wikipedia.org/wiki/Catamorphism)\n\n### <a name=\"generators\"></a> ジェネレーター\n\n`downToOne` 関数を書く別の方法として、ジェネレーターを使ったものがあります。\n`Generator` オブジェクトを生成するには、 `function *` 宣言を使わなくてはいけません。\nジェネレーターは、一度脱出した後に、コンテキスト（変数バインディング）を保った形で再突入できる関数です（訳注: 原文では「 Generators are functions that can be exited and later re-entered with its context (variable bindings) saved across re-entrances 」です）。\n\n例えば、上の `downToOne` 関数は次のように書き直すことができます:\n\n```js\nfunction * downToOne(n) {\n  for (let i = n; i > 0; --i) {\n    yield i;\n  }\n}\n\n[...downToOne(5)] //[ 5, 4, 3, 2, 1 ]\n```\n\nジェネレーターはイテラブルオブジェクトを返します。\nイテレーターの `next()` 関数が呼ばれると、最初の `yield` 式までが実行されます。\n`yield` 式はイテレーターから返すべき値を指定します。\n`yield*` を使えば、その処理が別のジェネレーター関数に委譲されます。\nジェネレーター式の中で `return` 式が呼ばれると、それはジェネレーターに完了済みという印を付けて、戻り値として返します。\nさらに `next()` を呼び出しても新しい値が返されることはありません。\n\n**サンプルコード**\n\n```js\n// Yield Example\nfunction * idMaker() {\n  var index = 0;\n  while (index < 2) {\n    yield index;\n    index = index + 1;\n  }\n}\n\nvar gen = idMaker();\n\ngen.next().value; // 0\ngen.next().value; // 1\ngen.next().value; // undefined\n```\n\n`yield*` 式を使えば、ジェネレーターの繰り返しの中で別のジェネレーターを呼び出すことができます。\n\n```js\n// 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; // 10\ngen.next().value; // 11\ngen.next().value; // 12\ngen.next().value; // 13\ngen.next().value; // 20\n```\n\n```js\n// Generator Return Example\nfunction* yieldAndReturn() {\n  yield \"Y\";\n  return \"R\";\n  yield \"unreachable\";\n}\n\nvar gen = yieldAndReturn()\ngen.next(); // { value: \"Y\", done: false }\ngen.next(); // { value: \"R\", done: true }\ngen.next(); // { value: undefined, done: true }\n```\n\n#### <a name=\"external-resources-12\"></a> 外部のリソース\n\n* [Mozilla MDN Web Docs, Iterators and Generators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators#Generators)\n\n### <a name=\"static-methods\"></a> スタティックメソッド\n\n#### <a name=\"short-explanation-1\"></a> 短い説明\n\n`static` キーワードは、スタティックメソッドを宣言するためにクラスの中で使用します。\nスタティックメソッドはクラスの中の関数であり、クラスオブジェクトに所属します。\nそのクラスのインスタンスからは利用することができません。\n\n#### <a name=\"sample-code-8\"></a> サンプルコード\n\n```js\nclass Repo{\n  static getName() {\n    return \"Repo name is modern-js-cheatsheet\"\n  }\n}\n\n//Note that we did not have to create an instance of the Repo class\nconsole.log(Repo.getName()) //Repo name is modern-js-cheatsheet\n\nlet r = new Repo();\nconsole.log(r.getName()) //Uncaught TypeError: repo.getName is not a function\n```\n\n#### <a name=\"detailed-explanation-2\"></a> 詳細な説明\n\nスタティックメソッドは、 `this` キーワードを使えば別のスタティックメソッドの中から呼ぶことができます。\nしかし、スタティックではないメソッド（訳注: 原文では「 non-static methods 」です）の場合はこれはできません。\nスタティックでないメソッドが `this` キーワードを使ってスタティックメソッドに直接アクセスすることはできません。\n\n##### <a name=\"calling-other-static-methods-from-a-static-method\"></a> スタティックメソッドから別のスタティックメソッドを呼ぶ\n\nスタティックメソッドを別のスタティックメソッドから呼び出すには、次のように `this` キーワードを使うことができます:\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()) //Repo name is modern-js-cheatsheet-added-this\n```\n\n##### <a name=\"calling-static-methods-from-non-static-methods\"></a> スタティックでないメソッドからスタティックメソッドを呼ぶ\n\nスタティックでないメソッドからはスタティックメソッドを呼ぶ方法が 2 つあります:\n\nNon-static methods can call static methods in 2 ways;\n\n1. クラス名を使う\n\nスタティックでないメソッドからスタティックメソッドにアクセスするには、クラス名を使って、プロパティのような形でスタティックメソッドを呼び出します。\n例: `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// we need to instantiate the class to use non-static methods\nlet r = new Repo()\nconsole.log(r.useName()) //Repo name is modern-js-cheatsheet and it contains some really important stuff\n```\n\n2. コンストラクターを使う\n\nスタティックメソッドは `constructor` オブジェクトのプロパティとして呼ぶことができます。\n\n```js\nclass Repo{\n  static getName() {\n    return \"Repo name is modern-js-cheatsheet\"\n  }\n\n  useName(){\n    //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// we need to instantiate the class to use non-static methods\nlet r = new Repo()\nconsole.log(r.useName()) //Repo name is modern-js-cheatsheet and it contains some really important stuff\n```\n\n#### <a name=\"external-resources-13\"></a> 外部のリソース\n\n- [static keyword- MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/static)\n- [Static Methods- Javascript.info](https://javascript.info/class#static-methods)\n- [Static Members in ES6- OdeToCode](http://odetocode.com/blogs/scott/archive/2015/02/02/static-members-in-es6.aspx)\n\n## <a name=\"glossary\"></a> 用語集\n\n### <a name=\"-scope\"></a> <a name=\"scope_def\"></a> スコープ\n\n値と式が「見え」て、参照可能な場合なコンテキストのこと。\n変数やその他の式が「カレントスコープ」に無い場合は、それらは利用することができません。\n\nソース: [MDN](https://developer.mozilla.org/en-US/docs/Glossary/Scope)\n\n### <a name=\"-variable-mutation\"></a> <a name=\"mutation_def\"></a> 変数ミューテーション\n\n初期値が後から変更されたとき、その変数はミューテートされた（訳注: 原文では「 have been mutated 」です）と言います。\n\n```js\nvar myArray = [];\nmyArray.push(\"firstEl\") // myArray is being mutated\n```\n\nもしある変数がミューテートできなければ、その変数は *イミュータブル* である（訳注: 原文では「 immutable 」です）と言います。\n\n詳しくは、 [MDN の Mutable の記事](https://developer.mozilla.org/en-US/docs/Glossary/Mutable) をご覧ください。\n"
  },
  {
    "path": "translations/pl_PL.md",
    "content": "# <a name=\"modern-javascript-cheatsheet\"></a>Współczesny JavaScript - ściągawka\n\n![Modern JavaScript cheatsheet](https://i.imgur.com/aexPxMb.png)\n<small>Image Credits: [Ahmad Awais ⚡️](https://github.com/ahmadawais)</small>\n\n## <a name=\"introduction\"></a>Wstęp\n\n### <a name=\"motivation\"></a>Motywacja\n\nW tym dokumencie zebrane zostały elementy języka JavaScript, z którymi często można się spotkać we współczesnych projektach i najnowszych przykładach kodu.\n\nCelem tego przewodnika nie jest nauka JavaScriptu od zera, ale pomoc posiadającym podstawową wiedzę developerom, którzy pracując ze współczesnymi bazami kodu (powiedzmy, ucząc się React) napotykają trudności, wynikające z użytych tam konceptów języka JavaScript.\n\nPrócz tego, od czasu do czasu będę zamieszczał własne porady, z którymi niekoniecznie trzeba się zgadzać, ale postaram się za każdym razem podkreślać, że chodzi tylko o moja opinię.\n\n> **Uwaga:** Większość omawianych tu pojęć pochodzi z nowej wersji języka JavaScript (ES2015, często nazywanego ES6). Bardzo dobre omówienie nowych możliwości wprowadzonych w tej wersji można znaleźć [tutaj](http://es6-features.org).\n\n### <a name=\"complementary-resources\"></a>Materiały uzupełniające\n\nJeśli masz problem ze zrozumieniem jakiegoś pojęcia, proponuję poszukać odpowiedzi w poniższych źródłach:\n\n- [MDN (Mozilla Developer Network)](https://developer.mozilla.org/en-US/search?q=)\n- [You don't know JS (book)](https://github.com/getify/You-Dont-Know-JS)\n- [ES6 Features with examples](http://es6-features.org)\n- [WesBos blog (ES6)](http://wesbos.com/category/es6/)\n- [Javascript Basics for Beginners](https://www.udacity.com/course/javascript-basics--ud804) - bezpłatny kurs od Udacity\n- [Reddit (JavaScript)](https://www.reddit.com/r/javascript/)\n- [Google](https://www.google.com/) - dla znalezienia specjalistycznych blogów i innych źródeł\n- [StackOverflow](https://stackoverflow.com/questions/tagged/javascript)\n\n## <a name=\"table-of-contents\"></a>Spis treści\n\n- [Współczesny JavaScript - ściągawka](#modern-javascript-cheatsheet)\n  * [Wstęp](#introduction)\n    + [Motywacja](#motivation)\n    + [Materiały uzupełniające](#complementary-resources)\n  * [Spis treści](#table-of-contents)\n  * [Pojęcia](#notions)\n    + [Deklaracja zmiennych: var, const, let](#variable-declaration-var-const-let)\n      - [Krótkie wyjaśnienie](#short-explanation)\n      - [Przykładowy kod](#sample-code)\n      - [Szczegółowe wyjaśnienie](#detailed-explanation)\n      - [Dodatkowe źródła](#external-resource)\n    + [Funkcje strzałkowe (arrow functions)](#-arrow-function)\n      - [Przykładowy kod](#sample-code-1)\n      - [Szczegółowe wyjaśnienie](#detailed-explanation-1)\n        * [Zwięzłość](#concision)\n        * [Użycie *this*](#this-reference)\n      - [Pomocne źródła](#useful-resources)\n    + [Domyślna wartość argumentów funkcji](#function-default-parameter-value)\n      - [Dodatkowe źródła](#external-resource-1)\n    + [Destrukturyzacja obiektów i tablic](#destructuring-objects-and-arrays)\n      - [Wyjaśnienie z przykładowym kodem](#explanation-with-sample-code)\n      - [Pomocne źródła](#useful-resources-1)\n    + [Metody tablicowe - map / filter / reduce](#array-methods---map--filter--reduce)\n      - [Przykładowy kod](#sample-code-2)\n      - [Wyjaśnienie](#explanation)\n        * [Array.prototype.map()](#arrayprototypemap)\n        * [Array.prototype.filter()](#arrayprototypefilter)\n        * [Array.prototype.reduce()](#arrayprototypereduce)\n      - [Dodatkowe źródła](#external-resource-2)\n    + [Operator rozwijania \"...\"](#spread-operator-)\n      - [Przykładowy kod](#sample-code-3)\n      - [Wyjaśnienie](#explanation-1)\n        * [W obiektach iterowalnych (np. w tablicach)](#in-iterables-like-arrays)\n        * [Parametry rest](#function-rest-parameter)\n        * [Rozwijanie własności obiektów](#object-properties-spreading)\n      - [Dodatkowe źródła](#external-resources)\n    + [Skrócony zapis własności obiektów](#object-property-shorthand)\n      - [Wyjaśnienie](#explanation-2)\n      - [Dodatkowe źródła](#external-resources-1)\n    + [Obietnice (promises)](#promises)\n      - [Przykładowy kod](#sample-code-4)\n      - [Wyjaśnienie](#explanation-3)\n        * [Tworzenie obietnicy (promise)](#create-the-promise)\n        * [Użycie procedur obsługi](#promise-handlers-usage)\n      - [Dodatkowe źródła](#external-resources-2)\n    + [Łańcuchy szablonowe (template literals)](#template-literals)\n      - [Przykładowy kod](#sample-code-5)\n      - [Dodatkowe źródła](#external-resources-3)\n    + [Oznaczone łańcuchy szablonowe (tagged template literals)](#tagged-template-literals)\n      - [Dodatkowe źródła](#external-resources-4)\n    + [Importy / eksporty](#imports--exports)\n      - [Wyjaśnienie z przykładowym kodem](#explanation-with-sample-code-1)\n        * [Nazwane eksporty (named exports)](#named-exports)\n        * [Domyślny import / eksport](#default-import--export)\n      - [Dodatkowe źródła](#external-resources-5)\n    + [*this* w JavaScript](#-javascript-this)\n      - [Dodatkowe źródła](#external-resources-6)\n    + [Klasa](#class)`\n      - [Przykłady](#samples)\n      - [Dodatkowe źródła](#external-resources-7)\n    + [Słowa kluczowe extends i super](#extends-and-super-keywords)\n      - [Przykładowy kod](#sample-code-6)\n      - [Dodatkowe źródła](#external-resources-8)\n    + [Składnia async/await](#async-await)\n      - [Przykładowy kod](#sample-code-7)\n      - [Wyjaśnienie z przykładowym kodem](#explanation-with-sample-code-2)\n      - [Obsługa błędów](#error-handling)\n      - [Dodatkowe źródła](#external-resources-9)\n    + [Prawda / Fałsz](#truthy--falsy)\n      - [Dodatkowe źródła](#external-resources-10)\n    + [Anamorfizmy i Katamorfizmy](#anamorphisms-and-catamorphisms)\n      - [Anamorfizmy](#anamorphisms)\n      - [Katamorfizmy](#catamorphisms)\n      - [Dodatkowe źródła](#external-resources-11)\n    + [Generatory](#generators)\n      - [Dodatkowe źródła](#external-resources-12)\n    + [Metody statyczne](#static-methods)\n      - [Krótkie wyjaśnienie](#short-explanation-1)\n      - [Przykładowy kod](#sample-code-8)\n      - [Szczegółowe wyjaśnienie](#detailed-explanation-2)\n        * [Wzywanie innych metod statycznych z metody statycznej](#calling-other-static-methods-from-a-static-method)\n        * [Wzywanie metod statycznych z metod niestatycznych](#calling-static-methods-from-non-static-methods)\n      - [Dodatkowe źródła](#external-resources-13)\n  * [Słowniczek](#glossary)\n    + [Zakres widoczności (scope)](#-scope)\n    + [Przekształcenie zmiennej (variable mutation)](#-variable-mutation)\n\n## <a name=\"notions\"></a>Pojęcia\n\n### <a name=\"variable-declaration-var-const-let\"></a>Deklaracja zmiennych: var, const, let\n \nW języku JavaScript mamy do dyspozycji trzy słowa kluczowe, za pomocą których deklarowane są zmienne. Są to ```var```, ```let``` and ```const```.\n\n#### <a name=\"short-explanation\"></a>Krótkie wyjaśnienie\n\nZmienne deklarowane z użyciem ```const``` nie moga być ponownie przypisane, natomiast ```let``` i ```var``` mogą.\n\nRadziłbym zawsze deklarować zmienne za pomocą ```const```, a ```let``` stosować, kiedy zamierzamy *przekształcać* zmienne bądź przypisywać im inną wartość.\n\n<table>\n  <tr>\n    <th></th>\n    <th>Zakres widoczności</th>\n    <th>Można nadpisać</th>\n    <th>Można zmienić</th>\n   <th><a href=\"#tdz_sample\">Czasowo martwa strefa</a></th>\n  </tr>\n  <tr>\n    <th>const</th>\n    <td>Blok</td>\n    <td>Nie</td>\n    <td><a href=\"#const_mutable_sample\">Tak</a></td>\n    <td>Tak</td>\n  </tr>\n  <tr>\n    <th>let</th>\n    <td>Blok</td>\n    <td>Tak</td>\n    <td>Tak</td>\n    <td>Tak</td>\n  </tr>\n   <tr>\n    <th>var</th>\n    <td>Funkcja</td>\n    <td>Tak</td>\n    <td>Tak</td>\n    <td>Nie</td>\n  </tr>\n</table>\n\n#### <a name=\"sample-code\"></a>Przykładowy kod\n\n```javascript\nconst person = \"Nick\";\nperson = \"John\" // Wywoła błąd, person nie może być przepisane\n```\n\n```javascript\nlet person = \"Nick\";\nperson = \"John\";\nconsole.log(person) // \"John\", przepisanie jest dozwolone z let\n```\n\n#### <a name=\"detailed-explanation\"></a>Szczegółowe wyjaśnienie\n\n[*Zakres widoczności*] zmiennej oznacza mniej więcej \"to, gdzie zmienna jest dostępna w kodzie\". \n\n##### var\n\nZakresem widoczności zmiennych deklarowanych za pomocą ```var``` jest funkcja. Oznacza to, że jeśli zmienna była stworzona wewnątrz funkcji, to wszystko w ciele tej funkcji ma dostęp do danej zmiennej. Poza tym, zmienna o opisanym zakresie nie jest dostępna poza funkcją.\n\nMożna myśleć o tym następująco: jeśli zakres widoczności zmiennej to *X*, to zmienna ta stanowi jak gdyby własność X.\n\n```javascript\nfunction myFunction() {\n  var myVar = \"Nick\";\n  console.log(myVar); // \"Nick\" - myVar dostępna wewnątrz funkcji.\n}\nconsole.log(myVar); // ReferenceError, myVar nie jest dostępna poza funkcją.\n```\n\nA oto mniej oczywisty przykład:\n\n```javascript\nfunction myFunction() {\n  var myVar = \"Nick\";\n  if (true) {\n    var myVar = \"John\";\n    console.log(myVar); // \"John\"\n    // ponieważ zakresem myVar jest funkcja, zastępujemy wcześniejszą wartość \"Nick\" wartością \"John\"\n  }\n  console.log(myVar); // \"John\" - zwróć uwagę, jak instrukcje w bloku if wpłynęły na wartość\n}\nconsole.log(myVar); // ReferenceError, myVar nie jest dostępna poza funkcją.\n```\n\nPoza tym, zmienne zadeklarowane poprzez *var* przy wykonaniu kodu przemieszczają się na początek zakresu widoczności. Proces ten nazywamy [var hoisting](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var#var_hoisting).\n\nTen fragment kodu:\n\n```js\nconsole.log(myVar) // undefined -- brak błędu\nvar myVar = 2;\n```\n\nw momencie wykonania rozumiany jest tak:\n\n```js\nvar myVar;\nconsole.log(myVar) // undefined -- brak błędu\nmyVar = 2;\n```\n\n##### let\n\n```var``` i ```let ``` znaczą mniej więcej to samo, ale w przypadku zmiennych zadeklarowanych za pomocą ```let``` \n\n- zakres widoczności stanowi blok\n- są **niedostępne** przed przypisaniem\n- nie mogą być ponownie zadeklarowane w tym samym zakresie widoczności\n\nPrzyjrzyjmy się blokowemu zakresu widoczności, używając poprzedniego przykładu:\n\n```javascript\nfunction myFunction() {\n  let myVar = \"Nick\";\n  if (true) {\n    let myVar = \"John\";\n    console.log(myVar); // \"John\"\n    // ponieważ zakresem widoczności myVar jest blok, \n    // właśnie stworzyliśmy nową zmienną myVar.\n    // zmienna ta jest niedostępna poza blokiem i zupełnie \n    // niezależna od pierwszej zmiennej myVar.\n  }\n  console.log(myVar); // \"Nick\", instrukcje bloku if NIE wpłynęły na tę zmienną\n}\nconsole.log(myVar); //  ReferenceError, myVar nie jest dostępna poza funkcją.\n```\n\n<a name=\"tdz_sample\"></a> A teraz rozpatrzmy, co oznacza, że zmienne zadeklarowane z *let* (i *const*) są niedostępne przed przypisaniem:\n\n```js\nconsole.log(myVar) // wywołuje ReferenceError !\nlet myVar = 2;\n```\n\nW odróżnieniu od zmiennych zadeklarowanych poprzez *var*, próba odczytu bądź nadpisania zmiennej stworzonej za pomocą *let* lub *const* przed przypisaniem wywoła błąd. Zjawisko to nazywane jest często [*Czasowo martwą strefą*](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let#Temporal_Dead_Zone_and_errors_with_let) albo *TDZ*\n\n> **Uwaga:** Ściśle rzecz biorąc zmienne zadeklarowane przy pomocy *let* i *const* też są windowane, ale nie przypisywane. Ponieważ nie mogą one być użyte przed przypisaniem, może się wydawać, że nie dochodzi do windowania (hoistingu), co nie jest prawdą. Jeśli chcesz dowiedzieć się więcej, możesz zapoznać się z [dokładnym omówieniem tego zjawiska](http://jsrocks.org/2015/01/temporal-dead-zone-tdz-demystified).\n\nPonadto nie można ponownie zadeklarować zmiennej stworzonej z *let*\n\n```js\nlet myVar = 2;\nlet myVar = 3; // SyntaxError\n```\n\n##### const\n\nZmienne zadeklarowane poprzez słowo kluczowe ```const``` zachowują się, jak te zadeklarowane z *let*, ale nie mogą być ponownie przypisane.\n\nPodsumowując, zmienne stworzone z *const*:\n\n- ich zakresem widoczności jest blok\n- nie są dostępne przed przypisaniem\n- nie mogą być ponownie zadeklarowane w tym samym zakresie widoczności\n- nie mogą być ponownie przypisane\n\n```js\nconst myVar = \"Nick\";\nmyVar = \"John\" // wywołuje błąd, ponowne przypisanie jest niedozwolone\n```\n\n```js\nconst myVar = \"Nick\";\nconst myVar = \"John\" // wywołuje błąd, ponowna deklaracja jest niedozwolone\n```\n\n<a name=\"const_mutable_sample\"></a> Jest jednak pewien szczegół : zmienne zadeklarowane z ```const``` nie są [**niezmienne**](#mutation_def) ! Konkretnie, oznacza to, że *objekty* i *tablice* zadeklarowane poprzez ```const``` **mogą** podlegać modyfikacjom.\n\nW przypadku obiektów:\n```js\nconst person = {\n  name: 'Nick'\n};\nperson.name = 'John' // działa! Zmienna person nie jest ponownie przypisywana, ale ulega zmianie.\nconsole.log(person.name) // \"John\"\nperson = \"Sandra\" // wywoła błąd, ponieważ nie można nadpisywać zmiennych deklarowanych poprzez const\n```\n\nW przypadku tablic:\n```js\nconst person = [];\nperson.push('John'); // działa! Zmienna person nie jest ponownie przypisywana, ale ulega zmianie.\nconsole.log(person[0]) // \"John\"\nperson = [\"Nick\"] // wywoła błąd, ponieważ nie można nadpisywać zmiennych deklarowanych poprzez const\n```\n\n#### <a name=\"external-resource\"></a>Dodatkowe źródła\n\n- [How let and const are scoped in JavaScript - WesBos](http://wesbos.com/javascript-scoping/)\n- [Temporal Dead Zone (TDZ) Demystified](http://jsrocks.org/2015/01/temporal-dead-zone-tdz-demystified)\n\n### <a name=\"-arrow_func\"></a> Funkcje strzałkowe (arrow functions)\n\nW wersji ES6 JavaScript wprowadzone zostały *funkcje strzałkowe* (*arrow functions*) - nowy sposób zapisu funkcji. Oto niektóre jego zalety:\n\n- większa zwięzłość\n- *this* pobierane jest z otaczającego kontekstu\n- niejawny zwrot (implicit return)\n\n#### <a name=\"sample-code-1\"></a>Przykładowy kod\n\n- Zwięzłość i niejawny zwrot\n\n```js\nfunction double(x) { return x * 2; } // Tradycyjny sposób\nconsole.log(double(2)) // 4\n```\n\n```js\nconst double = x => x * 2; // Ta sama funkcja jako funkcja strzałkowa z niejawnym zwrotem\nconsole.log(double(2)) // 4\n```\n\n- Użycie *this*\n\nW funkcji strzałkowej *this* jest równe wartości *this* w otaczającym zakresie widoczności. Zasadniczo, dzięki funkcjom strzałkowym, nie ma już potrzeby używania tricku \"that = this\" przed wywołaniem funkcji wewnątrz funkcji.\n\n```js\nfunction myFunc() {\n  this.myVar = 0;\n  setTimeout(() => {\n    this.myVar++;\n    console.log(this.myVar) // 1\n  }, 0);\n}\n```\n\n#### <a name=\"detailed-explanation-1\"></a>Szczegółowe wyjaśnienie\n\n##### <a name=\"concision\"></a>Zwięzłość\n\nFunkcje strzałkowe są w wielu aspektach bardziej zwięzłe niż tradycyjne funkcje. Rozpatrzmy kilka przypadków:\n\n- Jawny vs niejawny zwrot\n\n**Jawny zwrot** (**explicit return**) to funkcja, w której ciele użyte jest słowo kluczowe *return*. \n\n```js\n  function double(x) {\n    return x * 2; // this function explicitly returns x * 2, *return* keyword is used\n  }\n```\n\nPrzy tradycyjnym sposobie pisania funkcji zwrot był zawsze jawny. Jednak arrow functions pozwalają na *niejawny zwrot*, czyli taki, w którym słowo kluczowe *return* nie jest konieczne przy zwrocie wartości.\n\n```js\n  const double = (x) => {\n    return x * 2; // Jawny zwrot\n  }\n```\n\nPonieważ funkcja ta ogranicza się do zwrotu pewnej wartości (poza tym brak innych instrukcji), możemy użyć niejawnego zwrotu.\n\n```js\n  const double = (x) => x * 2; // Correct, returns x*2\n```\n\nBy to zrobić, musimy ***usunąć nawiasy* i słowo **return**. Stąd też nazwa *niejawny* (implicit) zwrot - mimo braku słowa kluczowego **return**, funkcja i tak zwróci ```x * 2```.\n\n> **Uwaga:** Jeśli funkcja nie zwraca żadnej wartości (z *efektami ubocznymi*), nie ma w niej ani jawnego ani niejawnego zwrotu.\n\nPoza tym, jeśli chcemy niejawnie zwrócić *obiekt*, należy **otoczyć go okrągłymi nawiasami**, by nie dopuścić do konfliktu z nawiasami samego bloku.\n\n```js\nconst getPerson = () => ({ name: \"Nick\", age: 24 })\nconsole.log(getPerson()) // { name: \"Nick\", age: 24 } -- obiekt niejawnie zwracany przez arrow function\n```\n\n- Tylko jeden argument\n\nJeśli funkcja posiada tylko jeden argument, możemy ominąć nawiasy wokół niego. Przyjrzyjmy się ponownie funkcji *double* z poprzedniego kodu:\n\n```js\n  const double = (x) => x * 2; // arrow function ma jeden argument\n```\n\nNawiasy wokół argumentu można usunąć:\n\n```js\n  const double = x => x * 2; // arrow function ma jeden argument\n```\n\n- Brak argumentów\n\nGdy funkcja nie ma argumentu, należy użyć okrągłych nawiasów, jeśli chcemy zachować poprawną składnię.\n\n```js\n  () => { // są nawiasy, wszystko w porządku\n    const x = 2;\n    return x;\n  }\n```\n\n```js\n  => { // brak nawiasów, kod nie będzie działać!\n    const x = 2;\n    return x;\n  }\n```\n\n##### <a name=\"this-reference\"></a>Użycie *this*\n\nAby w pełni zrozumieć działanie funkcji strzałkowych, trzeba wiedzieć, jak w JavaScript zachowuje się [this](#this_def).\n\nW funckji strzałkowej *this* jest równe wartości *this* w otaczającym kontekście. Oznacza to, że funkcja strzałkowa nie tworzy nowego *this*, ale zamiast tego pobiera je z otoczenia.\n\nBez funkcji strzałkowej, jeśli chcemy otrzymać dostęp do zmiennej przez *this* w funkcji znajdującej się w innej funkcji musimy użyć tricku *that = this* lub *self = this*.\n\nNa przykład, używając funkcji setTimeout w myFunc:\n\n```js\nfunction myFunc() {\n  this.myVar = 0;\n  var that = this; // that = this trick\n  setTimeout(\n    function() { // Nowy *this* tworzony w tym zakresie widoczności\n      that.myVar++;\n      console.log(that.myVar) // 1\n\n      console.log(this.myVar) // undefined -- zobacz: deklaracja funkcji wyżej\n    },\n    0\n  );\n}\n```\n\nAle w przypadku funkcji strzałkowej, *this* pobierane jest z otoczenia:\n\n```js\nfunction myFunc() {\n  this.myVar = 0;\n  setTimeout(\n    () => { // this pobierane z otoczenia. W tym przypadku - z myFunc.\n      this.myVar++;\n      console.log(this.myVar) // 1\n    },\n    0\n  );\n}\n```\n\n#### <a name=\"useful-resources\"></a>Pomocne źródła\n\n- [Arrow functions introduction - WesBos](http://wesbos.com/arrow-functions/)\n- [JavaScript arrow function - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions)\n- [Arrow function and lexical *this*](https://hackernoon.com/javascript-es6-arrow-functions-and-lexical-this-f2a3e2a5e8c4)\n\n### <a name=\"function-default-parameter-value\"></a>Domyślna wartość argumentów funkcji\n\nPocząwszy od wersji ES2015, możliwe jest ustawienie domyślnej wartości argumentów funkcji przy użyciu następującej składni: \n\n```js\nfunction myFunc(x = 10) {\n  return x;\n}\nconsole.log(myFunc()) // 10 -- żadna wartość nie jest podana, x otrzymuje wartość domyślną, czyli 10\nconsole.log(myFunc(5)) // 5 -- wartość podana, więc x otrzymuje wartość 5\n\nconsole.log(myFunc(undefined)) // 10 -- podana wartość undefined, więc x otrzymuje wartość domyślną, czyli 10\nconsole.log(myFunc(null)) // null -- wartość (null) jest podana, zobacz: niżej.\n```\n\nDomyślny argument będzie użyty jedynie w dwóch sytuacjach:\n\n- żaden argument nie jest podany\n- jako argument podano *undefined*\n\nInnymi słowami, jeśli jako argument podamy *null*, wartość domyślna **nie zostanie użyta**.\n\n> **Note:** Przypisanie wartości domyślnej można zastować także z destrukturyzowanymi parametrami (patrz: następna sekcja)\n\n#### <a name=\"external-resource-1\"></a>Dodatkowe źródła\n\n- [Default parameter value - ES6 Features](http://es6-features.org/#DefaultParameterValues)\n- [Default parameters - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters)\n\n### <a name=\"destructuring-objects-and-arrays\"></a>Destrukturyzacja obiektów i tablic\n\n*Destrukturyzacja* to wygodny sposób tworzenia nowych zmiennych poprzez wydobycie pewnych wartości z danych przechowywanych w obiektach i tablicach.\n\n*Destrukturyzacja* może być użyta do przypisania zmiennym rozbitych na części parametrów funkcji lub *this.props* w projektach React.\n\n#### <a name=\"explanation-with-sample-code\"></a>Wyjaśnienie z przykładowym kodem\n\n- Obiekt\n\nWe wszystkich przykładach używać będziemy następującego obiektu:\n\n```js\nconst person = {\n  firstName: \"Nick\",\n  lastName: \"Anderson\",\n  age: 35,\n  sex: \"M\"\n}\n```\n\nBez destrukturyzacji:\n\n```js\nconst first = person.firstName;\nconst age = person.age;\nconst city = person.city || \"Paris\";\n```\n\nZ destrukturyzacją, wszystko w jednej linijce:\n\n```js\nconst { firstName: first, age, city = \"Paris\" } = person; // Gotowe !\n\nconsole.log(age) // 35 -- Stworzono nową zmienną równą person.age\nconsole.log(first) // \"Nick\" -- Stworzono nową zmienną równą person.firstName\nconsole.log(firstName) // ReferenceError -- person.firstName istnieje, ale nowo stworzona zmienna nazywa się first\nconsole.log(city) // \"Paris\" -- Stworzono nową zmienną city i, ponieważ person.city jest równe undefined, zmienna jest równa domyślnej wartość \"Paris\".\n```\n\n**Uwaga:** W ```const { age } = person;``` nawiasy po słowie *const* nie są użyte do deklaracji obiektu ani jako blok, ale jako składnia *destrukturyzacji*.\n\n- Argumenty funkcji\n\n*Destrukturyzacja* jest często używana do rozbicia parametrów funkcji na części.\n\nBez destrukturyzacji:\n\n```js\nfunction joinFirstLastName(person) {\n  const firstName = person.firstName;\n  const lastName = person.lastName;\n  return firstName + '-' + lastName;\n}\n\njoinFirstLastName(person); // \"Nick-Anderson\"\n```\n\nJeśli destrukturyzujemy parametr *person*, otrzymujemy znacznie bardziej zwięzłą funkcję:\n\n```js\nfunction joinFirstLastName({ firstName, lastName }) { // tworzymy zmienne firstName i lastName z części argumentu person.\n  return firstName + '-' + lastName;\n}\n\njoinFirstLastName(person); // \"Nick-Anderson\"\n```\n\nDestrukturyzacja jest jeszcze przyjemniejsza, gdy użyjemy [funkcji strzałkowych](#arrow_func_concept):\n\n```js\nconst joinFirstLastName = ({ firstName, lastName }) => firstName + '-' + lastName;\n\njoinFirstLastName(person); // \"Nick-Anderson\"\n```\n\n- Tablica\n\nRozpatrzmy następującą tablicę:\n\n```js\nconst myArray = [\"a\", \"b\", \"c\"];\n```\n\nBez destrukturyzacji\n\n```js\nconst x = myArray[0];\nconst y = myArray[1];\n```\n\nZ destrukturyzacją\n\n```js\nconst [x, y] = myArray; // Gotowe !\n\nconsole.log(x) // \"a\"\nconsole.log(y) // \"b\"\n```\n\n#### <a name=\"useful-resources-1\"></a>Pomocne źródła\n\n- [ES6 Features - Destructuring Assignment](http://es6-features.org/#ArrayMatching)\n- [Destructuring Objects - WesBos](http://wesbos.com/destructuring-objects/)\n- [ExploringJS - Destructuring](http://exploringjs.com/es6/ch_destructuring.html)\n\n### <a name=\"array-methods---map--filter--reduce\"></a>Metody tablicowe - map / filter / reduce\n\n*Map*, *filter* i *reduce* to metody tablicowe zapożyczone z paradygmatu [*programowania funkcyjnego*](https://medium.com/javascript-scene/master-the-javascript-interview-what-is-functional-programming-7f218c68b3a0).\n\nOpiszmy je krótko:\n\n- **Array.prototype.map()** przyjmuje jako argument tablicę, modyfikuje jej elementy i zwraca nową tablicę ze zmienionymi elementami.\n- **Array.prototype.filter()** przyjmuje jako argument tablicę, decyduje, które elementy zatrzymać a które usunąć. Zwraca tablicę z zachowanymi elementami.\n- **Array.prototype.reduce()** przyjmuje jako argument tablicę, wylicza z jej elementów jedną wspólną wartość, którą zwraca.\n\nPolecam używać ich jak najczęściej, zgodnie z zasadami programowania funkcyjnego, ponieważ metody tablicowe są zwięzłe, eleganckie i można je ze sobą łączyć.\n\nWykorzystując trzy powyższe metody możemy uniknąć użycia pętli *for* i *forEach* w większości sytuacji. Kiedy następnym razem będziesz chciał skorzystać z pętli *for*, spróbuj zamiast niej użyć kompozycji *map*, *filter* i *reduce*. Z początku może to sprawiać problemy, bo wymaga przyzwyczajenia sie do nowego sposobu myślenia, ale jeśli już go przyswoisz, wszystko będzie prostsze.\n\n#### <a name=\"sample-code-2\"></a>Przykładowy kod\n\n```js\nconst numbers = [0, 1, 2, 3, 4, 5, 6];\nconst doubledNumbers = numbers.map(n => n * 2); // [0, 2, 4, 6, 8, 10, 12]\nconst evenNumbers = numbers.filter(n => n % 2 === 0); // [0, 2, 4, 6]\nconst sum = numbers.reduce((prev, next) => prev + next, 0); // 21\n```\n\nObliczmy sumę ocen wszystkich studentów z oceną powyżej 10 łącząc *map*, *filter* i *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) // tworzymy tablicę ocen z tablicy studentów za pomocą map \n  .filter(grade => grade >= 10) // filtrujemy tablicę ocen, by pozostawić większe lub równe 10\n  .reduce((prev, next) => prev + next, 0); // sumujemy wszystkie oceny powyżej 10\n\nconsole.log(aboveTenSum) // 44 -- 10 (Nick) + 15 (John) + 19 (Julia), Nathalie poniżej 10 - ignorowana\n```\n\n#### <a name=\"explanation\"></a>Wyjaśnienie\n\nW przykładach wykorzystywać będziemy poniższą tablicę:\n\n```js\nconst numbers = [0, 1, 2, 3, 4, 5, 6];\n```\n\n##### <a name=\"arrayprototypemap\"></a>Array.prototype.map()\n\n```js\nconst doubledNumbers = numbers.map(function(n) {\n  return n * 2;\n});\nconsole.log(doubledNumbers); // [0, 2, 4, 6, 8, 10, 12]\n```\n\nCo tu się dzieje? Używamy *map* na tablicy *numbers*, *map* iteruje przez każdy element i używa go jako argumentu funkcji. Celem funkcji jest przeprowadzenie kalkulacji i zwrot nowej wartości, która zastąpi wartość użytą jako argument.\n\nWydzielmy funkcję z tablicy, żeby przyjrzeć się jej bliżej:\n\n```js\nconst doubleN = function(n) { return n * 2; };\nconst doubledNumbers = numbers.map(doubleN);\nconsole.log(doubledNumbers); // [0, 2, 4, 6, 8, 10, 12]\n```\n\n```numbers.map(doubleN)``` tworzy ```[doubleN(0), doubleN(1), doubleN(2), doubleN(3), doubleN(4), doubleN(5), doubleN(6)]```, które są równe ```[0, 2, 4, 6, 8, 10, 12]```.\n.\n> **Uwaga:** Jeśli nie potrzebujesz zwrotu nowej tablicy i chcesz po prostu użyć pętli posiadającej efekty uboczne, możesz rozważyć użycie pętli for / forEach zamiast map.\n\n##### <a name=\"arrayprototypefilter\"></a>Array.prototype.filter()\n\n```js\nconst evenNumbers = numbers.filter(function(n) {\n  return n % 2 === 0; // true jeśli n jest parzyste, false jeśli nie jest\n});\nconsole.log(evenNumbers); // [0, 2, 4, 6]\n```\n\nUżywamy *filter* na tablicy *numbers*, *filter* iteruje przez każdy element i używa go jako argumentu funkcji. Celem funkcji jest zwrot zmiennej typu boolowskiego, która określi, czy daną wartość należy zachować, czy też nie. Następnie funkcja zwraca tablicę, zawierającą jedynie zachowane wartości.\n\n##### <a name=\"arrayprototypereduce\"></a>Array.prototype.reduce()\n\nCelem metody *reduce* jest wyliczenie na podstawie tablicy pewnej pojedynczej wartości. Jakie wyliczenia przeprowadzi metoda, zależy tylko od ciebie.\n\n```js\nconst sum = numbers.reduce(\n  function(acc, n) {\n    return acc + n;\n  },\n  0 // wartość zmiennej akumulującej po pierwszej iteracji\n);\n\nconsole.log(sum) //21\n```\n\nTak jak metody .map i .filter, .reduce wykorzystuje tablicę i jako pierwszy argument przyjmuje funkcję.\n\nSą jednak pewne różnice:\n\n- .reduce przyjmuje dwa argumenty\n\nPierwszy argument to funkcja, która będzie stosowana przy każdej iteracji.\n\nDrugi argument to wartość zmiennej akumulującej (w naszym przypadku *acc*) w pierwszej iteracji (by lepiej zrozumieć, czytaj dalej).\n\n- Argumenty funkcji\n\nFunkcja używana jako pierwszy argument .reduce przyjmuje dwa argumenty. Pierwszy (w naszym przypadku *acc*) to zmienna akumulująca, drugi (*n*) - obecny element.\n\nZmienna akumulująca równa jest wartości zwróconej przez naszą funkcję w **poprzedniej** iteracji. Na początku każdej iteracji *acc* równa jest wartości, która była przekazana jako drugi argument .reduce.\n\n###### W pierwszej iteracji\n\n```acc = 0``` ponieważ jako drugi element *reduce* podaliśmy 0\n\n```n = 0``` pierwszy element tablicy *array*\n\nFunkcja zwraca *acc* + *n* --> 0 + 0 --> 0\n\n###### W drugiej iteracji\n\n```acc = 0``` ponieważ taką wartość funkcja zwróciła przy poprzedniej iteracji\n\n```n = 1``` drugi element tablicy *array*\n\nFunkcja zwraca *acc* + *n* --> 0 + 1 --> 1\n\n###### W trzeciej iteracji\n\n```acc = 1``` ponieważ taką wartość funkcja zwróciła przy poprzedniej iteracji\n\n```n = 2``` trzeci element tablicy *array*\n\nFunkcja zwraca *acc* + *n* --> 1 + 2 --> 3\n\n###### W czwartej iteracji\n\n```acc = 3``` ponieważ taką wartość funkcja zwróciła przy poprzedniej iteracji\n\n```n = 3``` czwarty element tablicy *array*\n\nFunkcja zwraca *acc* + *n* --> 3 + 3 --> 6\n\n###### [...] W ostatniej iteracji\n\n```acc = 15``` ponieważ taką wartość funkcja zwróciła przy poprzedniej iteracji\n\n```n = 6``` ostatni element tablicy *array*\n\nFunkcja zwraca *acc* + *n* --> 15 + 6 --> 21\n\nPonieważ to ostatnia iteracja, **.reduce** zwraca 21.\n\n#### <a name=\"external-resource-2\"></a>Dodatkowe źródła\n\n- [Understanding map / filter / reduce in JS](https://hackernoon.com/understanding-map-filter-and-reduce-in-javascript-5df1c7eee464)\n\n### <a name=\"spread-operator-\"></a>Operator rozwijania \"...\"\n\nOperator rozwijania ```...``` został wprowadzony z ES2015 i przeznaczony jest do \"rozwijania\" elementów obiektów iterowalnych (np. tablic) tam, gdzie można zmieścić kilka elementów\n\n#### <a name=\"sample-code-3\"></a>Przykładowy kod\n\n```js\nconst arr1 = [\"a\", \"b\", \"c\"];\nconst arr2 = [...arr1, \"d\", \"e\", \"f\"]; // [\"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// \"a\"\n// \"b\"\n// [\"c\", \"d\", \"e\", \"f\"]\n```\n\n```js\nconst { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };\nconsole.log(x); // 1\nconsole.log(y); // 2\nconsole.log(z); // { a: 3, b: 4 }\n\nconst n = { x, y, ...z };\nconsole.log(n); // { x: 1, y: 2, a: 3, b: 4 }\n```\n\n#### <a name=\"explanation-1\"></a>Wyjaśnienie\n\n##### <a name=\"in-iterables-like-arrays\"></a>W obiektach iterowalnych (np. tablicach)\n\nJeśli mamy dwie następujące tablice:\n\n```js\nconst arr1 = [\"a\", \"b\", \"c\"];\nconst arr2 = [arr1, \"d\", \"e\", \"f\"]; // [[\"a\", \"b\", \"c\"], \"d\", \"e\", \"f\"]\n```\n\nPierwszy element tablicy *arr2* jest tablicą, ponieważ *arr1* został wprowadzony do *arr2* bezpośrednio. Co jednak, jeśli chcemy, by *arr2* było tablicą liter? Możemy rozwinąć (*spread*) elementy *arr1* w tablicy *arr2*.\n\nZ operatorem rozwijania\n\n```js\nconst arr1 = [\"a\", \"b\", \"c\"];\nconst arr2 = [...arr1, \"d\", \"e\", \"f\"]; // [\"a\", \"b\", \"c\", \"d\", \"e\", \"f\"]\n```\n\n##### <a name=\"function-rest-parameter\"></a>Parametry rest\n\nOperator rest pozwala przedstawić dowolna liczbę argumentów w postaci tablicy, po elementach której można iterować. Istnieje już obiekt **arguments** związany z każdą funkcją i równy tablicy wszystkich argumentów przekazanych do danej funkcji.\n\n\n```js\nfunction myFunc() {\n  for (var i = 0; i < arguments.length; i++) {\n    console.log(arguments[i]);\n  }\n}\n\nmyFunc(\"Nick\", \"Anderson\", 10, 12, 6);\n// \"Nick\"\n// \"Anderson\"\n// 10\n// 12\n// 6\n```\n\nWyobraźmy sobie teraz, że chcemy, żeby nasza funkcja tworzyła nowego ucznia z ocenami i średnią. Czy nie byłoby wygodniej zapisać dwa pierwsze argumenty jako dwie oddzielne zmienne, a wszystkie oceny umieścić w iterowalnej tablicy?\n\nWłaśnie na to pozwala nam operator rest!\n\n```js\nfunction createStudent(firstName, lastName, ...grades) {\n  // firstName = \"Nick\"\n  // lastName = \"Anderson\"\n  // [10, 12, 6] -- \"...\" bierze wszystkie pozostałe argumenty przekazane funkcji i tworzy zmienną \"grades\" z przechowującą je tablicą \n\n  const avgGrade = grades.reduce((acc, curr) => acc + curr, 0) / grades.length; // oblicza średnią z ocen\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// {\n//   firstName: \"Nick\",\n//   lastName: \"Anderson\",\n//   grades: [10, 12, 6],\n//   avgGrade: 9,33\n// }\n```\n\n> **Uwaga:** funkcja createStudent jest zła, bo nie sprawdzamy, czy grades.length istnieje i czy jest różna od zera. Nie ująłem tej sytuacji w kodzie, żeby funkcja była bardziej czytelna.\n\n##### <a name=\"object-properties-spreading\"></a>Rozwijanie własności obiektów\n\nAby zrozumieć tę część, polecam najpierw przeczytać poprzednie sekcje dotyczące użycia operatora rest na iterowalnych obiektach i parametrach funkcji.\n\n```js\nconst myObj = { x: 1, y: 2, a: 3, b: 4 };\nconst { x, y, ...z } = myObj; // destrukturyzacja obiektu\nconsole.log(x); // 1\nconsole.log(y); // 2\nconsole.log(z); // { a: 3, b: 4 }\n\n// z to reszta destrukturyzowanego obiektu: myObj object minus destrukturyzowane własności x i y\n\nconst n = { x, y, ...z };\nconsole.log(n); // { x: 1, y: 2, a: 3, b: 4 }\n\n// Własności obiektu z są rozwinięte w n\n```\n\n#### <a name=\"external-resources\"></a>Dodatkowe źródła\n\n- [TC39 - Object rest/spread](https://github.com/tc39/proposal-object-rest-spread)\n- [Spread operator introduction - WesBos](https://github.com/wesbos/es6-articles/blob/master/28%20-%20Spread%20Operator%20Introduction.md)\n- [JavaScript & the spread operator](https://codeburst.io/javascript-the-spread-operator-a867a71668ca)\n- [6 Great uses of the spread operator](https://davidwalsh.name/spread-operator)\n\n### <a name=\"object-property-shorthand\"></a>Skrócony zapis własności obiektów\n\nKiedy przypisujemy zmienną do własności obiektu, jeśli nazwa zmiennej jest taka sama, jak nazwa własności, możemy zrobić coś takiego:\n\n```js\nconst x = 10;\nconst myObj = { x };\nconsole.log(myObj.x) // 10\n```\n\n#### <a name=\"explanation-2\"></a>Wyjaśnienie\n\nDotychczas (przed ES2015), kiedy chcieliśmy przy deklaracji nowego literału obiektowego (*object literal*) zastosować zmienne jako jego własności, zapisalibyśmy to w ten sposób:\n\n```js\nconst x = 10;\nconst y = 20;\n\nconst myObj = {\n  x: x, // przypisanie wartości zmiennej x do myObj.x\n  y: y // przypisanie wartości zmiennej y do myObj.y\n};\n\nconsole.log(myObj.x) // 10\nconsole.log(myObj.y) // 20\n```\n\nJak widać, jest to dość powtarzalne, bo nazwy własności myObj są takie same, jak nazwy zmiennych, które chcemy przypisać do tych własności.\n\nZ ES2015, jeśli nazwa zmiennej jest taka sama jak własności, możemy skorzystać ze skróconego zapisu:\n\n```js\nconst x = 10;\nconst y = 20;\n\nconst myObj = {\n  x,\n  y\n};\n\nconsole.log(myObj.x) // 10\nconsole.log(myObj.y) // 20\n```\n\n#### <a name=\"external-resources-1\"></a>Dodatkowe źródła\n\n- [Property shorthand - ES6 Features](http://es6-features.org/#PropertyShorthand)\n\n### <a name=\"promises\"></a>Obietnice (promises)\n\nObietnica (promise) to obiekt, który może być zwrócony synchronicznie z asynchronicznej funkcji. ([ref](https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-promise-27fc71e77261#3cd0)).\n\nObietnice pozwalają zapobiec tzw. [callback hell](http://callbackhell.com/), i stosowane są coraz częściej we współczesnych projektach tworzonych w języku JavaScript.\n\n#### <a name=\"sample-code-4\"></a>Przykładowy kod\n\n```js\nconst fetchingPosts = new Promise((res, rej) => {\n  $.get(\"/posts\")\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#### <a name=\"explanation-3\"></a>Wyjaśnienie\n\nKiedy wykonujemy **zapytanie Ajax** odpowiedź nie jest synchroniczna, ponieważ żądamy zasobu, którego pobranie wymaga czasu. Może się nawet zdarzyć, że z jakiegoś powodu (404) zasób nigdy nie zostanie pobrany.\n\nAby radzić sobie w tego typu sytuacjach, ES2015 daje nam obietnice (*promises*). Obietnice mogą mieć trzy różne stany:\n\n- oczekujący (pending)\n- zakończony (fulfilled)\n- odrzucony (rejected)\n\nPowiedzmy, że chcemy wykorzystać obietnice dla obsługi zapytania Ajax w celu pobrania zasobu X.\n\n##### <a name=\"create-the-promise\"></a>Tworzenie obietnicy\n\nNajpierw musimy stworzyć obietnicę. Dla stworzenia zapytania Ajax do zasobu X użyjemy metody GET jQuery.\n\n```js\nconst xFetcherPromise = new Promise( // Tworzymy obietnicę poprzez słowo kluczowe new i zapisujemy go do zmiennej \n  function(resolve, reject) { // Konstruktor obietnicy przyjmuje jako argument funkcję, która sama przyjmuje dwa argumenty: resolve i reject\n    $.get(\"X\") // Uruchamiamy zapytanie Ajax\n      .done(function(X) { // Kiedy zapytanie jest gotowe...\n        resolve(X); // ... wypełniamy obietnicę z wartością X jako argumentem\n      })\n      .fail(function(error) { // Jeśli zapytanie się nie udało...\n        reject(error); // ... odrzucamy obietnicę z wartością X jako argumentem\n      });\n  }\n)\n```\n\nJak widać na przykładzie, obiekt Promise przyjmuje funkcję-*executor*, która z kolei przy dwa argumenty **resolve** i **reject**. Argumenty te są funkcjami, które przy wezwaniu zmieniają stan obietnicy oczekujący (*pending*) na, odpowiednio, zakończony (*fulfilled*) i odrzucony (*rejected*). \n\nObietnica znajduje się w stanie oczekiwania po stworzeniu instancji, a jej funkcja-*executor* jest natychmiast wykonywana. Kiedy jedna z funkcji *resolve* bądź *reject* zostanie wezwana w funkcji-*executor*, obietnica wywoła związane z nią procedury obsługi.\n\n##### <a name=\"promise-handlers-usage\"></a>Użycie procedur obsługi\n\nBy otrzymać rezultat obietnicy (lub błąd), musimy podpiąć ją pod procedury obsługi używając następującego kodu:\n\n```js\nxFetcherPromise\n  .then(function(X) {\n    console.log(X);\n  })\n  .catch(function(err) {\n    console.log(err)\n  })\n```\n\nJeśli wszystko przebiegło prawidłowo, zostaje wywołane *resolve* i wykonana zostaje funkcja przekazana jako argument ```.then```. \n\nJeśli zapytanie się nie udało, zostaje wywołane *reject* i wykonana zostaje funkcja przekazana jako argument ```.catch```. \n \n> **Uwaga:** Jeśli obietnica została już wypełniona lub odrzucona w momencie podpięcia odpowiedniej procedury obsługi, procedura będzie wywołana, tak więc nie wyniknie wyścig (race condition) między wykonaniem operacji asynchronicznej i wyznaczeniem procedur obsługi. [(Ref: MDN)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise#Description)\n\n#### <a name=\"external-resources-2\"></a>Dodatkowe źródła\n\n- [JavaScript Promises for dummies - Jecelyn Yeen](https://scotch.io/tutorials/javascript-promises-for-dummies)\n- [JavaScript Promise API - David Walsh](https://davidwalsh.name/promises)\n- [Using promises - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises)\n- [What is a promise - Eric Elliott](https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-promise-27fc71e77261)\n- [JavaScript Promises: an Introduction - Jake Archibald](https://developers.google.com/web/fundamentals/getting-started/primers/promises)\n- [Promise documentation - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)\n\n### <a name=\"template-literals\"></a>Łańcuchy szablonowe (template literals)\n\nŁańcuchy szablonowe to [*interpolacja wyrażenia*](https://en.wikipedia.org/wiki/String_interpolation) dla jedno- i wieloliniowych stringów.\n\nInaczej mówiąc, jest to nowa składnia stringów, pozwalająca na wygodne użycie dowolnych wyrażeń JavaScript (np. zmiennych).\n\n#### <a name=\"sample-code-5\"></a>Przykładowy kod\n\n```js\nconst name = \"Nick\";\n`Hello ${name}, następujące wyrażenie jest równe czterem: ${2+2}`;\n\n// Hello Nick, następujące wyrażenie jest równe czterem: 4\n```\n\n#### <a name=\"external-resources-3\"></a>Dodatkowe źródła\n\n- [String interpolation - ES6 Features](http://es6-features.org/#StringInterpolation)\n- [ES6 Template Strings - Addy Osmani](https://developers.google.com/web/updates/2015/01/ES6-Template-Strings)\n\n### <a name=\"tagged-template-literals\"></a>Oznaczone łańcuchy szablonowe\n\nTagi szablonowe to *funkcje które mogą być prefiksem dla [łańcucha szablonowego](#template-literals)*. Kiedy funkcja zostaje wezwana w ten sposób, pierwszy argument stanowi tablica *stringów*, które pojawiają się między interpolowanymi zmiennymi, a kolejne parametry to znaczenia wyrażeń wstawionych w string. Dla przechwycenia ich wszystkich można użyć operatora rozwijania. [(Ref: MDN)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#Tagged_template_literals).\n\n> **Uwaga :** Słynna biblioteka [styled-components](https://www.styled-components.com/) w dużej mierze polega na tej funkcjonalności.\n\nPoniżej znajduje się przykład działania tagów szablonowych:\n```js\nfunction highlight(strings, ...values) {\n  const interpolation = strings.reduce((prev, current) => {\n    return prev + current + (values.length ? \"<mark>\" + values.shift() + \"</mark>\" : \"\");\n  }, \"\");\n\n  return interpolation;\n}\n\nconst condiment = \"jam\";\nconst meal = \"toast\";\n\nhighlight`I like ${condiment} on ${meal}.`;\n// \"I like <mark>jam</mark> on <mark>toast</mark>.\"\n```\n\nI jeszcze jeden - ciekawszy - przykład:\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// \"I like apples, bananas, cherries to snack on.\"\n```\n\n#### <a name=\"external-resources-4\"></a>Dodatkowe źródła\n- [Wes Bos on Tagged Template Literals](http://wesbos.com/tagged-template-literals/)\n- [Library of common template tags](https://github.com/declandewet/common-tags)\n\n### <a name=\"imports--exports\"></a>Importy / eksporty\n\nModuły ES6 są używane dla otrzymania dostępu do zmiennych lub funkcji z drugich modułów, przy czym eksport powinien być jasno oznaczony w wyjściowym module.\n\nBardzo polecam zapoznać się z zasobami MDN dotyczącymi importów i eksportów (zobacz: Dodatkowe materiały), znajdziecie tam dokładne i przystępne wyjaśnienie.\n\n#### <a name=\"explanation-with-sample-code-1\"></a>Wyjaśnienie z przykładowym kodem\n\n##### <a name=\"named-exports\"></a>Nazwane eksporty (named exports)\n\nNazwane eksporty są używane do eksportu kilku wartości z modułu.\n\n> **Uwaga :** W nazwanych eksportach można stosować jedynie [typy pierwszoklasowe](https://en.wikipedia.org/wiki/First-class_citizen), które posiadają nazwę.\n\n\n```js\n// mathConstants.js\nexport const pi = 3.14;\nexport const exp = 2.7;\nexport const alpha = 0.35;\n\n// -------------\n\n// myFile.js\nimport { pi, exp } from './mathConstants.js'; // Nazwany import - składnia podobna do destrukturyzacji\nconsole.log(pi) // 3.14\nconsole.log(exp) // 2.7\n\n// -------------\n\n// mySecondFile.js\nimport * as constants from './mathConstants.js'; // Wszystkie eksportowane wartości przypisane są do stałych\nconsole.log(constants.pi) // 3.14\nconsole.log(constants.exp) // 2.7\n```\n\nChociaż nazwane importy przypominają *destrukturyzację*, posiadają inną składnią i nie są tym samym. Nie wspierają ani wartości domyślnych, ani *głębokiej* destrukturyzacji.\n\nPoza tym, można tworzyć aliasy, ale składnia wygląda inaczej niż przy destrukturyzacji:\n\n```js\nimport { foo as bar } from 'myFile.js'; // foo jest importowane i przypisane do nowej zmiennej bar\n```\n\n##### <a name=\"default-import--export\"></a>Domyślny import / export\n\nW przypadku domyślnego eksportu na jeden moduł przypada jeden domyślny eksport. Domyślny eksport może być funkcją, klasą, obiektem itp. Wartość ta jest traktowana jako \"główna\" eksportowana wartość, ponieważ importowanie jej jest najprostsze. [Ref: MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export#Description)\n\n```js\n// coolNumber.js\nconst ultimateNumber = 42;\nexport default ultimateNumber;\n\n// ------------\n\n// myFile.js\nimport number from './coolNumber.js';\n// Eksport domyślny, niezależnie od swojej nazwy w wyjściowym module, automatycznie przypisywany jest do zmiennej number;\nconsole.log(number) // 42\n```\n\nEksport funkcji:\n\n```js\n// sum.js\nexport default function sum(x, y) {\n  return x + y;\n}\n// -------------\n\n// myFile.js\nimport sum from './sum.js';\nconst result = sum(1, 2);\nconsole.log(result) // 3\n```\n\n#### <a name=\"external-resources-5\"></a>Dodatkowe źródła\n\n- [ES6 Modules in bulletpoints](https://ponyfoo.com/articles/es6#modules)\n- [Export - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export)\n- [Import - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import)\n- [Understanding ES6 Modules](https://www.sitepoint.com/understanding-es6-modules/)\n- [Destructuring special case - import statements](https://ponyfoo.com/articles/es6-destructuring-in-depth#special-case-import-statements)\n- [Misunderstanding ES6 Modules - Kent C. Dodds](https://medium.com/@kentcdodds/misunderstanding-es6-modules-upgrading-babel-tears-and-a-solution-ad2d5ab93ce0)\n- [Modules in JavaScript](http://exploringjs.com/es6/ch_modules.html#sec_modules-in-javascript)\n\n### <a name=\"-javascript-this\"></a> *this* w JavaScript\n\nOperator *this* zachowuje się inaczej niż w innych językach. W większości przypadków jego zachowanie zależy od tego, jak wywoływana jest funkcja.\n\nZagadnienie to może być dość trudne do zrozumienia, dlatego polecam zapoznać się dokładnie z dodatkowymi materiałami podanymi niżej. Postaram się wyjaśnić, jak sam rozumiem działanie *this*. Nauczyłem się tego z [artykułu Yehudy Katza](http://yehudakatz.com/2011/08/11/understanding-javascript-function-invocation-and-this/).\n\n```js\nfunction myFunc() {\n  ...\n}\n\n// Po każdym wyrażeniu postaramy się określić znaczenie this w myFunc\n\nmyFunc.call(\"myString\", \"hello\") // \"myString\" -- pierwszy parametr .call zapisywany jest w *this*\n\n// W trybie non-strict\nmyFunc(\"hello\") // window -- myFunc() to cukier syntaktyczny dla myFunc.call(window, \"hello\")\n\n// W trybie strict\nmyFunc(\"hello\") // undefined -- myFunc() to cukier syntaktyczny dla myFunc.call(undefined, \"hello\")\n```\n\n```js\nvar person = {\n  myFunc: function() { ... }\n}\n\nperson.myFunc.call(person, \"test\") // person Object -- pierwszy parametr .call zapisywany jest w *this*\nperson.myFunc(\"test\") // person Object -- person.myFunc() to cukier syntaktyczny dla person.myFunc.call(person, \"test\")\n\nvar myBoundFunc = person.myFunc.bind(\"hello\") // Tworzy nową funkcję, w której \"hello\" zapisywane jest w *this*\nperson.myFunc(\"test\") // person Object -- Metoda bind nie ma wpływu na oryginalną metodę\nmyBoundFunc(\"test\") // \"hello\" -- myBoundFunc to person.myFunc z \"hello\" przywiązanym do *this*\n```\n\n#### <a name=\"external-resources-6\"></a>Dodatkowe źródła\n\n- [Understanding JavaScript Function Invocation and \"this\" - Yehuda Katz](http://yehudakatz.com/2011/08/11/understanding-javascript-function-invocation-and-this/)\n- [JavaScript this - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this)\n\n### <a name=\"class\"></a>Klasa\n\nJavaScript jest językiem [opartym na prototypach](https://en.wikipedia.org/wiki/Prototype-based_programming) (podczas gdy, na przykład, Java jest [oparta na klasach](https://en.wikipedia.org/wiki/Class-based_programming)). ES6 wprowadza klasy JavaScript, które mają być cukrem syntaktycznym dla dziedziczenia opartego na prototypach a *nie* nowym modelem dziedziczenia opartego na klasach ([ref](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes)).\n\nUżycie słowa *class* może istotnie prowadzić do błędów, jeśli jesteśmy przyzwyczajeni do klas stosowanych w innych językach. Dlatego też klasy w JavaScript lepiej traktować jak zupełnie odrębne zagadnienie.\n\nPonieważ nasz przewodnik nie ma na celu nauki języka od podstaw, zakładam, że wiesz, czym są prototypy i jak działają. Jeśli nie, zapoznaj się z dodatkowymi materiałami znajdującymi się pod kodem przykładowym.\n\n#### <a name=\"samples\"></a>Przykłady\n\nSkładnia prototypu sprzed ES6:\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\nSkładnia klasy z ES6:\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'm \" + this.age;\n  }\n}\n\nconst myPerson = new Person(\"Manu\", 23);\nconsole.log(myPerson.age) // 23\nconsole.log(myPerson.stringSentence()) // \"Hello, my name is Manu and I'm 23\n```\n\n#### <a name=\"external-resources-7\"></a>Dodatkowe źródła\n\nOmówienie prototypów:\n\n- [Understanding Prototypes in JS - Yehuda Katz](http://yehudakatz.com/2011/08/12/understanding-prototypes-in-javascript/)\n- [A plain English guide to JS prototypes - Sebastian Porto](http://sporto.github.io/blog/2013/02/22/a-plain-english-guide-to-javascript-prototypes/)\n- [Inheritance and the prototype chain - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain)\n\nOmówienie klas:\n\n- [ES6 Classes in Depth - Nicolas Bevacqua](https://ponyfoo.com/articles/es6-classes-in-depth)\n- [ES6 Features - Classes](http://es6-features.org/#ClassDefinition)\n- [JavaScript Classes - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes)\n\n### <a name=\"extends-and-super-keywords\"></a>Słowa kluczowe `extends` i `super`\n\nSłowo kluczowe `extends` używane jest w deklaracji klas w celu stworzenia klasy dziedziczącej od innej klasy ([Ref: MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/extends)). Klasa pochodna dziedziczy wszystkie własności klasy bazowej, może dodawać nowe lub modyfikować odziedziczone własności.\n\nSłowo kluczowe `super` służy do wzywania funkcji na klasie bazowej obiektu, włącznie z jej konstruktorem. \n\n- słowo kluczowe `super` musi być użyte przed słowem `this` w konstruktorze\n- Wezwanie `super()` wywołuje konstruktor klasy bazowej. Jeśli chcesz przekazać argumenty w konstruktorze klasy do konstruktora klasy bazowej, użyj `super(arguments)`.\n- Jeśli klasa bazowa posiada metodę (także statyczną) o nazwie `X`, można użyć `super.X()`, by wywołać ją w klasie pochodnej.\n\n#### <a name=\"sample-code-6\"></a>Przykładowy kod\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    // Wzywany jest konstruktor klasy bazowej z szerokością i długością przekazanymi przez Polygon\n    super(length, length);\n    // Uwaga: W klasach pochodnych super() musi zostać wezwane przed 'this'. W przeciwnym razie pojawi się błąd.\n    this.name = 'Square';\n    this.length = length;\n  }\n\n  getCustomHelloPhrase() {\n    const polygonPhrase = super.getHelloPhrase(); // super.X() daje dostęp do metody klasy bazowej\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) // 100\nconsole.log(mySquare.getHelloPhrase()) // 'Hi, I am a Square' -- Square dziedziczy od Polygon i ma dostęp do jego metod\nconsole.log(mySquare.getCustomHelloPhrase()) // 'Hi, I am a Square with a length of 10'\n```\n\n**Uwaga :** Jeśli spróbujemy użyć `this` przed wezwaniem `super()` w klasie Square, pojawi się ReferenceError \n\n```js\nclass Square extends Polygon {\n  constructor(length) {\n    this.height; // ReferenceError, najpierw trzeba wezwać super!\n\n    // Wzywany jest konstruktor klasy bazowej z szerokością i długością przekazanymi przez Polygon\n    super(length, length);\n\n    // Uwaga: W klasach pochodnych super() musi zostać wezwane przed 'this'. W przeciwnym razie pojawi się błąd.\n    this.name = 'Square';\n  }\n}\n```\n\n#### <a name=\"external-resources-8\"></a>Dodatkowe źródła\n\n- [Extends - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/extends)\n- [Super operator - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/super)\n- [Inheritance - MDN](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Inheritance)\n\n### <a name=\"async-await\"></a>Składnia async/await\n\nOprócz [Obietnic (Promises)](#promises), możesz spotkać jeszcze jeden rodzaj składni dla obsługi kodu asynchronicznego, a mianowicie *async / await*.\n \nRolą funkcji async/await jest uproszczenie zachowania używanych synchronicznie obietnic oraz by używać grup Obietnic. Async/await przypomina połączenie generatorów i obietnic. Funkcje async *zawsze* zwracają Obietnicę ([Ref: MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function))\n\n> **Uwaga :** Ponieważ funkcje async / await bazują na obietnicach, aby prawidłowo stosować wspomniane funkcje, musisz najpierw dobrze rozumieć działanie obietnic.\n\n> **Uwaga 2:** [*await* musi zostać użyte w funkcji *async*](https://hackernoon.com/6-reasons-why-javascripts-async-await-blows-promises-away-tutorial-c7ec10518dd9#f3f0), co oznacza, że await nie można użyć na wyższym poziomie kodu, nie znajdującym się wewnątrz funkcji async.\n\n#### <a name=\"sample-code-7\"></a>Przykładowy kod\n\n```js\nasync function getGithubUser(username) { // słowo kluczowe async pozwala użyć await w funkcji i oznacza, że funkcja zwraca obietnicę\n  const response = await fetch(`https://api.github.com/users/${username}`); // Czeka na obietnicę przed przejściem do reszty kodu\n  return response.json();\n}\n\ngetGithubUser('mbeaudru')\n  .then(user => console.log(user)) // logowanie użytkownika - nie można użyć await, bo nie znajduje się w funkcji async\n  .catch(err => console.log(err)); // jeśli w funkcji async pojawi się błąd, wyłapujemy go tutaj\n```\n\n#### <a name=\"explanation-with-sample-code-2\"></a>Wyjaśnienie z przykładowym kodem\n\n*Async / Await* jest zbudowany na obietnicach, ale pozwala na bardziej imperatywny styl kodu.\n\nOperator *async* oznacza funkcję jako asynchroniczną. Dana funkcja zawsze zwraca Obietnicę. W funkcji *async* można użyć operatora *async*, aby zatrzymać wykonanie kodu na danej linijce dopóki zwracana Obietnica nie zostanie wypełniona bądź odrzucona.\n\n```js\nasync function myFunc() {\n  // ponieważ to funkcja async, możemy użyć operatora await\n  return \"hello world\";\n}\n\nmyFunc().then(msg => console.log(msg)) // \"hello world\" -- wartość zwracana przez myFunc jest przekształcana w obietnicę ze względu na operator async\n```\n\nKiedy zostaje osiągnięte wyrażenie *return* w funkcji async, Obietnica zostaje wypełniona ze zwracaną wartością. Jeśli wewnątrz funkcji async pojawia się błąd, stan Obietnicy zmienia się na *odrzucony* (*rejected*). Jeśli funkcja async nie zwraca żadnej wartości, Obietnica zostanie zwrócona i wypełniona bez wartości, kiedy zakończy się wykonanie funkcji async.\n\n\nOperator *await* jest używany do oczekiwania na wypełnienie Obietnicy i może być użyty jedynie w ciele funkcji *async*. Kiedy zostanie osiągnięty, następuje wstrzymanie wypełnienia kodu do chwili wypełnienia obietnicy.\n\n> **Uwaga :** *fetch* to funkcja, która zwraca Obietnicę i pozwala na wykonania zapytania Ajax.\n\nRozpatrzmy przykład użycia fetch z obietnicami:\n\n```js\nfunction getGithubUser(username) {\n  return fetch(`https://api.github.com/users/${username}`).then(response => response.json());\n}\n\ngetGithubUser('mbeaudru')\n  .then(user => console.log(user))\n  .catch(err => console.log(err));\n```\n\nA oto ekwiwalent z *async / await*:\n\n```js\nasync function getGithubUser(username) { // dozwolone użycie obietnicy + await\n  const response = await fetch(`https://api.github.com/users/${username}`); // Wykonanie wstrzymane do czasu wypełnienia obietnicy fetch\n  return response.json();\n}\n\ngetGithubUser('mbeaudru')\n  .then(user => console.log(user))\n  .catch(err => console.log(err));\n```\n\nSkładnia *async / await* jest wyjątkowo użyteczna, gdy chcemy połączyć w łańcuch wzajemnie zależne od siebie obietnice.\n\nNa przykład, kiedy potrzebujemy tokena, by pobrać z bazy danych post na blogu i informacje o autorze:\n\n> **Uwaga :** wyrażenia *await* muszą być otoczone nawiasami, aby można było wezwać wartości ich metod i własności w jednej linijce.\n\n```js\nasync function fetchPostById(postId) {\n  const token = (await fetch('token_url')).json().token;\n  const post = (await fetch(`/posts/${postId}?token=${token}`)).json();\n  const author = (await fetch(`/users/${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##### <a name=\"error-handling\"></a>Obsługa błędów\n\nJeśli nie dodamy bloków *try / catch* wokół wyrażeń *await*, nieschwytane wyjątki - niezależnie od tego, czy pojawią się w ciele funkcji *async*, czy zostaną wstrzymane w czasie *await* - doprowadzą do odrzucenia obietnicy zwracanej przez funkcję *async*. Użycie wyrażenia `throw` w funkcji async sprowadza się do tego samego, co zwrot odrzuconej obietnicy. [(Ref: PonyFoo)](https://ponyfoo.com/articles/understanding-javascript-async-await#error-handling).  \n\n> **Uwaga :** Obietnice zachowują się tak samo!\n\nOto jak obsługujemy błędy z pomocą obietnic:\n\n```js\nfunction getUser() { // Obietnica będzie odrzucona!\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)); // \"User not found !\"\n```\n\nEkwiwalent z *async / await*:\n\n```js\nasync function getUser() { // Zwrócona obietnica zostanie odrzucona!\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)); // \"User not found !\"\n```\n\n#### <a name=\"external-resources-9\"></a>Dodatkowe źródła\n\n- [Async/Await - JavaScript.Info](https://javascript.info/async-await)\n- [ES7 Async/Await](http://rossboucher.com/await/#/)\n- [6 Reasons Why JavaScript’s Async/Await Blows Promises Away](https://hackernoon.com/6-reasons-why-javascripts-async-await-blows-promises-away-tutorial-c7ec10518dd9)\n- [JavaScript awaits](https://dev.to/kayis/javascript-awaits)\n- [Using Async Await in Express with Node 8](https://medium.com/@Abazhenov/using-async-await-in-express-with-node-8-b8af872c0016)\n- [Async Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)\n- [Await](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await)\n- [Using async / await in express with node 8](https://medium.com/@Abazhenov/using-async-await-in-express-with-node-8-b8af872c0016)\n\n### <a name=\"truthy--falsy\"></a>Prawda / fałsz\n\nW JavaScript wartości \"prawda\" lub \"fałsz\" określane są w kontekście boolowskim. Przykładem kontekstu boolowskiego może być określenie warunku ```if```: \n\nJako prawda (```true```) określona będzie każda wartość, jeśli nie jest równa:\n\n- ```false```\n- ```0```\n- ```\"\"``` (empty string)\n- ```null```\n- ```undefined```\n- ```NaN```\n\nPrzykłady *kontekstu boolowskiego*:\n\n- określenie warunku ```if```\n\n```js\nif (myVar) {}\n```\n\n```myVar``` może być dowolnym [obiektem pierwszoklasowym](https://en.wikipedia.org/wiki/First-class_citizen) (zmienna, funkcja, typ boolowski) ale będzie przekształcona w typ boolowski, ponieważ określana jest w kontekście boolowskim.\n\n- Po operatorze logicznym **NOT** ```!```\n\nThis operator returns false if its single operand can be converted to true; otherwise, returns true.\nOperator ten zwraca \"fałsz\" jeśli jego jedyny operand może być przekształcony w znaczenie \"prawda\"; w przeciwnym razie zwraca \"prawdę\"\n\n```js\n!0 // true -- 0 to \"fałsz\", więc zwraca \"prawdę\"\n!!0 // false -- 0 to \"fałsz\", więc !0 zwraca \"prawdę\", więc !(!0) zwraca \"fałsz\"\n!!\"\" // false -- pusty string to \"fałsz\", więc NOT (NOT false) równe jest \"fałszowi\"\n```\n\n- Z konstruktorem obiektu *Boolean*\n\n```js\nnew Boolean(0) // false\nnew Boolean(1) // true\n```\n\n- Z operatorem warunkowym\n\n```js\nmyVar ? \"prawda\" : \"fałsz\"\n```\n\nmyVar jest określana w kontekście boolowskim.\n\n```\n\n#### <a name=\"external-resources-10\"></a>Dodatkowe źródła\n\n- [Truthy (MDN)](https://developer.mozilla.org/en-US/docs/Glossary/Truthy)\n- [Falsy (MDN)](https://developer.mozilla.org/en-US/docs/Glossary/Falsy)\n- [Truthy and Falsy values in JS - Josh Clanton](http://adripofjavascript.com/blog/drips/truthy-and-falsy-values-in-javascript.html)\n\n### <a name=\"anamorphisms-and-catamorphisms\"></a>Anomorfizmy i katamorfizmy\n\n#### <a name=\"anamorphisms\"></a>Anamorfizmy\n\nAnamorfizmy to funkcje, które mapują pewien obiekt to bardziej złożonej struktury zawierającej typ tego obiektu. Jest to proces *rozwijania* (*unfolding*) prostej struktury do bardziej złożonej. Rozpatrzmy rozwijanie liczby całkowitej do listy liczb całkowitych. Początkowym obiektem jest liczba całkowita, bardziej złożoną strukturą - lista liczb całkowitych.\n\n**Przykładowy kod**\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  //=> [ 5, 4, 3, 2, 1 ]\n```\n\n#### <a name=\"catamorphisms\"></a>Katamorfizmy\n\nKatamorfizmy to przeciwieństwo anamorfizmów - \"zwijają\" bardziej skomplikowane struktury do prostszych. Przyjrzyjmy się funkcji `product`, która przyjmuje listę liczb całkowitych i zwraca pojedynczą liczbę całkowitą. \n\n**Przykładowy kod**\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)) // 120\n```\n\n#### <a name=\"external-resources-11\"></a>Dodatkowe źródła\n\n* [Anamorphisms in JavaScript](http://raganwald.com/2016/11/30/anamorphisms-in-javascript.html)\n* [Anamorphism](https://en.wikipedia.org/wiki/Anamorphism)\n* [Catamorphism](https://en.wikipedia.org/wiki/Catamorphism)\n\n### <a name=\"generators\"></a>Generatory\n\nInnym sposobem zapisania funkcji `downToOne` jest użycie Generatora. Stworzenie instancji obiektu `Generator` wymaga użycia deklaracji funkcji `function *`. Generatory to funkcje, które mogą być zamknięte i później uruchomione ponownie z zachowaniem kontekstu między kolejnymi uruchomieniami.\n\nNa przykład funkcja `downToOne` może być zapisana tak:\n\n```js\nfunction * downToOne(n) {\n  for (let i = n; i > 0; --i) {\n    yield i;\n  }\n}\n\n[...downToOne(5)] //[ 1, 2, 3, 4, 5 ]\n```\n\nGeneratory zwracają obiekt iterowalny. Kiedy wzywana jest funkcja iteratora `next()`, jest ona wykonywana aż do perwszego wyrażenia `yield`, które określa wartość, jaka zostanie zwrócona przez iterator lub z `yield*`, które odsyła do kolejnej funkcji-generatora. Jeśli w generatorze wezwane jest wyrażenie `return`, generator zostanie oznaczony jako wyczerpany i przekazany jako wartość do zwrotu. Kolejne wezwania `next()` nie zwrócą żadnych nowych wartości. \n\n**Przykładowy kod**\n\n```js\n// Przykład Yield\nfunction * idMaker() {\n  var index = 0;\n  while (index < 2) {\n    yield index;\n    index = index + 1;\n  }\n}\n\nvar gen = idMaker();\n\ngen.next().value; // 0\ngen.next().value; // 1\ngen.next().value; // undefined\n```\n\nWyrażenie `yield*` pozwala generatorowi wzywać inną funkcję-generator w czasie iteracji. \n\n```js\n// 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; // 10\ngen.next().value; // 11\ngen.next().value; // 12\ngen.next().value; // 13\ngen.next().value; // 20\n```\n\n```js\n// Przykład Generator Return\nfunction* yieldAndReturn() {\n  yield \"Y\";\n  return \"R\";\n  yield \"unreachable\";\n}\n\nvar gen = yieldAndReturn()\ngen.next(); // { value: \"Y\", done: false }\ngen.next(); // { value: \"R\", done: true }\ngen.next(); // { value: undefined, done: true }\n```\n\n#### <a name=\"external-resources-12\"></a>Dodatkowe źródła\n\n* [Mozilla MDN Web Docs, Iterators and Generators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators#Generators)\n\n### <a name=\"static-methods\"></a>Metody statyczne\n\n#### <a name=\"short-explanation-1\"></a>Krótkie wyjaśnienie\n\nSłowo kluczowe `static` jest używane w klasach dla deklaracji metod statycznych. Metody statyczne to funkcje klasy, które należą do obiektu klasy, ale nie są dostępne dla instancji tej klasy.\n\n#### <a name=\"sample-code-8\"></a>Przykładowy kod\n\n```js\nclass Repo{\n  static getName() {\n    return \"Repo name is modern-js-cheatsheet\"\n  }\n}\n\n//Zauważ, że nie musieliśmy tworzyć instancji klasy Repo\nconsole.log(Repo.getName()) //Repo name is modern-js-cheatsheet\n\nlet r = new Repo();\nconsole.log(r.getName()) //Nieprzechwycony TypeError: repo.getName nie jest funkcją\n```\n\n#### <a name=\"detailed-explanation-2\"></a>Szczegółowe wyjaśnienie\n\nMetody statyczne mogą być wezwane z innych metod statycznych za pomocą słowa kluczowego `this`, co nie działa w przypadku metod niestatycznych. Metody niestatyczne nie mają bezpośredniego dostępu do metod statycznych z użyciem `this`.\n\n##### <a name=\"calling-other-static-methods-from-a-static-method\"></a>Wzywanie innych metod statycznych z metod statycznych\n\nAby wezwać metodę statyczną z innej metody statycznej, należy użyć słowa kluczowego `this`:\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()) //Repo name is modern-js-cheatsheet-added-this\n```\n\n##### <a name=\"calling-static-methods-from-non-static-methods\"></a>Wzywanie metod statycznych z metod niestatycznych\n\nMetody niestatyczne mogą wzywać metody statyczne na dwa sposoby;\n1. ###### Używając nazwy klasy.\n\nAby zyskać dostęp do metody statycznej z metody niestatycznej używamy nazwy klasy i wzywamy metodę statyczną jak własność, np. `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// musimy stworzyć instancję klasy, by mieć dostęp do metod niestatycznych\nlet r = new Repo()\nconsole.log(r.useName()) //Repo name is modern-js-cheatsheet and it contains some really important stuff\n```\n\n2. ###### Używając konstruktora\n\nMetody statyczne mogą być wzywane jak własności na obiekcie konstruktora.\n\n```js\nclass Repo{\n  static getName() {\n    return \"Repo name is modern-js-cheatsheet\"\n  }\n\n  useName(){\n    //Wzywa metodę statyczną jako własność konstruktora\n    return this.constructor.getName() + ' and it contains some really important stuff'\n  }\n}\n\n// musimy stworzyć instancję klasy, by mieć dostęp do metod niestatycznych\nlet r = new Repo()\nconsole.log(r.useName()) //Repo name is modern-js-cheatsheet and it contains some really important stuff\n```\n\n#### <a name=\"external-resources-13\"></a>Dodatkowe źródła\n- [static keyword- MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/static)\n- [Static Methods- Javascript.info](https://javascript.info/class#static-methods)\n- [Static Members in ES6- OdeToCode](http://odetocode.com/blogs/scott/archive/2015/02/02/static-members-in-es6.aspx)\n\n## <a name=\"glossary\"></a>Słowniczek\n\n### <a name=\"-scope\"></a>Zakres widoczności (scope)\n\nKontekst, w którym wartości i wyrażenia są \"widoczne\" lub można się do nich odwoływać. Jeśli zmienna lub inne wyrażenie \"nie znajduje się w aktualnym zakresie widoczności\", oznacza to, że jest niedostępna do użytku.\n\nŹródło: [MDN](https://developer.mozilla.org/en-US/docs/Glossary/Scope)\n\n### <a name=\"-variable-mutation\"></a>Przekształcenie zmiennej (variable mutation)\n\nMówimy, że zmienna została przekształcona, kiedy jej wartość jest inna niż wartość początkowa.\n\n```js\nvar myArray = [];\nmyArray.push(\"firstEl\") // myArray została przekształcona\n```\n\nZmienna jest określana jako \"niemodyfikowalna\" (*immutable*), kiedy nie może być przekształcana.\n\n[Zobacz artykuł](https://developer.mozilla.org/en-US/docs/Glossary/Mutable).\n"
  },
  {
    "path": "translations/pt-BR.md",
    "content": "# Cheatsheet de JavaScript Moderno\n\n![Modern JavaScript cheatsheet](https://i.imgur.com/aexPxMb.png)\n<small>Crédito da Imagem: [Ahmad Awais ⚡️](https://github.com/ahmadawais)</small>\n\n## Introdução\n\n### Motivação\n\nEsse documento é um conjunto de \"cheatsheet\" para javascript que você frequentemente encontrará em projetos modernos e na maioria de exemplos de códigos atuais.\n\nEsse guia não tem a intenção de te ensinar Javascript do zero, mas sim ajudar desenvolvedores com conhecimentos básicos a se familiarizarem com códigos modernos.\n\nAlém disso, eu @mbeaudru ocasionalmente forneço dicas que podem ser discutidas, mas tomarei o cuidado de avisar quando eu fizer uma recomendação pessoal.\n\n> **Nota:** Muito dos conceitos apresentados aqui vem de uma atualização do Javascript (ES2015, chamada também de ES6). Você pode achar as novas funcionalidades adicionadas nessa atualização [aqui](http://es6-features.org).\n\n### Material Complementar\n\nSe você estiver com dificuldades em entender alguma coisa, eu sugiro que você procure por respostas nos seguintes lugares:\n\n- [MDN (Mozilla Developer Network)](https://developer.mozilla.org/fr/search?q=)\n- [You don't know JS (livro)](https://github.com/getify/You-Dont-Know-JS)\n- [ES6 Funcionalidades e exemplos](http://es6-features.org)\n- [WesBos blog (ES6)](http://wesbos.com/category/es6/)\n- [Reddit (JavaScript)](https://www.reddit.com/r/javascript/)\n- [Google](https://www.google.com/) para encontrar blogs e recursos específicos\n\n## Sumário\n\n- [Modern JavaScript cheatsheet](#modern-javascript-cheatsheet)\n  * [Introdução](#Introdução)\n    + [Motivação](#Motivação)\n    + [Material Complementar](#Material-Complementar)\n  * [Tabela de Conteúdos](#Sumário)\n  * [Noções](#Noções)\n    + [Declaração de variáveis: var, const, let](#declaração-de-variáveis-var-const-let)\n      - [Breve explicação](#breve-explicação)\n      - [Exemplo](#exemplo)\n      - [Explicação Detalhada](#explicação-detalhada)\n      - [Material Complementar](#material-complementar)\n    + [Função de Seta](#função-de-seta)\n      - [Exemplo](#exemplo-de-codigo)\n      - [Explicação Detalhada](#detailed-explanation-1)\n        * [Concisão](#concisão)\n        * [Referência *this*](#referência-this)\n      - [Material Útil](#material-útil)\n    + [Parametros padrão de uma Function](#parametros-padrão-de-uma-function)\n      - [Material Complementar](#material-complementar)\n    + [Desestruturação de objetos e arrays](#desestruturação-de-objetos-e-arrays)\n      - [Explicação com exemplo de código](#explicação-com-exemplo-de-código)\n      - [Material Útil](#material-útil-1)\n    + [Metodos de lista - map / filter / reduce](#array-methods---map--filter--reduce)\n      - [Exemplo](#sample-code-2)\n      - [Explicação](#explanation)\n        * [Array.prototype.map()](#arrayprototypemap)\n        * [Array.prototype.filter()](#arrayprototypefilter)\n        * [Array.prototype.reduce()](#arrayprototypereduce)\n      - [Material Complementar](#external-resource)\n    + [Spread operator \"...\"](#spread-operator-)\n      - [Exemplo](#sample-code-3)\n      - [Explicação](#explanation-1)\n        * [Em interações (como arrays)](#in-iterables-like-array)\n        * [Function rest parameter](#function-rest-parameter)\n        * [Object properties spreading](#object-properties-spreading)\n      - [Material Complementar](#external-resources)\n    + [Object property shorthand](#object-property-shorthand)\n      - [Explicação](#explanation-2)\n      - [Material Complementar](#external-resources-1)\n    + [Promises](#promises)\n      - [Exemplo](#sample-code-4)\n      - [Explicação](#explanation-3)\n        * [Criando uma promise](#create-the-promise)\n        * [Usando uma promise](#use-the-promise)\n      - [External Resources](#external-resources)\n    + [Template literals](#template-literals)\n      - [Sample code](#sample-code-5)\n      - [External resources](#external-resources-2)\n    + [Imports / Exports](#imports--exports)\n      - [Explanation with sample code](#explanation-with-sample-code-1)\n      - [External resources](#external-resources-3)\n    + [JavaScript *this*](#-javascript-this)\n      - [External resources](#external-resources-4)\n    + [Class](#class)\n      - [Samples](#samples)\n      - [External resources](#external-resources-5)\n    + [Async Await](#async-await)\n      - [Sample code](#sample-code-6)\n      - [Explanation](#explanation-4)\n      - [External resources](#external-resources-7)\n  * [Glossary](#glossary)\n    + [Scope](#-scope)\n    + [Variable mutation](#-variable-mutation)\n\n## Noções\n\n### Declaração de variáveis: var, const, let\n\nEm JavaScript, existem três palavras-chave disponíveis para declarar uma variável, e cada uma tem suas diferenças. São elas ```var```, ```let``` e ```const```.\n\n#### Breve explicação\n\nVariáveis declaradas com a palavra-chave ```const``` não podem ser reatribuídas, enquanto ```let``` e ```var``` podem.\n\nEu recomendo sempre declarar suas variáveis com ```const``` por padrão, e com ```let``` se você precisar *modifica-lo* ou reatribuí-lo mais tarde.\n\n<table>\n  <tr>\n    <th></th>\n    <th>Escopo</th>\n    <th>Reatribuível</th>\n    <th>Mutável</th>\n   <th><a href=\"#tdz_sample\">Zona Temporal Inoperante</a></th>\n  </tr>\n  <tr>\n    <th>const</th>\n    <td>Bloco</td>\n    <td>Não</td>\n    <td><a href=\"#const_mutable_sample\">Sim</a></td>\n    <td>Sim</td>\n  </tr>\n  <tr>\n    <th>let</th>\n    <td>Bloco</td>\n    <td>Sim</td>\n    <td>Sim</td>\n    <td>Sim</td>\n  </tr>\n   <tr>\n    <th>var</th>\n    <td>Função</td>\n    <td>Sim</td>\n    <td>Sim</td>\n    <td>Não</td>\n  </tr>\n</table>\n\n#### Exemplo\n\n```javascript\nconst person = \"Nick\";\nperson = \"John\" // Irá ocorrer um erro, person não pode ser reatribuída\n```\n\n```javascript\nlet person = \"Nick\";\nperson = \"John\";\nconsole.log(person) // \"John\", a reatribuição é permitida com let\n```\n\n#### Explicação Detalhada\n\nO [*escopo*](#scope_def) de uma variável grosseiramente significa \"onde esta variável está disponível no código\".\n\n##### var\n\nVariáveis declaradas com ```var``` são *função escopada*, significando que quando uma variável é criada em uma função, tudo naquela função pode acessar essa variável. Além disso, uma variável de *função escopada* criada em uma função não pode ser acessada fora desta função.\n\nEu recomendo que você imagine isso, como se uma variável *X escopada* significasse que essa variável era uma propriedade de X.\n\n```javascript\nfunction myFunction() {\n  var myVar = \"Nick\";\n  console.log(myVar); // \"Nick\" - myVar é acessível dentro da função.\n}\nconsole.log(myVar); // Lança um ReferenceError, myVar não está acessível fora da função.\n```\n\nAinda focado na variável de escopo, aqui está um exemplo mais sutil:\n\n```javascript\nfunction myFunction() {\n  var myVar = \"Nick\";\n  if (true) {\n    var myVar = \"John\";\n    console.log(myVar); // \"John\"\n    // na verdade, sendo myVar do escopo da função, nós simplesmente apagamos o valor anterior do myVar \"Nick\" para \"John\"\n  }\n  console.log(myVar); // \"John\" - veja como as instruções no bloco if afetaram esse valor\n}\nconsole.log(myVar); // Lança um ReferenceError, myVar não é acessível fora da função.\n```\n\nAlém disso, variáveis declaradas *var* são movidas para o topo do escopo na execução. É o que chamamos de [içando a var](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var#var_hoisting).\n\nEsta parte do código:\n\n```js\nconsole.log(myVar) // undefined -- sem erro lançado\nvar myVar = 2;\n```\n\né entendido na execução como:\n\n```js\nvar myVar;\nconsole.log(myVar) // undefined -- sem erro lançado\nmyVar = 2;\n```\n\n##### let\n\n```var``` e ```let ``` são quase os mesmos, mas variáveis declaradas com ```let```\n\n- são *escopado em bloco*\n- **não** são acessíveis antes de serem atribuídas\n- não podem ser re-declaradas no mesmo escopo\n\nVamos ver o impacto do escopo em bloco em nosso exemplo anterior:\n\n```javascript\nfunction myFunction() {\n  let myVar = \"Nick\";\n  if (true) {\n    let myVar = \"John\";\n    console.log(myVar); // \"John\"\n    // na verdade, myVar sendo escopada em bloco, nós criamos uma nova variável myVar.\n    // essa variável não é acessível fora do bloco e é totalmente independente\n    // da primeira myVar criada !\n  }\n  console.log(myVar); // \"Nick\", veja como as instruções no bloco IF NÃO afetou este valor\n}\nconsole.log(myVar); // lançado um ReferenceError, myVar não é acessível fora da fucnção.\n```\n\n<a name=\"tdz_sample\"></a> Agora, o que significa para as variáveis *let* (e *const*) não estarem acessíveis antes de serem atribuídas:\n\n```js\nconsole.log(myVar) // lança um ReferenceError !\nlet myVar = 2;\n```\n\nEm contraste com as variáveis *var*, se você tentar ler ou escrever em uma variável *let* ou *const* antes de serem atribuídos, um erro será gerado. Esse fenômeno é freqüentemente chamado [*Zona Temporal Inoperante*](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let#Temporal_Dead_Zone_and_errors_with_let) ou *TDZ*.\n\n> **Nota:** Tecnicamente, as declarações de *let* e *const* também estão sendo içadas, mas não a sua atribuição. Uma vez que elas são feitas para que elas não possam ser usados antes da atribuição, ela intuitivamente parece que não há içamento, mas existe. Saiba mais sobre isso [explicação muito detalhada aqui](http://jsrocks.org/2015/01/temporal-dead-zone-tdz-demystified) se quiser saber mais.\n\nAlém disso, você não pode re-declarar uma variável *let*:\n\n```js\nlet myVar = 2;\nlet myVar = 3; // Retorna um SyntaxError\n```\n\n##### const\n\nVariáveis declaradas ```const``` agem como variáveis *let*, mas elas não podem ser reatribuídas.\n\nPara resumir, variáveis *const*:\n\n- são *escopado em bloco*\n- não são acessíveis antes de serem atribuídos\n- não podem ser re-declaradas no mesmo escopo\n- não podem ser reatribuídas\n\n```js\nconst myVar = \"Nick\";\nmyVar = \"John\" // lança um erro, reatribuição não é permitido\n```\n\n```js\nconst myVar = \"Nick\";\nconst myVar = \"John\" // lança um erro, re-declaração não é permitida\n```\n\n<a name=\"const_mutable_sample\"></a> Mas há uma sutileza : variáveis ```const``` não são [**imutáveis**](#mutation_def) ! Concretamente, Isto significa que variáveis *objetos* e *arrays* declaradas com ```const``` **podem** ser mutadas.\n\nPara objetos:\n```js\nconst person = {\n  name: 'Nick'\n};\nperson.name = 'John' // isto irá funcionar! A variável objeto person não é completamente reatribuída, mas mutada\nconsole.log(person.name) // \"John\"\nperson = \"Sandra\" // lança um erro, porque a reatribuição não é permitida com variáveis declaradas com const\n```\n\nPara arrays:\n```js\nconst person = [];\nperson.push('John'); // isto irá funcionar! A variável array person não é completamente reatribuída, mas mutada\nconsole.log(person[0]) // \"John\"\nperson = [\"Nick\"] // lança um erro, porque a reatribuição não é permitida com variáveis declaradas com array\n```\n\n#### Material Complementar\n\n- [Como let e const são escopados em JavaScript - WesBos](http://wesbos.com/javascript-scoping/)\n- [Zona temporal Inoperante (TDZ) desmistificada](http://jsrocks.org/2015/01/temporal-dead-zone-tdz-demystified)\n\n### <a name=\"função-de-seta\"></a> Função de seta\n\nA atualização do JavaScript ES6 introduziu *funções de seta*, que é outra maneira de declarar e usar funções. Aqui estão os benefícios que elas trazem:\n\n- Mais conciso\n- *this* é retirado dos arredores\n- retorno implícito\n\n#### Exemplo de código\n\n- Concisão e retorno implícito\n\n```js\nfunction double(x) { return x * 2; } // Forma tradicional\nconsole.log(double(2)) // 4\n```\n\n```js\nconst double = x => x * 2; // A mesma função escrita como uma função de seta com retorno implícito\nconsole.log(double(2)) // 4\n```\n\n- Referência *this*\n\nEm uma função de seta, *this* é igual ao valor *this* do contexto de execução envolvente. Basicamente, com as funções de seta, você não precisa fazer o truque \"that/self = this\" antes de chamar uma função dentro de uma função.\n\n```js\nfunction myFunc() {\n  this.myVar = 0;\n  setTimeout(() => {\n    this.myVar++;\n    console.log(this.myVar) // 1\n  }, 0);\n}\n```\n\n#### Explicação detalhada\n\n##### Concisão\n\nAs funções de seta são mais concisas do que as funções tradicionais em diversas maneiras. Vamos rever todos os casos possíveis:\n\n- Retorno implícito VS explícito\n\nUm **retorno explícito** é uma função em que a palavra-chave *return* é usada em seu corpo.\n\n```js\n  function double(x) {\n    return x * 2; // esta função retorna explicitamente x * 2, a palavra-chave *retorno*  é usada\n  }\n```\n\nNa maneira tradicional de escrever funções, o retorno sempre foi explícito. Mas com funções de seta, você pode fazer *retorno implícito*, o que significa que você não precisa usar a palavra-chave *return* para retornar um valor.\n\n```js\n  const double = (x) => {\n    return x * 2; // um retorno explícito aqui\n  }\n```\n\nUma vez que esta função apenas retorna algo (sem instruções antes da palavra-chave *return*), podemos fazer um retorno implícito.\n\n```js\n  const double = (x) => x * 2; // Correto, retorna x*2\n```\n\nPara fazer isso, só precisamos **remover os colchetes** e a palavra-chave **return**. É por isso que é chamado de *retorno implícito*, a palavra-chave *return* não existe, mas essa função retornará ```x * 2```.\n\n> **Nota:** Se sua função não retornar um valor (com *efeitos colaterais*), ele não faz um retorno explícito nem implícito.\n\nAlém disso, se você quiser retornar implicitamente um *objeto*, você **deve ter parênteses em torno dele**, pois isso entrará em conflito com as chaves do bloco:\n\n```js\nconst getPerson = () => ({ name: \"Nick\", age: 24 })\nconsole.log(getPerson()) // { name: \"Nick\", age: 24 } -- objeto implicitamente retornado pela função de seta\n```\n\n- Só um argumento\n\nSe a sua função apenas tiver um parâmetro, você pode omitir os parênteses à sua volta. Se pegarmos o código *double* acima:\n\n```js\n  const double = (x) => x * 2; // esta função de seta apenas leva um parâmetro\n```\n\nParênteses ao redor do parâmetro podem ser evitados:\n\n```js\n  const double = x => x * 2; // esta função de seta tem apenas um parâmetro\n```\n\n- Nenhum argumento\n\nQuando não há argumento fornecido para uma função de seta, você precisa fornecer parênteses, ou não será uma sintaxe válida.\n\n```js\n  () => { // parênteses são fornecidos, tudo está ok\n    const x = 2;\n    return x;\n  }\n```\n\n```js\n  => { // Sem parênteses, isso não funcionará!\n    const x = 2;\n    return x;\n  }\n```\n\n##### Referência *this*\n\nPara entender essa sutileza introduzida com funções de seta, você deve saber como [this](#this_def) se comporta em JavaScript.\n\nEm funções de seta, *this* é igual ao valor *this* do contexto de execução envolvente. O que significa que uma função de seta não cria um novo *this*, Ela pega do seu entorno em vez disso.\n\nSem uma função de seta, se você quisesse acessar uma variável de *this* em uma função dentro de outra função, você tinha que usar *that = this* ou *self = this*.\n\nPor exemplo, usando a função setTimeout dentro de myFunc:\n\n```js\nfunction myFunc() {\n  this.myVar = 0;\n  var that = this; // that = this (truque)\n  setTimeout(\n    function() { // Um novo *this* é criado neste escopo de função\n      that.myVar++;\n      console.log(that.myVar) // 1\n\n      console.log(this.myVar) // undefined -- veja a declaração da função acima\n    },\n    0\n  );\n}\n```\n\nMas com função de seta, *this* é retirado do seu entorno:\n\n```js\nfunction myFunc() {\n  this.myVar = 0;\n  setTimeout(\n    () => { // this é retirado do entorno, o que significa de myFunc aqui\n      this.myVar++;\n      console.log(this.myVar) // 1\n    },\n    0\n  );\n}\n```\n\n#### Material Útil\n\n- [Arrow functions introduction (Introdução à Funções de Seta) - WesBos](http://wesbos.com/arrow-functions/)\n- [JavaScript arrow function - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions)\n- [Arrow function and lexical *this*](https://hackernoon.com/javascript-es6-arrow-functions-and-lexical-this-f2a3e2a5e8c4)\n\n### Parametros padrão de uma Function\n\nA partir da atualização do JavaScript ES2015, você pode definir um valor padrão para os parâmetros da função usando a seguinte sintaxe:\n\n```js\nfunction myFunc(x = 10) {\n  return x;\n}\nconsole.log(myFunc()) // 10 -- nenhum valor é fornecido então o valor padrão de x que é 10 será atribuído a x em myFunc\nconsole.log(myFunc(5)) // 5 -- um valor é fornecido então x é igual a 5 em myFunc\n\nconsole.log(myFunc(undefined)) // 10 -- um valor undefined é fornecido então o valor padrão é atribuído para x\nconsole.log(myFunc(null)) // null -- um valor (null) é fornecido, veja abaixo para mais detalhes neste caso\n```\n\nO valor de parâmetro padrão é aplicado em duas e somente duas situações:\n\n- Nenhum parâmetro fornecido\n- *undefined* parâmetro fornecido\n\nEm outras palavras, se você passar um *null* o parâmetro padrão **não irá ser aplicado**.\n\n> **Nota:** Atribuição de valor padrão também pode ser usada com parâmetros desestruturados (veja o próximo conceito para ver um exemplo)\n\n#### Material Complementar\n\n- [Default parameter value - ES6 Features](http://es6-features.org/#DefaultParameterValues)\n- [Default parameters - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters)\n\n### Desestruturação de objetos e arrays\n\n*Desestruturação* é uma maneira conveniente de criar novas variáveis extraindo alguns valores de dados armazenados em objetos ou arrays (matrizes).\n\nPara nomear alguns casos de uso, *desestruturação* pode ser usado para desestruturar parâmetros de função ou *this.props* em projetos React, por exemplo.\n\n#### Explicação com exemplo de código\n\n- Objeto\n\nVamos considerar o seguinte objeto para todos os exemplos:\n\n```js\nconst person = {\n  firstName: \"Nick\",\n  lastName: \"Anderson\",\n  age: 35,\n  sex: \"M\"\n}\n```\n\nSem desestruturação\n\n```js\nconst first = person.firstName;\nconst age = person.age;\nconst city = person.city || \"Paris\";\n```\n\nCom desestruturação, tudo em uma única linha:\n\n```js\nconst { firstName: first, age, city = \"Paris\" } = person; // É isso ! :)\n\nconsole.log(age) // 35 -- uma nova variável age é criada e é igual a person.age\nconsole.log(first) // \"Nick\" -- uma nova variável first é criada e é igual person.firstName\nconsole.log(firstName) // ReferenceError -- person.firstName existe MAS a nova variável criada é nomeada primeiro\nconsole.log(city) // \"Paris\" -- uma nova variável city é criada e uma vez que person.city é indefinida, city é igual ao valor padrão fornecido \"Paris\".\n```\n\n**Nota :** Em ```const { age } = person;```, os colchetes depois da palavra-chave *const* não são usados para declarar um objeto nem um bloco, mas é a sintaxe da *desestruturação*.\n\n- Parâmetros de função\n\n*Desestruturação* é freqüentemente usado para desestruturar parâmetros de objetos em funções.\n\nSem desestruturação\n\n```js\nfunction joinFirstLastName(person) {\n  const firstName = person.firstName;\n  const lastName = person.lastName;\n  return firstName + '-' + lastName;\n}\n\njoinFirstLastName(person); // \"Nick-Anderson\"\n```\n\nAo desestruturar o parâmetro de objeto *person*, obtemos uma função mais concisa:\n\n```js\nfunction joinFirstLastName({ firstName, lastName }) { // criamos variáveis firstName e lastName por desestruturação person parameter\n  return firstName + '-' + lastName;\n}\n\njoinFirstLastName(person); // \"Nick-Anderson\"\n```\n\nA desestruturação é ainda mais agradável para usar com [funções de seta] (#função-de-seta):\n\n```js\nconst joinFirstLastName = ({ firstName, lastName }) => firstName + '-' + lastName;\n\njoinFirstLastName(person); // \"Nick-Anderson\"\n```\n\n- Array (Matriz)\n\nVamos considerar a seguinte array:\n\n```js\nconst myArray = [\"a\", \"b\", \"c\"];\n```\n\nSem desestruturação\n\n```js\nconst x = myArray[0];\nconst y = myArray[1];\n```\n\nCom desestruturação\n\n```js\nconst [x, y] = myArray; // É isso !\n\nconsole.log(x) // \"a\"\nconsole.log(y) // \"b\"\n```\n\n#### Material Útil\n\n- [ES6 Features - Destructuring Assignment (Funcionalidades ES6 - Atribuição de Destruturação)](http://es6-features.org/#ArrayMatching)\n- [Destructuring Objects - WesBos](http://wesbos.com/destructuring-objects/)\n- [ExploringJS - Destructuring](http://exploringjs.com/es6/ch_destructuring.html)"
  },
  {
    "path": "translations/ru-RU.md",
    "content": "# Памятка по современному JavaScript\n![Памятка по современному JavaScript](https://i.imgur.com/aexPxMb.png)\n<small>За картинку спасибо [Ahmad Awais ⚡️](https://github.com/ahmadawais)</small>\n\n## Введение\n\n### Мотивация\nВ этом документе собраны возможности языка JavaScript, с которыми вы наверняка столкнетесь в современных проектах и примерах кода.\n\nЦель этого руководства — не обучить вас JavaScript с нуля, а помочь разработчикам с базовыми знаниями, которые при изучении современных кодовых баз (или, скажем, React) сталкиваются со сложностями из-за использованных в них концепций JavaScript.\n\nИногда я буду давать личные советы, которые могут быть спорными, но постараюсь упоминать, что это личное мнение.\n> **Примечание:** Большинство представленных здесь понятий взяты из обновления языка JavaScript (ES2015, которое часто называют ES6). Вы можете найти новые возможности из этого обновления [здесь](http://es6-features.org); они хорошо описаны.\n\n### Дополнительные ресурсы\nЕсли вам сложно разобраться с каким-то понятием, рекомендую искать ответы на вопросы на следующих ресурсах:\n- [MDN (сеть разработчиков Mozilla)](https://developer.mozilla.org/ru/search?q=).\n- [Вы не знаете JS (серия книг)](https://github.com/azat-io/you-dont-know-js-ru).\n- [ES6 Features with examples](http://es6-features.org).\n- [Блог WesBos (ES6)](http://wesbos.com/category/es6/).\n- [Javascript Basics for Beginners](https://www.udacity.com/course/javascript-basics--ud804) — бесплатный курс от Udacity.\n- [Reddit (JavaScript)](https://www.reddit.com/r/javascript/).\n- [Google](https://www.google.com/) для поиска специализированных блогов и ресурсов.\n- [StackOverflow](https://stackoverflow.com/questions/tagged/javascript).\n\n## Содержание\n- [Памятка по современному JavaScript](#Памятка-по-современному-javascript)\n  * [Введение](#Введение)\n    + [Мотивация](#Мотивация)\n    + [Дополнительные ресурсы](#Дополнительные-ресурсы)\n  * [Содержание](#Содержание)\n  * [Понятия](#Понятия)\n    + [Объявление переменных: `var`, `const`, `let`](#Объявление-переменных-var-const-let)\n      - [Краткое объяснение](#Краткое-объяснение)\n      - [Пример кода](#Пример-кода)\n      - [Подробное объяснение](#Подробное-объяснение)\n      - [Дополнительные материалы](#Дополнительные-материалы)\n    + [Стрелочные функции](#-Стрелочные-функции)\n      - [Пример кода](#Пример-кода-1)\n      - [Подробное объяснение](#Подробное-объяснение-1)\n        * [Краткость](#Краткость)\n        * [Использование `this`](#Использование-this)\n      - [Полезные ресурсы](#Полезные-ресурсы)\n    + [Значение аргументов функции по умолчанию](#Значение-аргументов-функции-по-умолчанию)\n      - [Дополнительные материалы](#Дополнительные-материалы-1)\n    + [Деструктуризация объектов и массивов](#Деструктуризация-объектов-и-массивов)\n      - [Объяснение с помощью примера кода](#Объяснение-с-помощью-примера-кода)\n      - [Полезные ресурсы](#Полезные-ресурсы-1)\n    + [Методы массивов - `map` / `filter` / `reduce`](#Методы-массивов--map--filter--reduce)\n      - [Пример кода](#Пример-кода-2)\n      - [Объяснение](#Объяснение)\n        * [`Array.prototype.map()`](#arrayprototypemap)\n        * [`Array.prototype.filter()`](#arrayprototypefilter)\n        * [`Array.prototype.reduce()`](#arrayprototypereduce)\n      - [Дополнительные материалы](#Дополнительные-материалы-2)\n    + [Оператор расширения `...`](#Оператор-расширения-)\n      - [Пример кода](#Пример-кода-3)\n      - [Объяснение](#Объяснение-1)\n        * [В итерируемых объектах (например, массивах)](#В-итерируемых-объектах-например-массивах)\n        * [Оставшиеся аргументы функции](#Оставшиеся-аргументы-функции)\n        * [Расширение свойств объектов](#Расширение-свойств-объектов)\n      - [Дополнительные материалы](#Дополнительные-материалы-3)\n    + [Сокращенная запись свойств объектов](#Сокращенная-запись-свойств-объектов)\n      - [Объяснение](#Объяснение-2)\n      - [Дополнительные материалы](#Дополнительные-материалы-4)\n    + [Промисы](#Промисы)\n      - [Пример кода](#Пример-кода-4)\n      - [Пояснение](#Пояснение)\n        * [Создание промиса](#Создание-промиса)\n        * [Использование обработчиков промисов](#Использование-обработчиков-промисов)\n      - [Дополнительные материалы](#Дополнительные-материалы-5)\n    + [Шаблонные строки](#Шаблонные-строки)\n      - [Пример кода](#Пример-кода-5)\n      - [Дополнительные материалы](#Дополнительные-материалы-6)\n    + [Тегированные шаблонные строки](#Тегированные-шаблонные-строки)\n      - [Дополнительные материалы](#Дополнительные-материалы-7)\n    + [Импорт / экспорт](#Импорт--экспорт)\n      - [Объяснение с помощью примера кода](#Объяснение-с-помощью-примера-кода)\n        * [Именованный экспорт](#Именованный-экспорт)\n        * [Импорт / экспорт по умолчанию](#Импорт--экспорт-по-умолчанию)\n      - [Дополнительные материалы](#Дополнительные-материалы-8)\n    + [`this` в JavaScript](#-this-в-javascript)\n      - [Дополнительные материалы](#Дополнительные-материалы-9)\n    + [Класс](#Класс)\n      - [Примеры](#Примеры)\n      - [Дополнительные материалы](#Дополнительные-материалы-10)\n    + [Ключевые слова Extends и super](#Ключевые-слова-extends-и-super)\n      - [Пример кода](#Пример-кода-6)\n      - [Дополнительные материалы](#Дополнительные-материалы-11)  \n    + [Async Await](#async-await)\n      - [Пример кода](#Пример-кода-7)\n      - [Объяснение с помощью примера кода](#Объяснение-с-помощью-примера-кода-1)\n      - [Обработка ошибок](#Обработка-ошибок)\n      - [Дополнительные материалы](#Дополнительные-материалы-12)\n    + [Истина / Ложь](#Истина--Ложь)\n      - [Дополнительные материалы](#Дополнительные-материалы-13)\n    + [Анаморфизмы и катаморфизмы](#Анаморфизмы-и-катаморфизмы)\n      - [Анаморфизмы](#Анаморфизмы)\n        * [Пример кода](#Пример-кода-8)\n      - [Катаморфизмы](#Катаморфизмы)\n        * [Пример кода](#Пример-кода-9)\n      - [Дополнительные материалы](#Дополнительные-материалы-14)\n    + [Генераторы](#Генераторы)\n      - [Пример кода](#Пример-кода-10)\n      - [Дополнительные материалы](#Дополнительные-материалы-15)  \n    + [Статические методы](#Статические-методы)\n      - [Краткое объяснение](#Краткое-объяснение-1)\n      - [Пример кода](#Пример-кода-11)\n      - [Подробное объяснение](#Подробное-объяснение-2)\n        * [Вызов статических методов из статического метода](#Вызов-статических-методов-из-статического-метода)\n        * [Вызов статических методов из нестатических методов](#Вызов-статических-методов-из-нестатических-методов)\n      - [Дополнительные материалы](#Дополнительные-материалы-16)\n  * [Глоссарий](#Глоссарий)\n    + [Область видимости](#-Область-видимости)\n    + [Изменение переменных](#-Изменение-переменных)\n\n## Понятия\n\n### Объявление переменных: `var`, `const`, `let`\nВ JavaScript есть три ключевых слова, отвечающих за объявление переменных, и у каждого из них свои особенности. Эти слова − `var`, `let` и `const`.\n\n#### Краткое объяснение\nПеременным, объявленным с помощью ключевого слова `const`, нельзя позже присвоить новое значение, в то время как переменным, объявленным с помощью `let` или `var`, можно.\n\nЯ рекомендую всегда объявлять переменные ключевым словом `const`, а `let` использовать только в том случае, если позже эту переменную понадобится *изменить* или переопределить.\n<table>\n<tr>\n<th></th>\n<th>Область видимости</th>\n<th>Можно переопределять</th>\n<th>Можно изменять</th>\n<th><a href=\"#tdz_sample\">Временная мертвая зона</a></th>\n</tr>\n<tr>\n<th>const</th>\n<td>Блок</td>\n<td>Нет</td>\n<td><a href=\"#const_mutable_sample\">Да</a></td>\n<td>Да</td>\n</tr>\n<tr>\n<th>let</th>\n<td>Блок</td>\n<td>Да</td>\n<td>Да</td>\n<td>Да</td>\n</tr>\n<tr>\n<th>var</th>\n<td>Функция</td>\n<td>Да</td>\n<td>Да</td>\n<td>Нет</td>\n</tr>\n</table>\n\n#### Пример кода\n```js\nconst person = \"Коля\";\nperson = \"Ваня\" // Вызовет ошибку, переменной person нельзя присвоить новое значение.\n```\n```js\nlet person = \"Коля\";\nperson = \"Ваня\";\nconsole.log(person) // -> \"Ваня\", присвоение нового значения разрешено в случае с let.\n```\n\n#### Подробное объяснение\n[*Область видимости*](#scope_def) переменной определяет, где эта переменная доступна в коде.\n\n##### `var`\nОбластью видимости переменных, объявленных с помощью `var`, является функция. Это означает, что если переменная была создана внутри функции, то у всего внутри этой функции есть доступ к данной переменной. Кроме того, переменная с областью видимости внутри функции недоступна за пределами этой функции.\n\nМожно думать об этом вот так: если у переменной область видимости *Х*, то эта переменная — как бы свойство Х.\n```js\nfunction myFunction() {\n  var myVar = \"Коля\";\n  console.log(myVar); // -> \"Коля\" — myVar доступна внутри функции.\n}\nconsole.log(myVar); // ReferenceError, myVar недоступна снаружи функции.\n```\nВот менее очевидный пример области видимости переменных:\n```js\nfunction myFunction() {\n  var myVar = \"Коля\";\n  if (true) {\n      var myVar = \"Ваня\";\n      console.log(myVar); // -> \"Ваня\"\n      /* На самом деле, область видимости myVar — функция,\n      мы всего лишь удалили предыдущее значение переменной myVar \"Коля\"\n      и заменили его на \"Ваня\". */\n    }\n    console.log(myVar); // -> \"Ваня\" — обратите внимание, как код в блоке if повлиял на это значение.\n  }\n  console.log(myVar); // ->  \n  /* ReferenceError, переменная myVar недоступна\n  за пределами функции, в которой определена. */\n```\nКроме этого, переменные, объявленные с помощью ключевого слова `var`, при выполнении кода перемещаются в начало области видимости. Это называется [поднятие переменных](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Statements/var#Поднятие_переменных).\n\nЭтот фрагмент кода:\n```js\nconsole.log(myVar) // -> undefined — ошибок нет.\nvar myVar = 2;\n```\nпри выполнении понимается как:\n```js\nvar myVar;\nconsole.log(myVar) // -> undefined — ошибок нет.\nmyVar = 2;\n```\n\n##### `let`\n`var` и `let` примерно одинаковы, в то время как переменные, объявленные словом `let`:\n- имеют в качестве области видимости блок;\n- **недоступны** до объявления;\n- не могут быть повторно объявлены в той же области видимости.\n\nДавайте разберемся, в чем особенности блочной области видимости, используя предыдущий пример:\n```js\nfunction myFunction() {\n  let myVar = \"Коля\";\n  if (true) {\n    let myVar = \"Ваня\";\n    console.log(myVar); // -> \"Ваня\"\n    /* Поскольку myVar имеет блочную область видимости,\n    здесь мы только что создали новую переменную myVar.\n    Эта переменная недоступна вне блока и никак не зависит\n    от первой переменной myVar, которую мы создали до этого! */\n  }\n  console.log(myVar); // -> \"Коля\" — обратите внимание: инструкции в блоке if НЕ повлияли на значение переменной.\n}\nconsole.log(myVar); // -> ReferenceError, myVar недоступна за пределами функции.\n```\n<a name=\"tdz_sample\"></a> Теперь разберемся, что значит «переменные, объявленные с помощью `let` и `const`, недоступны до их объявления»:\n```js\nconsole.log(myVar) // Вызовет ReferenceError!\nlet myVar = 2;\n```\nВ отличие от переменных, объявленных через `var`, попытка обратиться к переменной `let` или `const` до её объявления вызовет ошибку. Этот феномен часто называют  [*Временной мёртвой зоной*](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let#Temporal_Dead_Zone_and_errors_with_let).  \n> **Примечание:** строго говоря, объявления переменных с использованием `let` и `const` тоже поднимаются, однако их инициализация — нет. Они сделаны так, что использовать их до инициализации нельзя. Поэтому интуитивно кажется, что такие переменные не поднимаются, но на самом деле это не так. Больше информации можно найти в [этом очень подробном объяснении](http://jsrocks.org/2015/01/temporal-dead-zone-tdz-demystified).\n\nВ дополнение к сказанному: нельзя повторно объявить переменную, объявленную с помощью `let`:\n```js\nlet myVar = 2;\nlet myVar = 3; // Вызовет SyntaxError.\n```\n\n##### `const`\nПеременные, объявленные через `const`, ведут себя так же, как переменные, объявленные через `let`, но к тому же их нельзя переопределять.\n\nИтак, переменные, объявленные с помощью `const`:\n- имеют в качестве области видимости блок;\n- недоступны до объявления;\n- не могут быть повторно объявлены в той же области видимости;\n- не могут быть переопределены.\n```js\nconst myVar = \"Коля\";\nmyVar = \"Ваня\" // Вызовет ошибку, переопределять переменную нельзя.\n```\n```js\nconst myVar = \"Коля\";\nconst myVar = \"Ваня\" // Вызовет ошибку, объявить переменную можно только один раз.\n```\n<a name=\"const_mutable_sample\"></a> Но есть одна тонкость: переменные, объявленные с помощью `const`, не являются [**неизменными**](#mutation_def)! А именно, это означает, что *объекты* и *массивы*, объявленные с помощью `const`, **могут** быть изменены.\n\nВ случае объектов:\n```js\nconst person = {\n  name: 'Коля',\n};\nperson.name = 'Ваня'; // Сработает! Переменная person не полностью переопределяется, а просто меняется.\nconsole.log(person.name); // -> \"Ваня\"\nperson = \"Сандра\"; // Вызовет ошибку, потому что переменные, объявленные через const, переопределять нельзя.\n```\nВ случае массивов:\n```js\nconst person = [];\nperson.push('Ваня'); // Сработает!  Переменная person не полностью переопределяется, а просто меняется.\nconsole.log(person[0]); // -> \"Ваня\"\nperson = [\"Коля\"]; // Вызовет ошибку, потому что переменные, объявленные через const, переопределять нельзя.\n```\n\n#### Дополнительные материалы\n- [How let and const are scoped in JavaScript — WesBos](http://wesbos.com/javascript-scoping/).\n- [Temporal dead zone (tdz) demystified](http://jsrocks.org/2015/01/temporal-dead-zone-tdz-demystified).\n\n### <a name=\"arrow_func_concept\"></a> Стрелочные функции\nВ обновлении JavaScript ES6 добавлены *стрелочные функции* — новый синтаксис записи функций. Вот некоторые их преимущества:\n- краткость;\n- `this` берется из окружающего контекста;\n- неявный возврат.\n\n#### Пример кода\n- Краткость и неявный возврат.\n```js\nfunction double(x) { return x * 2; } // Обычный способ.\nconsole.log(double(2)); // -> 4\n```\n```js\nconst double = x => x * 2; /* Та же функция, записанная в виде стрелочной функции с неявным возвратом. */\nconsole.log(double(2)); // -> 4\n```\n- Использование `this`.\n\nВнутри стрелочной функции значение `this` такое же, как и во внешней области видимости. В принципе, со стрелочными функциями вам больше не нужно прибегать к хаку `that = this` перед вызовом функции внутри функции.\n```js\nfunction myFunc() {\n  this.myVar = 0;\n  setTimeout(() => {\n    this.myVar++;\n    console.log(this.myVar); // -> 1\n  }, 0);\n}\n```\n\n#### Подробное объяснение\n\n##### Краткость\nСтрелочные функции во многих отношениях более краткие, чем обычные. Рассмотрим все возможные случаи:\n- Явный и неявный возврат.\n\nФункция может **явно возвращать** результат с использованием ключевого слова `return`.\n```js\nfunction double(x) {\n  return x * 2; // Эта функция явно возвращает x * 2, использовано ключевое слово *return*.\n}\n```\nПри обычном способе написания функций возврат всегда был явным. Со стрелочными функциями его можно сделать *неявным*. Это значит, что для возврата значения не нужно использовать ключевое слово `return`.\n\n```js\nconst double = (x) => {\n  return x * 2; // Явный возврат.\n}\n```\nПоскольку здесь нет ничего, кроме возвращаемого значения, можно вернуть значение без явного указания.\n```js\nconst double = (x) => x * 2; // Всё верно, вернётся x * 2.\n```\nДля этого нам просто нужно **убрать фигурные скобки** и ключевое слово `return`. Поэтому это и называется *неявным* возвратом: ключевого слова `return` нет, но функция все равно вернет `x * 2`.\n> **Примечание**: Если ваша функция не возвращает никакого значения (с *побочными эффектами*), то в ней нет ни явного, ни неявного возврата.\n\nКроме того, если вы хотите неявно вернуть *объект*, вы **должны заключить его в круглые скобки**, так как иначе он будет конфликтовать с фигурными скобками блоков:\n```js\nconst getPerson = () => ({ name: \"Коля\", age: 24 })\nconsole.log(getPerson())\n// { name: \"Коля\", age: 24 } — объект, неявно возвращенный стрелочной функцией.\n```\n\n- Только один аргумент.\n\nЕсли ваша функция принимает только один аргумент, то скобки вокруг него можно опустить. Возвращаясь к функции `double` в коде выше:  \n```js\nconst double = (x) => x * 2; // Эта стрелочная функция принимает только один аргумент.\n```\nСкобки вокруг этого аргумента можно опустить:\n```js\nconst double = x => x * 2; // Эта стрелочная функция принимает только один аргумент.\n```\n- Без аргументов.\n\nКогда стрелочная функция вообще не принимает никаких аргументов, нужно использовать пустые круглые скобки, иначе синтаксис будет неправильным.\n```js\n() => { // Скобки есть, все хорошо.\n  const x = 2;\n  return x;\n}\n```\n```js\n=> { // Скобок нет, так работать не будет!\n  const x = 2;\n  return x;\n}\n```\n\n##### Использование `this`\nЧтобы понять эту тонкость поведения стрелочных функций, нужно понимать, как [`this`](#this_def) ведёт себя в JavaScript.\n\nВнутри стрелочной функции значение `this` равно значению `this` внешнего окружения. Это значит, что стрелочная функция не создает новый `this`, а получает его из окружения.\n\nБез использования стрелочных функций для получения доступа к переменной через `this` в функции, вложенной в другую функцию, придется использовать хак `that = this` или `self = this`.\n\nВот, к примеру, использование функции `setTimeout` внутри функции `myFunc`:\n```js\nfunction myFunc() {\n  this.myVar = 0;\n  var that = this; // Тот самый хак *that = this*\n  setTimeout(\n    function() { // В этой области видимости функции создается новый *this*.\n      that.myVar++;\n      console.log(that.myVar); // -> 1\n      console.log(this.myVar); // -> undefined — см. объявление функции выше.\n    },\n    0\n  );\n}\n```\nНо в случае стрелочных функций `this` берется из окружения:\n```js\nfunction myFunc() {\n  this.myVar = 0;\n  setTimeout(\n    () => { // this берется из окружения. В данном случае — из myFunc.\n      this.myVar++;\n      console.log(this.myVar); // -> 1\n    },\n    0\n  );\n}\n```\n\n#### Полезные ресурсы\n- [JavaScript Arrow Functions Introduction — WesBos](http://wesbos.com/arrow-functions/).\n- [Стрелочные функции в JavaScript — MDN](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Functions/Arrow_functions).\n- [Javascript ES6 — Arrow Functions and Lexical `this`](https://hackernoon.com/javascript-es6-arrow-functions-and-lexical-this-f2a3e2a5e8c4).\n\n### Значение аргументов функции по умолчанию\nНачиная с обновления JavaScript ES2015, аргументам функции можно присваивать значения по умолчанию, используя следующий синтаксис:\n```js\nfunction myFunc(x = 10) {\n  return x;\n}\nconsole.log(myFunc()); /* -> 10 — никакое значение не передается,\nпоэтому в myFunc х присваивается значение по умолчанию, т.е. 10 */\nconsole.log(myFunc(5)); /* -> 5 — передается значение,\nпоэтому в myFunc х присваивается значение 5 */\n\nconsole.log(myFunc(undefined)); /* -> 10 — передается значение undefined,\nпоэтому х присваивается значение по умолчанию */\nconsole.log(myFunc(null)); // -> null — передается значение null. Подробнее см. ниже.\n```\nЗначения по умолчанию применяются только в двух случаях:\n- значение не передано;\n- передано значение `undefined`.\n\nДругими словами, если передать в функцию параметр `null`, то параметр по умолчанию **не применится**.\n> **Примечание:** Присваивать значение по умолчанию можно в том числе и при работе с деструктурированными параметрами (см. пример в следующем понятии).\n\n#### Дополнительные материалы\n- [Extended Parameter Handling](http://es6-features.org/#DefaultParameterValues).\n- [Параметры по умолчанию — MDN](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Functions/Default_parameters).\n\n### Деструктуризация объектов и массивов\n**Деструктуризация** — это удобный способ создания новых переменных путем извлечения значений из объектов или массивов.\n\nНа практике *деструктуризацию* можно использовать, чтобы присваивать переменным разбитые на части параметры функции или `this.props` в React-проектах.\n\n#### Объяснение с помощью примера кода\n- Объект.\n\nДавайте использовать во всех примерах следующий объект:\n```js\nconst person = {\n  firstName: \"Коля\",\n  lastName: \"Андреев\",\n  age: 35,\n  sex: \"М\",\n};\n```\nБез деструктуризации:\n```js\nconst first = person.firstName;\nconst age = person.age;\nconst city = person.city || \"Санкт-Петербург\";\n```\nС деструктуризацией всё поместится в одну строку:\n```js\nconst { firstName: first, age, city = \"Санкт-Петербург\" } = person; // И всё!\nconsole.log(age); /* -> 35 — Создана новая переменная age,\nи ей присвоено значение, равное person.age. */\nconsole.log(first); /* -> \"Коля\" — Создана новая переменная first,\nи ей присвоено значение, равное person.firstName. */\nconsole.log(firstName); /* -> ReferenceError — person.firstName существует,\nНО новая созданная переменная называется first. */\nconsole.log(city); /* -> \"Санкт-Петербург\" — Создана новая переменная city,\nи, поскольку свойство person.city ранее не было определено,\nпеременной присвоено альтернативное значение \"Санкт-Петербург\". */\n```\n> **Примечание:** В `const { age } = person;` скобки после ключевого слова `const` используются не для обозначения объекта или блока. Это синтаксис *деструктуризации*.\n\n- Параметры функции.\n\nДеструктуризация часто используется для разбиения параметров функции на части.\n\nБез деструктуризации:\n```js\nfunction joinFirstLastName(person) {\n  const firstName = person.firstName;\n  const lastName = person.lastName;\n  return `${firstName}—${lastName}`;\n}\njoinFirstLastName(person); // -> \"Коля-Андреев\"\n```\nЕсли деструктурировать параметр `person`, то функция получится куда более лаконичной:\n```js\nfunction joinFirstLastName({ firstName, lastName }) { /* Мы создали переменные firstName и lastName\n  из частей параметра person. */\n  return `${firstName}—${lastName}`;\n}\njoinFirstLastName(person); // -> \"Коля-Андреев\"\n```\nЕщё удобнее использовать деструктуризацию со [стрелочными функциями](#arrow_func_concept):\n```js\nconst joinFirstLastName = ({ firstName, lastName }) => `${firstName}—${lastName}`;\njoinFirstLastName(person); // -> \"Коля-Андреев\"\n```\n- Массив.\n\nДавайте рассмотрим следующий массив:\n```js\nconst myArray = [\"a\", \"b\", \"c\"];\n```\nБез деструктуризации:\n```js\nconst x = myArray[0];\nconst y = myArray[1];\n```\nС использованием деструктуризации:\n```js\nconst [x, y] = myArray; // Вот и всё!\n\nconsole.log(x); // -> \"a\"\nconsole.log(y); // -> \"b\"\n```\n\n#### Полезные ресурсы\n- [Destructuring Assignment](http://es6-features.org/#ArrayMatching).\n- [Destructuring Assignment - WesBos](http://wesbos.com/destructuring-objects/).\n- [ExploringJS — Destructuring](http://exploringjs.com/es6/ch_destructuring.html).\n\n### Методы массивов — `map` / `filter` / `reduce`\n`map`, `filter` и `reduce` — это методы массивов, пришедшие из парадигмы [*функционального программирования*](https://medium.com/javascript-scene/master-the-javascript-interview-what-is-functional-programming-7f218c68b3a0).\n\nПеречислю их:\n- `Array.prototype.map()` принимает массив, каким-нибудь образом преобразует его элементы и возвращает новый массив трансформированных элементов.\n- `Array.prototype.filter()` принимает массив, просматривает каждый элемент и решает, убрать его или оставить. Возвращает массив оставшихся значений.\n- `Array.prototype.reduce()` принимает массив и вычисляет на основе его элементов какое-то единое значение, которое и возвращает.\n\nЯ рекомендую пользоваться ими как можно чаще, следуя принципам функционального программирования, потому что они лаконичные, элегантные и их можно комбинировать.\n\nВооружившись этими тремя методами, вы можете обойтись без использования `for` и `forEach` в большинстве ситуаций. Когда в следующий раз соберётесь запустить цикл `for`, попробуйте решить задачу с помощью `map`, `filter` и `reduce`. Поначалу это будет трудно, потому что вам придётся научиться мыслить по-другому, но, разобравшись один раз, вы сможете применять эти методы без особых усилий.\n\n#### Пример кода\n```js\nconst numbers = [0, 1, 2, 3, 4, 5, 6];\nconst doubledNumbers = numbers.map(n => n * 2); // -> [0, 2, 4, 6, 8, 10, 12]\nconst evenNumbers = numbers.filter(n => n % 2 === 0); // -> [0, 2, 4, 6]\nconst sum = numbers.reduce((prev, next) => prev + next, 0); // -> 21\n```\nДавайте посчитаем сумму баллов всех студентов, которые набрали больше 10 баллов, используя `map`, `filter` и `reduce`:\n```js\nconst students = [\n  { name: \"Коля\", grade: 10 },\n  { name: \"Ваня\", grade: 15 },\n  { name: \"Юля\", grade: 19 },\n  { name: \"Наташа\", grade: 9 },\n];\n\nconst aboveTenSum = students\n  .map(student => student.grade) // Создаём массив оценок из массива студентов с помощью метода map.\n  .filter(grade => grade >= 10) // Выбираем только оценки выше 10 при помощи метода filter.\n  .reduce((prev, next) => prev + next, 0); // Суммируем все оценки выше 10 друг с другом.\n\nconsole.log(aboveTenSum); /* -> 44: 10 (Коля) + 15 (Ваня) + 19 (Юля),\nоценка Наташи меньше 10 и была проигнорирована */\n```\n\n#### Объяснение\nДавайте использовать в качестве примера следующий массив:\n```js\nconst numbers = [0, 1, 2, 3, 4, 5, 6];\n```\n\n##### `Array.prototype.map()`\n```js\nconst doubledNumbers = numbers.map(function(n) {\n  return n * 2;\n});\nconsole.log(doubledNumbers); // -> [0, 2, 4, 6, 8, 10, 12]\n```\nЧто же здесь происходит? Мы применяем к массиву `numbers` метод `map`, который взаимодействует с каждым элементом массива, передавая его в нашу функцию. Цель функции — произвести расчёт и вернуть новое значение, чтобы `map` мог подставить его вместо переданного в функцию.\n\nДавайте даже вынесем функцию из массива, чтобы было понятнее, что происходит:\n```js\nconst doubleN = function(n) { return n * 2; };\nconst doubledNumbers = numbers.map(doubleN);\nconsole.log(doubledNumbers); // -> [0, 2, 4, 6, 8, 10, 12]\n```\n`numbers.map(doubleN)` создаёт `[doubleN(0), doubleN(1), doubleN(2), doubleN(3), doubleN(4), doubleN(5), doubleN(6)]`, что равняется `[0, 2, 4, 6, 8, 10, 12]`.\n> **Примечание:** Если вам не нужно возвращать новый массив и вы просто хотите перебрать существующий массив, совершая с его элементами некоторые действия, можете просто использовать `for` / `forEach` вместо метода `map`.\n\n##### `Array.prototype.filter()`\n```js\nconst evenNumbers = numbers.filter(function(n) {\n  return n % 2 === 0; // Истинно, если n чётное; ложно, если n нечётное.\n});\nconsole.log(evenNumbers); // -> [0, 2, 4, 6]\n```\nМы применяем `filter` к массиву `numbers`. Метод `filter` взаимодействует с каждым элементом массива и передаёт его в нашу функцию. Функция возвращает булево значение, определяющее, будет ли элемент сохранён в массиве. Затем `filter` возвращает массив отфильтрованных значений.\n\n##### `Array.prototype.reduce()`\nЦель метода `reduce` заключается в том, чтобы вычислить на основе массива какое-то одно значение. Какие именно вычисления метод произведет с элементами, зависит только от вас.\n```js\nconst sum = numbers.reduce(\n  function(acc, n) {\n    return acc + n;\n  },\n0 // Значение аккумулирующей переменной на первом шаге цикла.\n);\nconsole.log(sum); // -> 21\n```\nТак же, как методы `.map` и `.filter`, метод `.reduce` применяется к массиву и в качестве первого параметра принимает функцию.\n\nНа этот раз, впрочем, кое-что изменилось:\n- `.reduce` принимает два параметра.\n\nПервый параметр — это функция, которая будет вызываться на каждом шаге цикла.\n\nВторой параметр — это значение аккумулирующей переменной (`acc` в нашем случае) на первом шаге цикла (чтобы разобраться, читайте далее).\n- Параметры функции.\n\nФункция, которую вы передаёте в качестве первого параметра метода `.reduce`, принимает два аргумента. Первый аргумент — это аккумулирующая переменная (`acc` в нашем примере), второй аргумент — текущий элемент.\n\nАккумулирующая переменная равна значению, возвращённому нашей функцией на **предыдущем** шаге цикла. В самом начале каждого цикла `acc` равна значению, которое было передано в качестве второго параметра `.reduce`.\n\n###### На первом шаге\n`acc = 0`, потому что мы передали `0` в качестве второго параметра метода `reduce`.\n\n`n = 0` — первый элемент массива `number`.\n\nФункция возвращает `acc` + `n` --> 0 + 0 --> 0.\n\n###### На втором шаге\n`acc = 0`, потому что это значение функция вернула на предыдущем шаге.\n\n`n = 1` — второй элемент массива `number`.\n\nФункция возвращает `acc` + `n` --> 0 + 1 --> 1.\n\n###### На третьем шаге\n`acc = 1`, потому что это значение функция вернула на предыдущем шаге.\n\n`n = 2` — третий элемент массива `number`.\n\nФункция возвращает `acc` + `n` --> 1 + 2 --> 3.\n\n###### На четвертом шаге\n`acc = 3`, потому что это значение функция вернула на предыдущем шаге.\n\n`n = 3` — четвёртый элемент массива `number`.\n\nФункция возвращает `acc` + `n` --> 3 + 3 --> 6.\n\n###### На последнем шаге\n`acc = 15`, потому что это значение функция вернула на предыдущем шаге.\n\n`n = 6` — последний элемент массива `number`.\n\nФункция возвращает `acc` + `n` --> 15 + 6 --> 21.\n\nПоскольку это был последний шаг, `.reduce` возвращает `21`.\n\n#### Дополнительные материалы\n- [Understanding map, filter and reduce in JavaScript](https://hackernoon.com/understanding-map-filter-and-reduce-in-javascript-5df1c7eee464).\n\n### Оператор расширения `...`\nОператор расширения `...`, появившийся в ES2015, предназначен для развертывания итерируемых объектов (например, массивов) в тех местах, где можно поместить несколько элементов.\n\n#### Пример кода\n```js\nconst arr1 = [\"a\", \"b\", \"c\"];\nconst arr2 = [...arr1, \"d\", \"e\", \"f\"]; // -> [\"a\", \"b\", \"c\", \"d\", \"e\", \"f\"]\n```\n```js\nfunction myFunc(x, y, ...params) {\n  console.log(x); // -> \"a\"\n  console.log(y); // -> \"b\"\n  console.log(params); // -> [\"c\", \"d\", \"e\", \"f\"]\n}\n\nmyFunc(\"a\", \"b\", \"c\", \"d\", \"e\", \"f\");\n// \"a\"\n// \"b\"\n// [\"c\", \"d\", \"e\", \"f\"]\n```\n```js\nconst { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };\nconsole.log(x); // -> 1\nconsole.log(y); // -> 2\nconsole.log(z); // -> { a: 3, b: 4 }\nconst n = { x, y, ...z };\nconsole.log(n); // -> { x: 1, y: 2, a: 3, b: 4 }\n```\n\n#### Объяснение\n\n##### В итерируемых объектах (например, массивах)\nЕсли у нас есть два следующих массива:\n```js\nconst arr1 = [\"a\", \"b\", \"c\"];\nconst arr2 = [arr1, \"d\", \"e\", \"f\"]; // -> [[\"a\", \"b\", \"c\"], \"d\", \"e\", \"f\"]\n```\nПервый элемент массива `arr2` — это массив, потому что `arr1` напрямую вставляется в `arr2`. Но мы хотим, чтобы `arr2` состоял только из букв. Чтобы добиться этого, мы можем *развернуть* элементы массива `arr1` в массиве `arr2`.\n\nС использованием оператора расширения:\n```js\nconst arr1 = [\"a\", \"b\", \"c\"];\nconst arr2 = [...arr1, \"d\", \"e\", \"f\"]; // -> [\"a\", \"b\", \"c\", \"d\", \"e\", \"f\"]\n```\n\n##### Оставшиеся аргументы функции\nДля объединения аргументов можно использовать оператор оставшихся аргументов функции. Этот оператор позволяет представить любое число аргументов в виде массива, элементы которого можно перебрать при помощи цикла. Вообще, к каждой функции уже привязан объект `arguments` — массив, состоящий из всех аргументов, переданных функции.\n```js\nfunction myFunc() {\n  for (var i = 0; i < arguments.length; i++) {\n    console.log(arguments[i]);\n  }\n}\nmyFunc(\"Коля\", \"Андреев\", 10, 12, 6);\n// \"Коля\"\n// \"Андреев\"\n// 10\n// 12\n// 6\n```\nНо давайте представим, что мы хотим, чтобы наша функция создала нового студента со своими оценками и средним баллом. Удобнее будет записать первые два аргумента в две отдельные переменные, а все оценки поместить в массив, который можно перебирать.\n\nИменно это позволяет нам сделать оператор оставшихся аргументов!\n```js\nfunction createStudent(firstName, lastName, ...grades) {\n  /* firstName = \"Коля\"\n  lastName = \"Андреев\"\n  [10, 12, 6] — оператор `...` берет все остальные параметры, переданные функции,\n  и создает переменную grades с массивом, в котором они хранятся. */\n\n  const avgGrade = grades.reduce((acc, curr) => acc + curr, 0) / grades.length;\n  // Вычисляет средний балл из всех оценок.\n\n  return {\n    firstName: firstName,\n    lastName: lastName,\n    grades: grades,\n    avgGrade: avgGrade,\n  }\n}\n\nconst student = createStudent(\"Коля\", \"Андреев\", 10, 12, 6);\nconsole.log(student);\n/* {\nfirstName: \"Коля\",\nlastName: \"Андреев\",\ngrades: [10, 12, 6],\navgGrade: 9,33\n} */\n```\n> **Примечание:** `createStudent` — плохая функция, потому что мы не проверяем, существует ли `grades.length` и отличается ли от 0. Но так функцию легче прочитать, поэтому я не учитывал эти случаи.\n\n##### Расширение свойств объектов\nЧтобы понять эту часть, рекомендую прочитать предыдущие объяснения о применении оператора оставшихся аргументов к итерируемым объектам и параметрам функций.\n```js\nconst myObj = { x: 1, y: 2, a: 3, b: 4 };\nconst { x, y, ...z } = myObj; // Деструктуризация объекта.\nconsole.log(x); // -> 1\nconsole.log(y); // -> 2\nconsole.log(z); // -> { a: 3, b: 4 }\n\n// z - это остаток от деструктурированного объекта: объект myObj минус деструктурированные свойства х и у.\n\nconst n = { x, y, ...z };\nconsole.log(n); // -> { x: 1, y: 2, a: 3, b: 4 }\n\n// Здесь свойства объекта z расширяются в n\n```\n\n#### Дополнительные материалы\n- [TC39 — Object Rest/Spread Properties for ECMAScript](https://github.com/tc39/proposal-object-rest-spread).\n- [Spread Operator Introduction — WesBos](https://github.com/wesbos/es6-articles/blob/master/28%20-%20Spread%20Operator%20Introduction.md).\n- [JavaScript & The spread operator](https://codeburst.io/javascript-the-spread-operator-a867a71668ca).\n- [6 Great Uses of the Spread Operator](https://davidwalsh.name/spread-operator).\n\n### Сокращенная запись свойств объектов\nПри записи переменной в свойство объекта, если у переменной то же имя, что и у свойства, можно сделать следующее:\n```js\nconst x = 10;\nconst myObj = { x };\nconsole.log(myObj.x) // -> 10\n```\n\n#### Объяснение\nРаньше (до ES2015), если вы хотели при объявлении нового *литерала объекта* использовать переменные в качестве его свойств, вам пришлось бы писать подобный код:\n```js\nconst x = 10;\nconst y = 20;\n\nconst myObj = {\n  x: x, // Запись значения переменной х в myObj.x.\n  y: y, // Запись значения переменной у в myObj.y.\n};\n\nconsole.log(myObj.x); // -> 10\nconsole.log(myObj.y); // -> 20\n```\nКак видите, приходится повторять одно и то же, потому что имена свойств объекта совпадают с именами переменных, которые вы хотите записать в эти свойства.\n\nС ES2015, если имя переменной совпадает с именем свойства, можно использовать такую сокращенную запись:\n```js\nconst x = 10;\nconst y = 20;\n\nconst myObj = {\n  x,\n  y,\n};\n\nconsole.log(myObj.x); // -> 10\nconsole.log(myObj.y); // -> 20\n```\n\n#### Дополнительные материалы\n- [Enhanced Object Properties — ES6 Features](http://es6-features.org/#PropertyShorthand).\n\n### Промисы\n**Промис (promise)** — это объект, который может быть синхронно возвращён из асинхронной функции ([Ссылка](https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-promise-27fc71e77261#3cd0)).\n\nПромисы могут использоваться, чтобы избежать [«ада обратных вызовов»](http://callbackhell.com/), и они всё чаще и чаще используются в современных JavaScript-проектах.\n\n#### Пример кода\n```js\nconst fetchingPosts = new Promise((res, rej) => {\n  $.get(\"/posts\")\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#### Пояснение\nКогда вы делаете *AJAX-запрос*, ответ будет несинхронным, так как вы запрашиваете ресурс, на обработку которого требуется некоторое время. Ответ может быть вообще не получен, если запрашиваемый ресурс недоступен по какой-то причине (404).\n\nЧтобы избежать таких ситуаций, в ES2015 были добавлены *промисы*. Промисы могут иметь 3 различных состояния:\n- выполняется;\n- выполнено;\n- отклонено.\n\nПредположим, мы хотим использовать промисы для обработки AJAX-запроса для получения ресурса X.\n\n##### Создание промиса\nСначала создадим промис. Будем использовать GET-метод jQuery для создания AJAX-запроса к ресурсу X.\n```js\nconst xFetcherPromise = new Promise(\n// Создаём промис с помощью ключевого слова new и сохраняем его в переменную\n  function(resolve, reject) {\n    /* Конструктор промиса принимает в виде параметра функцию, которая, в свою очередь,\n    принимает 2 параметра: resolve и reject. */\n    $.get(\"X\") // Запускаем AJAX-запрос\n      .done(function(X) { // Как только запрос выполнен...\n        resolve(X); // ... выполняем промис со значением X в качестве параметра.\n      })\n      .fail(function(error) { // Если запрос не прошёл...\n        reject(error); // ... отклоняем промис со значением error.\n      });\n  }\n)\n```\nКак видно из рассмотренного примера, объект Promise принимает функцию-*исполнитель*, в свою очередь принимающую два параметра: `resolve` и `reject`. Эти параметры — функции, которые при вызове изменяют состояние промиса со значения *выполняется* на *выполнено* или *отклонено* соответственно.\n\nПромис находится в состоянии *выполняется* после создания экземпляра, и его функция-*исполнитель* выполняется немедленно. Как только одна из функций *выполнено* или *отклонено* вызвана в функции-*исполнителе*, промис вызовет связанные с ним обработчики.\n\n##### Использование обработчиков промисов\nЧтобы получить результат (или ошибку) промиса, нужно назначить ему обработчики следующим образом:\n```js\nxFetcherPromise\n  .then(function(X) {\n    console.log(X);\n  })\n  .catch(function(err) {\n    console.log(err);\n  })\n```\nЕсли вызов прошёл успешно, вызывается `resolve` и выполняется функция, переданная в метод `.then`.\n\nЕсли вызов не прошёл, вызывается `reject` и выполняется функция, переданная в `.catch`.\n> **Примечание:** Если промис уже выполнен или отклонён на момент назначения соответствующего обработчика, обработчик всё равно будет вызван. Так что между выполнением асинхронной операции и назначением обработчиков не возникает состояние гонки. [(Ссылка: MDN)](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Promise)\n\n#### Дополнительные материалы\n- [JavaScript Promises for Dummies — Jecelyn Yeen](https://scotch.io/tutorials/javascript-promises-for-dummies).\n- [JavaScript Promise API — David Walsh](https://davidwalsh.name/promises).\n- [Using promises — MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises).\n- [Master the JavaScript Interview: What is a Promise? — Eric Elliott](https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-promise-27fc71e77261).\n- [JavaScript Promises: an Introduction — Jake Archibald](https://developers.google.com/web/fundamentals/getting-started/primers/promises).\n- [Документация по промисам — MDN](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Promise).\n\n### Шаблонные строки\n**Шаблонные строки** — это конструкции, позволяющие использовать вставку, или [*интерполяцию выражений*](https://en.wikipedia.org/wiki/String_interpolation), в однострочных и многострочных строках.\n\nДругими словами, это новый синтаксис записи строк, с которым удобно использовать любые выражения JavaScript (например, переменные).\n\n#### Пример кода\n```js\nconst name = \"Коля\";\n`Привет, ${name}, следующее выражение равно четырем: ${2+2}.`;\n\n// -> Привет, Коля, следующее выражение равно четырем: 4.\n```\n\n#### Дополнительные материалы\n- [String Interpolation — Особенности ES6](http://es6-features.org/#StringInterpolation).\n- [Getting Literal With ES6 Template Strings — Addy Osmani](https://developers.google.com/web/updates/2015/01/ES6-Template-Strings).\n\n### Тегированные шаблонные строки\n**Шаблонные теги** — это *функции, которые могут быть префиксом к [шаблонной строке](#Шаблонные-строки)*. Когда функция вызывается таким образом, первый параметр представляет собой массив *строк*, которые выводятся между интерполированными переменными, а последующие параметры — значения выражений, вставленных в строку. Для захвата всех этих значений используйте оператор расширения `...`. [(Ссылка: MDN)](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Template_literals#Tagged_template_literals).\n> **Примечание:** Известная библиотека, которая называется [стилизованные компоненты](https://www.styled-components.com/), основана на этой возможности.\n\nНиже приведен пример работы тегированных шаблонных строк:\n```js\nfunction highlight(strings, ...values) {\n  const interpolation = strings.reduce((prev, current) => {\n    return prev + current + (values.length ? \"<mark>\" + values.shift() + \"</mark>\" : \"\");\n  }, \"\");\n\n  return interpolation;\n}\n\nconst meal = \"круассаны\";\nconst drink = \"кофе\";\n\nhighlight`Я люблю ${meal} с ${drink}.`;\n// -> <mark>Я люблю круассаны с кофе.</mark>\n```\nБолее интересный пример:\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 = [\"яблоки\", \"бананы\", \"апельсины\"];\ncomma`Я люблю ${snacks} на десерт.`;\n// -> Я люблю яблоки, бананы, апельсины на десерт.\n```\n\n#### Дополнительные материалы\n- [Tagged Template Literals — Wes Bos](http://wesbos.com/tagged-template-literals/).\n- [Библиотека common-tags](https://github.com/declandewet/common-tags).\n\n### Импорт / экспорт\nМодули в ES6 используются для получения доступа к переменным и функциям из других модулей (файлов с кодом), причем экспорт этих переменных и функций должен быть четко обозначен в исходном модуле.\n\nКрайне рекомендую почитать ресурсы MDN об экспорте/импорте (см. Дополнительные материалы ниже), в них содержится четкая и полная информация.\n\n#### Объяснение с примером кода\n##### Именованный экспорт\nИменованный экспорт используется для экспорта нескольких значений из модуля.\n> **Примечание:** Вы можете именовать экспорт только [объектами первого класса](https://ru.wikipedia.org/wiki/%D0%9E%D0%B1%D1%8A%D0%B5%D0%BA%D1%82_%D0%BF%D0%B5%D1%80%D0%B2%D0%BE%D0%B3%D0%BE_%D0%BA%D0%BB%D0%B0%D1%81%D1%81%D0%B0), у которых есть имя.\n\n```js\n// mathConstants.js\nexport const pi = 3.14;\nexport const exp = 2.7;\nexport const alpha = 0.35;\n\n// -------------\n\n// myFile.js\nimport { pi, exp } from './mathConstants.js';\n// Именованный импорт — с синтаксисом, похожим на деструктуризацию.\nconsole.log(pi) // -> 3.14\nconsole.log(exp) // -> 2.7\n\n// -------------\n\n// mySecondFile.js\nimport * as constants from './mathConstants.js';\n// Все экспортированные значения записываются в переменную constants.\nconsole.log(constants.pi) // -> 3.14\nconsole.log(constants.exp) // -> 2.7\n```\nХотя именованный импорт выглядит как *деструктуризация*, это не одно и то же. Кроме того, именованный импорт имеет другой синтаксис, не поддерживает значения по умолчанию и *глубокую* деструктуризацию.\n\nКроме того, можно создавать псевдонимы, но их синтаксис будет отличаться от синтаксиса, используемого при деструктуризации:\n```js\nimport { foo as bar } from 'myFile.js';\n// foo импортируется и записывается в новую переменную bar.\n```\n\n##### Импорт / экспорт по умолчанию\nЧто касается экспорта по умолчанию, то для каждого модуля (файла) может быть только один экспорт. Экспортом по умолчанию может быть функция, класс, объект или что-то еще. Это значение считается «основным», поскольку его будет проще всего импортировать. [Ссылка: MDN](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Statements/export#Description).\n```js\n// coolNumber.js\nconst ultimateNumber = 42;\nexport default ultimateNumber;\n\n// ------------\n\n// myFile.js\nimport number from './coolNumber.js';\n/* В переменную number автоматически попадает экспорт по умолчанию —\nвне зависимости от его имени в исходном модуле. */\nconsole.log(number) // -> 42\n```\nЭкспорт функций:\n```js\n// sum.js\nexport default function sum(x, y) {\n  return x + y;\n}\n\n// -------------\n\n// myFile.js\nimport sum from './sum.js';\nconst result = sum(1, 2);\nconsole.log(result) // -> 3\n```\n\n#### Дополнительные материалы\n- [ES6 Modules in bulletpoints](https://ponyfoo.com/articles/es6#modules)\n- [Экспорт — MDN](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Statements/export).\n- [Импорт — MDN](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Statements/import).\n- [Understanding ES6 Modules](https://www.sitepoint.com/understanding-es6-modules/).\n- [Destructuring special case — import statements](https://ponyfoo.com/articles/es6-destructuring-in-depth#special-case-import-statements).\n- [Misunderstanding ES6 Modules — Kent C. Dodds](https://medium.com/@kentcdodds/misunderstanding-es6-modules-upgrading-babel-tears-and-a-solution-ad2d5ab93ce0).\n- [Modules in JavaScript](http://exploringjs.com/es6/ch_modules.html#sec_modules-in-javascript).\n\n### <a name=\"this_def\"></a> `this` в JavaScript\nОператор `this` в JavaScript ведет себя не так, как в других языках. В большинстве случаев он определяется тем, как вызвана функция ([Ссылка: MDN](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Operators/this)).\n\nЭто сложное понятие с множеством тонкостей, так что я крайне рекомендую вам тщательно изучить приведенные ниже Дополнительные материалы. Я покажу вам, как сам лично определяю, чему равно `this`. Этому меня научила [вот эта статья Yehuda Katz](http://yehudakatz.com/2011/08/11/understanding-javascript-function-invocation-and-this/).\n```js\nfunction myFunc() {\n  ...\n}\n\n// После каждого выражения находим значение this в myFunc.\n\nmyFunc.call(\"myString\", \"привет\");\n// myString — в this записывается значение первого параметра .call.\n\n// В non-strict-режиме.\nmyFunc(\"привет\");\n// window — myFunc() — это синтаксический сахар для myFunc.call(window, \"привет\").\n\n// В strict-режиме.\nmyFunc(\"привет\");\n// undefined — myFunc() — это синтаксический сахар для myFunc.call(undefined, \"привет\").\n```\n```js\nvar person = {\n  myFunc: function() { ... }\n}\n\nperson.myFunc.call(person, \"test\");\n// person Object — в this записывается значение первого параметра call.\nperson.myFunc(\"test\");\n// person Object — person.myFunc() — это синтаксический сахар для person.myFunc.call(person, \"test\").\n\nvar myBoundFunc = person.myFunc.bind(\"привет\");\n// Создает новую функцию, в которой мы записываем \"привет\" в значение this.\nperson.myFunc(\"test\");\n// person Object — Метод bind не влияет на первоначальный метод.\nmyBoundFunc(\"test\");\n// \"hello\" — myBoundFunc — это person.myFunc, в которой this привязана к \"привет\".\n```\n\n#### Дополнительные материалы\n- [Understanding JavaScript Function Invocation and \"this\" — Yehuda Katz](http://yehudakatz.com/2011/08/11/understanding-javascript-function-invocation-and-this/).\n- [`this` в JavaScript — MDN](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Operators/this).\n\n### Класс\nJavaScript — это язык, [основанный на прототипах](https://ru.wikipedia.org/wiki/%D0%9F%D1%80%D0%BE%D1%82%D0%BE%D1%82%D0%B8%D0%BF%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5) (в то время как, например, Java — язык, [основанный на классах](https://en.wikipedia.org/wiki/Class-based_programming)). В обновлении ES6 представлены классы JavaScript, которые являются синтаксическим сахаром для наследования на основе прототипов, а **не** новой моделью наследования на основе классов ([Ссылка](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Classes)).\n\nЕсли вы знакомы с классами в других языках, слово «класс» может ввести вас в заблуждение. Постарайтесь не делать предположений о работе классов в JavaScript на основе других языков. Считайте это совершенно другим понятием.\n\nПоскольку этот документ не является попыткой научить вас языку с нуля, я надеюсь, что вы знаете, что такое прототипы и как они себя ведут. Если нет, смотрите дополнительные материалы после примеров.\n\n#### Примеры\nДо ES6, синтаксис на основе прототипов:\n```js\nvar Person = function(name, age) {\n  this.name = name;\n  this.age = age;\n};\nPerson.prototype.stringSentence = function() {\n  return \"Привет, меня зовут \" + this.name + \" и мне \" + this.age;\n};\n```\nНачиная с ES6, синтаксис на основе классов:\n```js\nclass Person {\n  constructor(name, age) {\n    this.name = name;\n    this.age = age;\n  }\n\n  stringSentence() {\n    return `Привет, меня зовут ${this.name} и мне ${this.age}`;\n  }\n}\n\nconst myPerson = new Person(\"Маша\", 23);\nconsole.log(myPerson.age); // -> 23\nconsole.log(myPerson.stringSentence()); // -> \"Привет, меня зовут Маша и мне 23\n```\n\n#### Дополнительные материалы\nДля понимания прототипов:\n- [Understanding Prototypes in JS — Yehuda Katz](http://yehudakatz.com/2011/08/12/understanding-prototypes-in-javascript/)\n- [A plain English guide to JS prototypes — Sebastian Porto](http://sporto.github.io/blog/2013/02/22/a-plain-english-guide-to-javascript-prototypes/)\n- [Наследование и цепочка прототипов — MDN](https://developer.mozilla.org/ru/docs/Web/JavaScript/Inheritance_and_the_prototype_chain).\n\nДля понимания классов:\n- [ES6 Classes in Depth — Nicolas Bevacqua](https://ponyfoo.com/articles/es6-classes-in-depth)\n- [ES6 Features — Classes](http://es6-features.org/#ClassDefinition)\n- [Классы JavaScript — MDN](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Classes).\n\n### Ключевые слова `Extends` и `super`\n\nКлючевое слово `extends` используется в объявлении класса или в выражениях класса для создания дочернего класса ([Ссылка: MDN](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Classes/extends)). Дочерний класс наследует все свойства родительского класса и дополнительно может добавлять новые свойства или изменять унаследованные.\n\nКлючевое слово `super` используется для вызова функций родителя объекта, включая его конструктор.\n\n- В конструкторе ключевое слово `super` должно использоваться раньше, чем ключевое слово `this`.\n- Вызов `super()` вызывает конструктор родительского класса. Если вы хотите передать какие-то аргументы из конструктора класса в конструктор родительского класса, то нужно вызывать функцию следующим образом: `super(arguments)`.\n- Если у родительского класса есть метод `X` (даже статический), для его вызова в дочернем классе можно использовать `super.X()`.\n\n#### Пример кода\n\n```js\nclass Polygon {\n  constructor(height, width) {\n    this.name = 'Многоугольник';\n    this.height = height;\n    this.width = width;\n  }\n\n  getHelloPhrase() {\n    return `Привет, я — ${this.name}`;\n  }\n}\n\nclass Square extends Polygon {\n  constructor(length) {\n    /* Здесь вызывается конструктор родительского класса со значением length,\n    передаваемым для переменных width и height класса Polygon. */\n\n    super(length, length);\n    /* Примечание: в производных классах перед тем, как использовать 'this',\n    нужно вызвать функцию super(), иначе это приведёт к ошибке. */\n\n    this.name = 'Квадрат';\n    this.length = length;\n  }\n\n  getCustomHelloPhrase() {\n    const polygonPhrase = super.getHelloPhrase();\n    // Получение доступа к родительскому методу с помощью синтаксиса super.X().\n    return `${polygonPhrase} с длиной стороны ${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) // -> 100\nconsole.log(mySquare.getHelloPhrase())\n/* -> 'Привет, я — Квадрат'\nКласс Square наследуется от класса Polygon и имеет доступ к его методам.*/\nconsole.log(mySquare.getCustomHelloPhrase())\n// -> 'Привет, я — Квадрат с длиной стороны'\n```\n\n> **Примечание**: Если бы мы попытались использовать `this` перед вызовом `super()` в классе Square, произошёл бы ReferenceError:\n\n```js\nclass Square extends Polygon {\n  constructor(length) {\n    this.height;\n    // ReferenceError, сначала нужно вызывать super!\n\n    /* Здесь вызывается конструктор родительского класса со значением length\n    в качестве значений width и height класса Polygon. */\n    // Here, it calls the parent class' constructor with lengths\n    super(length, length);\n\n    /* Примечание: в производных класса super() должен быть вызван до использования 'this'.\n    Иначе это приведёт к ошибке. */\n    this.name = 'Квадрат';\n  }\n}\n```\n\n#### Дополнительные материалы\n\n- [Extends — MDN](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Classes/extends).\n- [Оператор Super — MDN](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Operators/super).\n- [Inheritance — MDN](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Inheritance).\n\n### Async Await\nПомимо [Промисов](#Промисы) вам может встретиться еще один синтаксис для обработки асинхронного кода — `async`/`await`.\n\nЦель функций `async`/`await` — упростить синхронное использование промисов и выполнить какое-либо действие над группой промисов. Точно так же, как промисы похожи на структурированные функции обратного вызова, `async`/`await` похожи на комбинацию генераторов и промисов. ([Ссылка: MDN](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Statements/async_function))\n> **Примечание:** перед тем как пытаться понять `async`/`await`, вы должны понимать, что такое промисы и как они работают, поскольку `async`/`await` основаны на промисах.\n\n> **Примечание 2:** [`await` должен использоваться в `async` функции](https://hackernoon.com/6-reasons-why-javascripts-async-await-blows-promises-away-tutorial-c7ec10518dd9#f3f0), что означает, что вы не можете использовать `await` на верхнем уровне вашего кода, так как он не находится внутри async-функции.\n\n#### Пример кода\n```js\nasync function getGithubUser(username) {\n  // Ключевое слово async позволяет использовать await в функции и означает, что функция возвращает промис.\n  const response = await fetch(`https://api.github.com/users/${username}`);\n  // «Синхронное» ожидание промиса перед переходом на новую строку.\n  return response.json();\n}\n\ngetGithubUser('mbeaudru')\n  .then(user => console.log(user))\n  /* Логирование пользователя — не может использовать синтаксис await,\n  так как этот код не находится внутри async-функции. */\n  .catch(err => console.log(err));\n  // Если в нашей асинхронной функции возникнет ошибка, то мы перехватим ее здесь.\n```\n\n#### Объяснение с помощью примера кода\n`async`/`await` построены на промисах, но позволяют использовать более императивный стиль кода.\n\nОператор `async` объявляет функцию как асинхронную, и данная функция всегда будет возвращать *промис*. В async-функции можно использовать оператор `await` для приостановки выполнения до тех пор, пока возвращаемый промис либо выполнится, либо будет отклонен.\n```js\nasync function myFunc() {\n  // Можно использовать оператор await, так как это async-функция.\n  return \"hello world\";\n}\n\nmyFunc().then(msg => console.log(msg));\n// \"Привет, мир!\" — возвращаемое значение myFunc превращается в промис из-за оператора async.\n```\nКогда будет достигнут оператор `return` async-функции, промис выполняется с возвращаемым значением. Если внутри async-функции генерируется ошибка, состояние промиса изменится на `rejected`. Если async-функция не возвращает никакого значения, промис всё равно будет возвращен и выполнится без значения, когда выполнение async-функции будет завершено.\n\nОператор `await` используется для ожидания выполнения *Промиса* и может быть использован только в теле async-функции. При этом выполнение кода приостанавливается, пока не будет выполнен промис.\n> **Примечание:** `fetch` — это функция, возвращающая промис, который позволяет выполнить AJAX-запрос.\n\nДавайте сначала посмотрим, как мы можем получить пользователя github с помощью промисов:\n```js\nfunction getGithubUser(username) {\n  return fetch(`https://api.github.com/users/${username}`).then(response => response.json());\n}\n\ngetGithubUser('mbeaudru')\n  .then(user => console.log(user))\n  .catch(err => console.log(err));\n```\nВот эквивалент с использованием  `async`/`await`:\n```js\nasync function getGithubUser(username) {\n  // Превращение в промис + разрешено использование ключевого слова await.\n  const response = await fetch(`https://api.github.com/users/${username}`);\n  // Выполнение останавливается здесь, пока не закончится выполнение промиса.\n  return response.json();\n}\n\ngetGithubUser('mbeaudru')\n  .then(user => console.log(user))\n  .catch(err => console.log(err));\n```\nСинтаксис `async`/`await` особенно удобен для построения цепочек взаимозависимых промисов.\n\nНапример, вам нужно получить токен для того, чтобы получить публикацию в блоге из базы данных, а затем информацию об авторе.\n> **Примечание:** Выражение `await` должно быть заключено в круглые скобки для вызова методов и свойств разрешенных значений в одной строке.\n\n```js\nasync function fetchPostById(postId) {\n  const token = (await fetch('token_url')).json().token;\n  const post = (await fetch(`/posts/${postId}?token=${token}`)).json();\n  const author = (await fetch(`/users/${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##### Обработка ошибок\nЕсли мы не добавим блок `try` / `catch` вокруг выражения `await`, неперехваченные исключения — неважно, были ли они выброшены в теле вашей async-функции или во время ожидания выполнения `await` — отклонят промис, возвращенный из async-функции. Использование состояния `throw` в асинхронной функции — то же самое, что возврат промиса, который был отклонен. [(Ссылка: PonyFoo)](https://ponyfoo.com/articles/understanding-javascript-async-await#error-handling).\n> **Примечание:** Промисы ведут себя так же!\n\nС помощью промисов вот как бы мы обработали ошибки:\n```js\nfunction getUser() { // Этот промис будет отклонен!\n  return new Promise((res, rej) => rej(\"Пользователь не найден!\"));\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)); // -> \"Пользователь не найден!\"\n```\nЭквивалент с использованием `async`/`await`:\n```js\nasync function getUser() {\n  // Возвращенный промис будет отклонен!\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)); // -> \"Пользователь не найден!\"\n```\n\n#### Дополнительные материалы\n- [Async/Await — JavaScript.Info](https://javascript.info/async-await).\n- [ES7 Async/Await](http://rossboucher.com/await/#/).\n- [6 Reasons Why JavaScript’s Async/Await Blows Promises Away](https://hackernoon.com/6-reasons-why-javascripts-async-await-blows-promises-away-tutorial-c7ec10518dd9).\n- [JavaScript awaits](https://dev.to/kayis/javascript-awaits).\n- [Using Async Await in Express with Node 8](https://medium.com/@Abazhenov/using-async-await-in-express-with-node-8-b8af872c0016).\n- [Функция Async](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Statements/async_function).\n- [Await](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Operators/await).\n- [Using async / await in express with node 8](https://medium.com/@Abazhenov/using-async-await-in-express-with-node-8-b8af872c0016).\n\n### Истина / Ложь\nВ JavaScript «истинность» или «ложность» значения определяется при вычислении этого значения в булевом контексте. Примером булева контекста может быть вычисление в условии `if`.\n\nЛюбое значение будет приведено к `true` (истина), кроме:\n- `false` (ложь);\n- `0`;\n- `\"\"` (пустая строка);\n- `null`;\n- `undefined`;\n- `NaN`.\n\nВот примеры *булева контекста*:\n- значение условия `if`.\n```js\nif (myVar) {}\n```\n\nЗначение `myVar` может быть любым [объектом первого класса](https://ru.wikipedia.org/wiki/%D0%9E%D0%B1%D1%8A%D0%B5%D0%BA%D1%82_%D0%BF%D0%B5%D1%80%D0%B2%D0%BE%D0%B3%D0%BE_%D0%BA%D0%BB%D0%B0%D1%81%D1%81%D0%B0) (переменная, функция, логическое значение), но оно будет преобразовано в логическое значение, поскольку вычисляется в булевом контексте.\n\n- После логического оператора **NOT** `!`.\n\nЭтот оператор возвращает значение «ложь», если его единственный операнд может быть преобразован к значению «истина»; иначе он возвращает значение «истина».\n```js\n!0 // -> «истина»: 0 — это «ложь», поэтому вернется \"истина\".\n!!0 // -> «ложь»: 0 — это «ложь», следовательно !0 возвращает истину, а !(!0) возвращает «ложь».\n!!\"\" // -> «ложь»: пустая строка — «ложь», поэтому НЕ (НЕ «ложь») равно «ложь».\n```\n- Конструктор объектов типа `Boolean`.\n\n```js\nnew Boolean(0); // «ложь»\nnew Boolean(1); // «истина»\n```\n- Тернарный оператор.\n\n```js\nmyVar ? \"истина\" : \"ложь\"\n```\n\nЗначение `myVar` вычисляется в булевом контексте.\n\nБудьте внимательны при сравнении двух значений. Значения объектов (которые должны быть приведены к истине), **не** приводятся к булеву типу, а приводятся к примитивному типу в соответствии со [спецификацией](http://javascript.info/object-toprimitive). Внутри, когда объект сравнивается с булевым значением, например, `[] == true`, выполняется `[].toString() == true`, происходит следующее:\n\n```js\nlet a = [] == true // a ложно, так как [].toString() возвращает пустую строку (\"\").\nlet b = [1] == true // b истинно, так как [1].toString() возвращает \"1\".\nlet c = [2] == true // c ложно, так как [2].toString() возвращает \"2\".\n```\n\n#### Дополнительные материалы\n\n- [Truthy (MDN)](https://developer.mozilla.org/en-US/docs/Glossary/Truthy).\n- [Falsy (MDN)](https://developer.mozilla.org/en-US/docs/Glossary/Falsy).\n- [Truthy and Falsy values in JS — Josh Clanton](http://adripofjavascript.com/blog/drips/truthy-and-falsy-values-in-javascript.html).\n\n### Анаморфизмы и катаморфизмы\n\n#### Анаморфизмы\n\nАнаморфизмы — это фунции, которые отображают некоторый объект на более сложную структуру, содержащую тип объекта. Это процесс *разворачивания* простой структуры в более сложную.\n\nРассмотрим разворачивание целого числа в список целых чисел. Целое число — наш изначальный объект, а список целых чисел — более сложная структура.\n\n##### Пример кода\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  //-> [ 5, 4, 3, 2, 1 ]\n```\n\n#### Катаморфизмы\n\nКатаморфизмы противоположны анаморфизмам: они берут объекты более сложной структуры и *складывают* их в более простые структуры.\n\nРассмотрим следующий пример функции `product`, которая принимает список целых чисел и возвращает простое целое число.\n\n##### Пример кода\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)) // -> 120\n```\n\n#### Дополнительные материалы\n\n- [Anamorphisms in JavaScript](http://raganwald.com/2016/11/30/anamorphisms-in-javascript.html).\n- [Anamorphism](https://en.wikipedia.org/wiki/Anamorphism).\n- [Catamorphism](https://en.wikipedia.org/wiki/Catamorphism).\n\n### Генераторы\n\nДругой способ написания функции `downToOne` — использование генератора. Чтобы создать объект типа `Generator`, нужно использовать объявление `function *`. Генераторы — это функции, выполнение которых может быть прервано, а затем продолжено с тем же контекстом (привязками переменных), сохраняющимся при всех вызовах.\n\nНапример, функция `downToOne` может быть переписана следующим образом:\n\n```js\nfunction * downToOne(n) {\n  for (let i = n; i > 0; --i) {\n    yield i;\n  }\n}\n\n[...downToOne(5)] // -> [ 5, 4, 3, 2, 1 ]\n```\n\nГенераторы возвращают итерируемый объект. Когда вызывается метод `next()` итератор, она выполняется до первого выражения `yield`, которое указывает значение, которое должно быть возвращено из итератора или с помощью `yield*`, которое дегегирует выполнение другому генератору. Когда в генераторе вызывается выражение `return`, он будет помечать генератор как выполненный и возвращать значение из выражения `return`. Дальнейшие вызовы `next()` не будут возвращать никаких новых значений.\n\n#### Пример кода\n\n```js\n// Пример использования\nfunction * idMaker() {\n  var index = 0;\n  while (index < 2) {\n    yield index;\n    index = index + 1;\n  }\n}\n\nvar gen = idMaker();\n\ngen.next().value; // -> 0\ngen.next().value; // -> 1\ngen.next().value; // -> undefined\n```\n\nВыражение `yield*` позволяет генератору вызывать другую функцию-генератор во время итерации.\n\n```js\n// Пример использования yield *\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; // -> 10\ngen.next().value; // -> 11\ngen.next().value; // -> 12\ngen.next().value; // -> 13\ngen.next().value; // -> 20\n```\n\n```js\n// Пример возврата из генератора\nfunction* yieldAndReturn() {\n  yield \"Y\";\n  return \"R\";\n  yield \"unreachable\";\n}\n\nvar gen = yieldAndReturn()\ngen.next(); // -> { value: \"Y\", done: false }\ngen.next(); // -> { value: \"R\", done: true }\ngen.next(); // -> { value: undefined, done: true }\n```\n\n#### Дополнительные материалы\n- [Итераторы и генераторы — MDN](https://developer.mozilla.org/ru/docs/Web/JavaScript/Guide/Iterators_and_Generators#%D0%93%D0%B5%D0%BD%D0%B5%D1%80%D0%B0%D1%82%D0%BE%D1%80%D1%8B).\n\n### Статические методы\n\n#### Краткое объяснение\nКлючевое слово `static` используется в классах для объявления статических методов. Статические методы — это функции в классе, которые принадлежат объекту класса и недоступны никаким экземплярам этого класса.\n\n#### Пример кода\n```js\nclass Repo {\n  static getName() {\n    return \"Repo name is modern-js-cheatsheet\";\n  }\n}\n\n// Обратите внимание, что нам не пришлось создавать экземпляр класса Repo.\nconsole.log(Repo.getName()); // Repo name is modern-js-cheatsheet\n\nlet r = new Repo();\nconsole.log(r.getName()); // Не пойманный TypeError: repo.getName не является функцией.\n```\n\n#### Подробное объяснение\nСтатические методы можно вызвать в другом статическом методе, используя ключевое слово `this`, однако это не работает для нестатических методов. Нестатические методы не могут напрямую обращаться к статическим методам, используя ключевое слово `this`.\n\n##### Вызов статических методов из статического метода.\nДля вызова статического метода из другого статического метода можно использовать ключевое слово `this` следующим образом:\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()); // Repo name is modern-js-cheatsheet-added-this\n```\n\n##### Вызов статических методов из нестатических методов\nНестатические методы могут вызывать статические двумя способами:\n\n1. Используя имя класса.\n\nЧтобы получить доступ к статическому методы из нестатического, используем имя класса и вызываем статический метод как обычное свойство, например, `ClassName.StaticMethodName`:\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// Нужно создать экземпляр класса для использования нестатических методов.\nlet r = new Repo();\nconsole.log(r.useName()); // Repo name is modern-js-cheatsheet and it contains some really important stuff\n```\n\n2. Используя конструктор.\n\nСтатические методы можно вызвать как свойства объекта-конструктора класса.\n```js\nclass Repo {\n  static getName() {\n    return \"Repo name is modern-js-cheatsheet\"\n  }\n\nuseName(){\n// Вызывает статический метод как обычное свойство конструктора.\n  return `${this.constructor.getName()} and it contains some really important stuff`;\n  }\n}\n\n// Нужно создать экземпляр класса для использования нестатических функций.\nlet r = new Repo();\nconsole.log(r.useName()); // Repo name is modern-js-cheatsheet and it contains some really important stuff\n```\n\n#### Дополнительные материалы\n- [Ключевое слово static — MDN](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Classes/static).\n- [Static Methods- Javascript.info](https://javascript.info/class#static-methods).\n- [Static Members in ES6 — OdeToCode](http://odetocode.com/blogs/scott/archive/2015/02/02/static-members-in-es6.aspx).\n\n## Глоссарий\n\n### <a name=\"scope_def\"></a> Область видимости\nКонтекст, в котором переменная и выражения являются «видимыми» или могут быть получены. Если переменная или выражение находятся «вне текущей области видимости», значит, их нельзя использовать.\n\nИсточник: [MDN](https://developer.mozilla.org/ru/docs/Glossary/Scope)\n\n### <a name=\"mutation_def\"></a> Изменение переменных\nГоворят, что переменная изменилась, когда её значение изменилось относительно начального.\n```js\nvar myArray = [];\nmyArray.push(\"firstEl\") // Значение myArray изменено.\n```\nПеременная называется *неизменяемой*, если она не может быть изменена.\n\nБолее подробно [смотрите в статье на MDN](https://developer.mozilla.org/ru/docs/Glossary/Mutable).\n"
  },
  {
    "path": "translations/th-TH.md",
    "content": "# Modern JavaScript Cheatsheet\n\n![Modern JavaScript cheatsheet](https://i.imgur.com/aexPxMb.png)\n<small>เครดิตรูปภาพ: [Ahmad Awais ⚡️](https://github.com/ahmadawais)</small>\n\n## เกริ่นนำ\n\n### จุดประสงค์\n\nเอกสารนี้เป็น cheatsheet ชุดคำสั่งของภาษา JavaScript ที่คุณได้พบเจอเป็นประจำใน​โปรเจ็คและโค้ดตัวอย่างใหม่ๆ\n\nบทความนี้ไม่ได้มีจุดประสงค์ในการสอน Javascript ตั้งแต่พื้นฐาน แต่ต้องการจะช่วยให้ Developer ที่มีพื้นฐานอยู่แล้วแต่อาจจะติดปัญหาในการเข้าใจในโค้ด Javascript สมัยใหม่ (ยกตัวอย่างเช่นกำลังเรียนรู้ React อยู่) เนื่องจากมีการใช้ concept ของ Javascript สมัยใหม่\n\nนอกจากนี้ผมจะแนะนำเคล็ดลับส่วนตัว(ซึ่งอาจจะมีบางคนไม่เห็นด้วย)ใส่ไว้ในบางส่วน โดยจะมีหมายเหตุบอกเอาไว้\n\n> **หมายเหตุ:** คอนเซปส่วนใหญ่ในนี้จะมาจากการอัปเดตใหม่ๆของ JavaScript (ES2015, หรือโดยทั่วไปเรียกว่า ES6). คุณสามารถดูฟีเจอร์ใหม่ๆของ Javascript ที่เพิ่มเข้ามาโดยสามารถติดตามได้จาก [ที่นี่](http://es6-features.org); ซึ่งเป็นเว็บไซต์ที่ดีทีเดียว\n\n### แหล่งเรียนรู้ฟรีที่แนะนำเพิ่มเติม\n\nเมื่อติดปัญหาในการเข้าใจตรงจุดไหนแนะนำให้ลองหาคำตอบจากแหล่งข้อมูลเพิ่มเติมเหล่านี้ดูก่อน:\n\n- [MDN (Mozilla Developer Network)](https://developer.mozilla.org/en-US/search?q=)\n- [You don't know JS (book)](https://github.com/getify/You-Dont-Know-JS)\n- [ES6 Features with examples](http://es6-features.org)\n- [WesBos blog (ES6)](http://wesbos.com/category/es6/)\n- [Javascript Basics for Beginners](https://www.udacity.com/course/javascript-basics--ud804) - คอร์สฟรีจาก Udacity\n- [Reddit (JavaScript)](https://www.reddit.com/r/javascript/)\n- [Google](https://www.google.com/) to find specific blog and resources\n- [StackOverflow](https://stackoverflow.com/questions/tagged/javascript)\n\n## สารบัญ\n\n- [Modern JavaScript cheatsheet](#modern-javascript-cheatsheet)\n  * [เกริ่นนำ](#เกริ่นนำ)\n    + [จุดประสงค์](#จุดประสงค์)\n    + [แหล่งเรียนรู้ฟรีที่แนะนำเพิ่มเติม](#แหล่งเรียนรู้ฟรีที่แนะนำเพิ่มเติม)\n  * [สารบัญ](#สารบัญ)\n  * [เนื้อหา](#เนื้อหา)\n    + [การประกาศตัวแปร: var, const, let](#การประกาศตัวแปร-var-const-let)\n      - [อธิบายสั้นๆ](#อธิบายสั้นๆ)\n      - [ตัวอย่างโค้ด](#ตัวอย่างโค้ด)\n      - [อธิบายรายละเอียด](#อธิบายรายละเอียด)\n      - [ข้อมูลเพิ่มเติมจากภายนอก](#ข้อมูลเพิ่มเติมจากภายนอก)\n    + [Arrow ฟังก์ชั่น](#-arrow-ฟังก์ชั่น)\n      - [ตัวอย่างโค้ด](#ตัวอย่างโค้ด-1)\n      - [อธิบายรายละเอียด](#อธิบายรายละเอียด-1)\n        * [การย่อสั้น](#การย่อสั้น)\n        * [การอ้างอิงของ *this*](#การอ้างอิงของ-this)\n      - [แหล่งข้อมูลที่มีประโยชน์](#แหล่งข้อมูลที่มีประโยชน์)\n    + [ค่า default parameter ของฟังก์ชั่น](#ค่า-default-parameter-ของฟังก์ชั่น)\n      - [ข้อมูลเพิ่มเติมจากภายนอก](#ข้อมูลเพิ่มเติมจากภายนอก-1)\n    + [Destructuring objects และ arrays](#destructuring-objects-และ-arrays)\n      - [อธิบายตัวอย่างโค้ด](#อธิบายตัวอย่างโค้ด)\n      - [แหล่งข้อมูลที่มีประโยชน์](#แหล่งข้อมูลที่มีประโยชน์-1)\n    + [Array methods - map / filter / reduce](#array-methods---map--filter--reduce)\n      - [ตัวอย่างโค้ด](#ตัวอย่างโค้ด-2)\n      - [อธิบาย](#อธิบาย)\n        * [Array.prototype.map()](#arrayprototypemap)\n        * [Array.prototype.filter()](#arrayprototypefilter)\n        * [Array.prototype.reduce()](#arrayprototypereduce)\n      - [ข้อมูลเพิ่มเติมจากภายนอก](#ข้อมูลเพิ่มเติมจากภายนอก-2)\n    + [Spread operator \"...\"](#spread-operator-)\n      - [ตัวอย่างโค้ด](#ตัวอย่างโค้ด-3)\n      - [อธิบาย](#อธิบาย-1)\n        * [ใช้กับสิ่งที่สามารถวนลูปได้ (iterables) (แบบ arrays)](#ใช้กับสิ่งที่สามารถวนลูปได้-iterables-แบบ-arrays)\n        * [Rest parameter ของฟังก์ชั่น](#rest-parameter-ของฟังก์ชั่น)\n        * [Object properties spreading](#object-properties-spreading)\n      - [ข้อมูลเพิ่มเติมจากภายนอก](#ข้อมูลเพิ่มเติมจากภายนอก)\n    + [Object property shorthand](#object-property-shorthand)\n      - [อธิบาย](#อธิบาย-2)\n      - [ข้อมูลเพิ่มเติมจากภายนอก](#ข้อมูลเพิ่มเติมจากภายนอก-1)\n    + [Promises](#promises)\n      - [ตัวอย่างโค้ด](#ตัวอย่างโค้ด-4)\n      - [อธิบาย](#อธิบาย-3)\n        * [การสร้าง Promise](#create-the-promise)\n        * [การใช้งาน Promise handlers](#การใช้งาน-promise-handlers)\n      - [ข้อมูลเพิ่มเติมจากภายนอก](#ข้อมูลเพิ่มเติมจากภายนอก-2)\n    + [Template literals](#template-literals)\n      - [ตัวอย่างโค้ด](#ตัวอย่างโค้ด-5)\n      - [ข้อมูลเพิ่มเติมจากภายนอก](#ข้อมูลเพิ่มเติมจากภายนอก-3)\n    + [Tagged Template Literals](#tagged-template-literals)\n      - [ข้อมูลเพิ่มเติมจากภายนอก](#ข้อมูลเพิ่มเติมจากภายนอก-4)\n    + [Imports / Exports](#imports--exports)\n      - [อธิบายตัวอย่างโค้ด](#อธิบายตัวอย่างโค้ด-1)\n        * [Named exports](#named-exports)\n        * [Default import / export](#default-import--export)\n      - [ข้อมูลเพิ่มเติมจากภายนอก](#ข้อมูลเพิ่มเติมจากภายนอก-5)\n    + [JavaScript *this*](#-javascript-this)\n      - [ข้อมูลเพิ่มเติมจากภายนอก](#ข้อมูลเพิ่มเติมจากภายนอก-6)\n    + [Class](#class)\n      - [ตัวอย่าง](#samples)\n      - [ข้อมูลเพิ่มเติมจากภายนอก](#ข้อมูลเพิ่มเติมจากภายนอก-7)\n    + [Async Await](#async-await)\n      - [ตัวอย่างโค้ด](#ตัวอย่างโค้ด-6)\n      - [อธิบายตัวอย่างโค้ด](#อธิบายตัวอย่างโค้ด-2)\n      - [การจัดการกับ Error](#การจัดการกับ-error)\n      - [ข้อมูลเพิ่มเติมจากภายนอก](#ข้อมูลเพิ่มเติมจากภายนอก-8)\n    + [Truthy / Falsy](#truthy--falsy)\n    + [Static Methods](#static-methods)\n      - [อธิบายสั้นๆ](#อธิบายสั้นๆ-1)\n      - [ตัวอย่างโค้ด](#ตัวอย่างโค้ด-7)\n      - [อธิบายรายละเอียด](#อธิบายรายละเอียด-2)\n        * [เรียก static methods อื่นจาก static method](#เรียก-static-methods-อื่นจาก-static-method)\n        * [เรียก static methods จาก non-static method](#เรียก-static-methods-จาก-non-static-method)\n      - [ข้อมูลเพิ่มเติมจากภายนอก](#ข้อมูลเพิ่มเติมจากภายนอก-9)\n  * [คำศัพธ์](#คำศัพธ์)\n    + [Scope](#-scope)\n    + [Variable mutation](#-variable-mutation)\n\n## เนื้อหา\n\n### การประกาศตัวแปร: var, const, let\n\nใน JavaScript มีวิธีการประกาศตัวแปรได้ 3 แบบคือ ```var```, ```let``` และ ```const``` ซึ่งแต่ละแบบมีความแตกต่างกัน\n\n#### อธิบายสั้นๆ\n\nตัวแปรที่ประกาศโดยใช้ ```const``` จะไม่สามารถถูก assign ค่าให้กับตัวแปรใหม่ได้ ในขณะที่ ```let``` กับ ```var``` สามารถทำได้\n\nผมแนะนำให้ประกาศตัวแปรด้วย ```const``` เสมอและค่อยเปลี่ยนเป็น ```let``` ถ้าคุณต้องการ*เปลี่ยนแปลงค่า (mutate)* หรือ assign ค่าให้ตัวแปรในภายหลัง\n\n<table>\n  <tr>\n    <th></th>\n    <th>Scope</th>\n    <th>สามารถ Assign ค่าใหม่ได้</th>\n    <th>สามารถเปลี่ยนแปลงค่าได้</th>\n   <th><a href=\"#tdz_sample\">Temporal Dead Zone</a></th>\n  </tr>\n  <tr>\n    <th>const</th>\n    <td>Block</td>\n    <td>ไม่ใช่</td>\n    <td><a href=\"#const_mutable_sample\">ใช่</a></td>\n    <td>ใช่</td>\n  </tr>\n  <tr>\n    <th>let</th>\n    <td>Block</td>\n    <td>ใช่</td>\n    <td>ใช่</td>\n    <td>ใช่</td>\n  </tr>\n   <tr>\n    <th>var</th>\n    <td>Function</td>\n    <td>ใช่</td>\n    <td>ใช่</td>\n    <td>ไม่ใช่</td>\n  </tr>\n</table>\n\n#### ตัวอย่างโค้ด\n\n```javascript\nconst person = \"Nick\";\nperson = \"John\" // จะ thrown error เพราะว่า person ไม่สามารถ assign ค่าใหม่ได้\n```\n\n```javascript\nlet person = \"Nick\";\nperson = \"John\";\nconsole.log(person) // \"John\", let จะยอมให้สามารถ assign ค่าใหม่ได้\n```\n\n#### อธิบายรายละเอียด\n\nอธิบาย [*scope*](#scope_def) ของตัวแปรได้อย่างคร่าวๆ หมายถึง \"ขอบเขตที่ตัวแปรสามารถใช้งานได้ภายในโค้ด\"\n\n##### var\n\nตัวแปรที่ถูกประกาศด้วย ```var``` จะเป็น *function scoped* เมื่อตัวแปรถูกสร้างภายใน function โค้ดใน function นั้นสามารถเข้าถึงตัวแปรนั้นได้ และตัวแปร *function scoped* ที่ถูกสร้างใน function จะไม่สามารถถูกเข้าถึงจากภายนอก function ได้\n\nแนะนำให้ลองจินตนาการดูว่าถ้าตัวแปรเป็นตัวแปร *X scoped* หมายความว่าตัวแปรนี้เป็น property ของ X เท่านั้น\n\n```javascript\nfunction myFunction() {\n  var myVar = \"Nick\";\n  console.log(myVar); // \"Nick\" - myVar จะสามารถเข้าถึงได้จากภายใน function\n}\nconsole.log(myVar); // จะเกิด ReferenceError เพราะ myVar ไม่สามารถเข้าถึงได้จากภายนอก function\n```\n\nตัวอย่างเพิ่มเติมสำหรับเรื่อง scope ของตัวแปร\n\n```javascript\nfunction myFunction() {\n  var myVar = \"Nick\";\n  if (true) {\n    var myVar = \"John\";\n    console.log(myVar); // \"John\"\n    // จริงๆ แล้ว myvar เป็นตัวแปร function scoped เราแค่ได้ลบค่าตัวแปร myVar จาก \"Nick\" และเปลี่ยนเป็น \"John\"\n  }\n  console.log(myVar); // \"John\" - จะเห็นได้ว่าค่าได้ถูกเปลี่ยนไปแล้ว\n}\nconsole.log(myVar); // จะเกิด ReferenceError เพราะ myVar ไม่สามารถเข้าถึงได้จากภายนอก function\n```\n\nนอกจากนี้ตัวแปรที่ประกาสด้วย *var* จะถูกย้ายตอน execution ไปอยู่ด้านบนสุดของ scope และนี่คือสิ่งที่เราเรียกว่า [var hoisting](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var#var_hoisting).\n\nโค้ดตัวอย่างกรณีนี้:\n\n```js\nconsole.log(myVar) // undefined -- ไม่มีการเกิด error\nvar myVar = 2;\n```\n\nเพราะว่าตามความเข้าใจเวลา Execution จะเป็นแบบนี้:\n\n```js\nvar myVar;\nconsole.log(myVar) // undefined -- ไม่มีการเกิด error\nmyVar = 2;\n```\n\n##### let\n\n```var``` และ ```let ``` จะคล้ายกันแต่ตัวแปรที่ประกาศด้วย ```let``` จะ\n\n- เป็น *block scoped*\n- จะ**ไม่สามารถ**เข้าถึงก่อนที่มันจะถูก assign ค่าได้\n- ไม่สามารถประกาศตัวแปรซ้ำใน scope เดียวกันได้\n\nลองดูตัวอย่างเรื่องผลกระทบ (side effect) ของ block-scoping จากตัวอย่างก่อนหน้า\n\n```javascript\nfunction myFunction() {\n  let myVar = \"Nick\";\n  if (true) {\n    let myVar = \"John\";\n    console.log(myVar); // \"John\"\n    // จริงๆ แล้ว myVar เป็น block scoped เราสามารถสร้างตัวแปร myVar ใหม่ได้\n    // ตัวแปรนี้จะไม่สามารถเข้าถึงได้จากภายนอก block นี้และเป็นอิสระจากกัน\n    // กับตัวแปร myVar ตัวแรกที่เราสร้าง !\n  }\n  console.log(myVar); // \"Nick\", จะเห็นตามที่อธิบายข้างต้นว่าภายใน block ไม่ส่งผลกระทบกับค่านี้\n}\nconsole.log(myVar); // จะเกิด ReferenceError เพราะ myVar จะไม่สามารถเข้าถึงได้จากภายนอก function\n```\n\n<a name=\"tdz_sample\"></a> ตอนนี้น่าจะเข้าใจเหตุผลแล้วว่าทำไมตัวแปรที่ประกาศโดยใช้ *let* (และ *const*) ไม่สามารถเข้าถึงได้ก่อนจะถูก assign ค่า\n\n```js\nconsole.log(myVar) // เกิด ReferenceError !\nlet myVar = 2;\n```\n\nสิ่งนี้จะแตกต่างกับตัวแปรที่ประกาศโดยใช้ *var* ถ้าเราพยายามที่จะอ่านหรือเขียนตัวแปรที่ประกาศโดย *let* หรือ *const* ก่อนที่ทำการ assign ค่าจะเกิด Error ทันที ปรากฏการณ์นี้มักถูกเรียกว่า [*Temporal dead zone*](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let#Temporal_Dead_Zone_and_errors_with_let) หรือ *TDZ*.\n\n> **หมายเหตุ:** ในทางเทคนิคแล้ว การประกาศตัวแปร *let* กับ *const* เป็น hoisted เหมือนกัน, แต่ไม่ใช่กับการ assign ค่า ดังนั้นเมื่อมันไม่สามารถใช้งานได้ก่อน assign ค่าได้ทำให้ดูเหมือนว่าไม่มี hoisting แต่จริงๆ แล้วมันมี อ่าน[คำอธิบายเพิ่มเติมแบบละเอียดที่นี่](http://jsrocks.org/2015/01/temporal-dead-zone-tdz-demystified) ถ้าคุณต้องการ\n\nเพิ่มเติม คุณไม่สามารถประกาศตัวแปรที่ประกาศด้วย *let* ซ้ำได้:\n\n```js\nlet myVar = 2;\nlet myVar = 3; // เกิด SyntaxError\n```\n\n##### const\n\nการประกาศตัวแปรโดยใช้ ```const``` จะเหมือนกับ *let* แต่ต่างตรงที่พวกมันจะไม่สามารถ assign ค่าซ้ำได้\n\nสรุปสั้นๆ สำหรับตัวแปรที่ประกาศแบบ *const*:\n\n- เป็น *block scoped*\n- ไม่สามารถเข้าถึงได้ก่อนถูก assign ค่า\n- ไม่สามารถประกาศซ้ำได้ใน scope เดียวกัน\n- ไม่สามารถ assign ซ้ำได้\n\n```js\nconst myVar = \"Nick\";\nmyVar = \"John\" // เกิด error เพราะไม่สามารถ assign ค่าซ้ำได้\n```\n\n```js\nconst myVar = \"Nick\";\nconst myVar = \"John\" // เกิด error เพราะไม่สามารถประกาศตัวแปรซ้ำได้\n```\n\n<a name=\"const_mutable_sample\"></a> มีบางจุดที่ต้องระวัง: ตัวแปร ```const``` ไม่ใช่ [**immutable**](#mutation_def) ! อธิบายเพิ่มเติมคือตัวแปรที่ประกาศโดย ```const``` ที่เก็บค่าเป็น *object* และ *array* ค่าข้างใน**สามารถ**เปลี่ยนแปลงได้\n\nสำหรับ objects:\n```js\nconst person = {\n  name: 'Nick'\n};\nperson.name = 'John' // สามารถทำได้ ! ตัวแปร person ไม่ได้ถูก assign ใหม่ แต่ถูกแปลงค่าข้างใน\nconsole.log(person.name) // \"John\"\nperson = \"Sandra\" // เกิด error เพราะว่าไม่สามารถ assign ค่าซ้ำได้สำหรับตัวแปรที่ประกาศด้วย const\n```\n\nสำหรับ arrays:\n```js\nconst person = [];\nperson.push('John'); // สามารถทำได้ ! ตัวแปร person ไม่ได้ถูก assign ใหม่ แต่ถูกแปลงค่าข้างใน\nconsole.log(person[0]) // \"John\"\nperson = [\"Nick\"] // เกิด error เพราะว่าไม่สามารถ assign ค่าซ้ำได้สำหรับตัวแปรที่ประกาศด้วย const\n```\n\n#### ข้อมูลเพิ่มเติมจากภายนอก\n\n- [How let and const are scoped in JavaScript - WesBos](http://wesbos.com/javascript-scoping/)\n- [Temporal Dead Zone (TDZ) Demystified](http://jsrocks.org/2015/01/temporal-dead-zone-tdz-demystified)\n\n### <a name=\"arrow_func_concept\"></a> Arrow ฟังก์ชั่น\n\nใน JavaScript อัปเดต ES6 มี *arrow ฟังก์ชั่น* ซึ่งเป็นการประกาศและใช้ฟังก์ชั่นในรูปแบบใหม่ และมีความสามารถที่มาเพิ่มเติมดังนี้\n\n- เขียนสั้นกระชับมากขึ้น\n- *this* อ้างอิงถึงภายนอกรอบๆ\n- การ return ค่าทันทีได้แบบตรงไปตรงมา\n\n#### ตัวอย่างโค้ด\n\n- การ return ที่สั้นกระชัดและตรงไปตรงมามากขึ้น\n\n```js\nfunction double(x) { return x * 2; } // วิธีปกติ\nconsole.log(double(2)) // 4\n```\n\n```js\nconst double = x => x * 2; // ฟังก์ชั่นเดียวกันที่เปลี่ยนมาเขียนโดยใช้ arrow ฟังก์ชั่นและ return ทันที\nconsole.log(double(2)) // 4\n```\n\n- การอ้างอิงเมื่อใช้ *this*\n\nใน arrow ฟังก์ชั่น *this* จะอ้างอิงถึงค่าของ *this* ที่อยู่บริบทที่ครอบอยู่ พูดง่ายๆ คือเมื่อใช้ arrow ฟังก์ชั่นคุณไม่จำเป็นต้องทำทริค \"that = this\" ก่อนเรียกฟังก์ชั่นอื่นภายในฟังก์ชั่นอีกทีอีกต่อไป\n\n```js\nfunction myFunc() {\n  this.myVar = 0;\n  setTimeout(() => {\n    this.myVar++;\n    console.log(this.myVar) // 1\n  }, 0);\n}\n```\n\n#### อธิบายรายละเอียด\n\n##### การย่อสั้น\n\nArrow ฟังก์ชั่นจะสั้นกระชับกว่าฟังก์ชั่นแบบปกติทั่วไป ลองมาดูวิธีการเขียนแบบที่สามารถเขียนได้ดังนี้:\n\n- Implicit VS Explicit return\n\n**Explicit return** หมายถึง function ที่ต้องมีการใช้คีย์เวิร์ด *return* ข้างในตัวมัน\n\n```js\n  function double(x) {\n    return x * 2; // ฟังก์ชั่นนี้เป็น explicitly returns x * 2, ดังนั้นต้องมีคีย์เวิร์ด *return*\n  }\n```\n\nโดยวิธีเขียนฟังก์ชั่นแบบปกติแล้ว การ return จะเป็น explicit จะเสมอ แต่สำหรับ arrow ฟังก์ชั่นคุณสามารถทำ *implicit return* ซึ่งหมายความว่าคุณไม่จำเป็นต้องใช้คีย์เวิร์ด *return* เพื่อ return ค่าได้เลย\n\nในการเขียน implicit return จะทำให้สามารถเขียนโค้ดได้เหลือเพียง 1 บรรทัด\n\n```js\n  const double = (x) => {\n    return x * 2; // Explicit return ตรงนี้\n  }\n```\n\nเมื่อมันทำแค่ return ค่าตรงนั้นทันที เราสามารถเขียนแบบ implicit return ได้ข้างล่าง\n\n```js\n  const double = (x) => x * 2;\n```\n\nและจากข้างบน ที่เราต้องทำมีแค่ **เอาปีกกา** กับคีย์เวิร์ด **return** ออก แบบนี้เลยเรียกว่า *implicit* return เพราะว่าไม่จำเป็นต้องใช้คีย์เวิร์ด return แต่ฟังก์ชั่นก็ยัง return ```x * 2``` อยู่\n\n> **หมายเหตุ:** ถ้าฟังก์ชั่นของคุณไม่ได้ต้องการการ return ค่า (พร้อมกับ *side effects*) จะใช้แบบไหนก็ไม่ต่างกัน\n\nนอกจากนี้ ถ้าคุณใช้ implicit return ค่าเป็น *object* คุณ**ต้องใช้วงเล็บครอบ** เพื่อป้องกันการสับสนกับ block scope ตามข้างล่าง\n\n```js\nconst getPerson = () => ({ name: \"Nick\", age: 24 })\nconsole.log(getPerson()) // { name: \"Nick\", age: 24 } -- object implicitly return ค่าโดยใช้ arrow function\n```\n\n- มี argument แค่ตัวเดียว\n\nถ้า function รับ parameter เพียงแค่ตัวเดียว สามารถเอาวงเล็บออกได้ ถ้าเราปรับปรุงจากโค้ด *double* ก่อนหน้าจะได้ดังนี้\n\n```js\n  const double = (x) => x * 2; // arrow ฟังก์ชั่นนี้รับเพียง 1 parameter\n```\n\nวงเล็บสามารถเอาออกได้ดังนี้:\n\n```js\n  const double = x => x * 2; // arrow ฟังก์ชั่นนี้รับเพียง 1 parameter\n```\n\n- ไม่มี argument\n\nเมื่อไม่ต้องการ argument ใดๆ เลยใน arrow function คุณจำเป็นต้องใส่วงเล็บ ไม่อย่างนั้นมันจะไม่ใช่ syntax ที่ถูกต้อง\n\n```js\n  () => { // ถ้ามีวงเล็บ ทุกอย่างจะปกติ\n    const x = 2;\n    return x;\n  }\n```\n\n```js\n  => { // ถ้าไม่มีวงเล็บ จะใช้งานไม่ได้!\n    const x = 2;\n    return x;\n  }\n```\n\n##### การอ้างอิงของ *this*\n\nเพื่อที่จะเข้าใจเรื่อง this กับ arrow ฟังก์ชั่นคุณต้องเข้าใจก่อนว่า [this](#this_def) ทำงานยังไงใน JavaScript\n\nใน arrow function *this* มีค่าเท่าที่ค่าของ *this* ที่เป็นบริบทที่ครอบมันอยู่ นั่หมายถึงว่า arrow ฟังก์ชั่นไม่สร้าง *this* ขึ้นมาใหม่ แต่ว่ามันเอาค่าที่อยู่รอบนอกของมันมาใช้แทน\n\nถ้าไม่ใช่ arrow ฟังก์ชั่นถ้าคุณต้องการใช้งานตัวแปร *this* ของฟังก์ชั่นเมื่ออยู่ภายใน function อีกที เพื่ออ้างอิงถึง *this* ภายนอก คุณจะต้องใช้ *that = this* หรือว่า *self = this* เป็นทริคเพื่ออ้างอิงถึง\n\nยกตัวอย่างเช่น เมื่อใช้ฟังก์ชั่น setTimeout ภายใน myFunc:\n\n```js\nfunction myFunc() {\n  this.myVar = 0;\n  var that = this; // ทริค that = this\n  setTimeout(\n    function() { // *this* ใหม่ถูกสร้างภายใน function scope นี้\n      that.myVar++;\n      console.log(that.myVar) // 1\n\n      console.log(this.myVar) // undefined -- เพราะว่าไปหาที่ฟังก์ชั่นที่อยู่นี้ ไม่ใช่ myFunc\n    },\n    0\n  );\n}\n```\n\nแต่เมื่อใช้ arrow ฟังก์ชั่น *this* จะอ้างอิงถึงที่อยู่รอบๆ ตัวมัน:\n\n```js\nfunction myFunc() {\n  this.myVar = 0;\n  setTimeout(\n    () => { // this มาจากรอบๆ นั่นหมายถึง myFunc ในกรณีนี้\n      this.myVar++;\n      console.log(this.myVar) // 1\n    },\n    0\n  );\n}\n```\n\n#### หล่งข้อมูลที่มีประโยชน์\n\n- [Arrow functions introduction - WesBos](http://wesbos.com/arrow-functions/)\n- [JavaScript arrow function - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions)\n- [Arrow function and lexical *this*](https://hackernoon.com/javascript-es6-arrow-functions-and-lexical-this-f2a3e2a5e8c4)\n\n### ค่า Default Parameter ของฟังก์ชั่น\n\nตั้งแต่อัปเดตของ ES2015 JavaScript คุณสามารถตั้งค่า default ให้กับ parameter ของฟังก์ชั่นได้แล้วโดยใช้ syntax ตามข้างล่างนี้:\n\n```js\nfunction myFunc(x = 10) {\n  return x;\n}\nconsole.log(myFunc()) // 10 -- ไม่ได้มีค่าโยนเข้าไปใน parameter ดังนั้นค่า x จะถูก assign เป็นค่า default ของ myFunc นั่นก็คือ 10\nconsole.log(myFunc(5)) // 5 -- มีค่าโยนเข้าไปใน paramter ดังนั้นค่า x จะมีค่าเท่ากับ 5 ใน myFunc\n\nconsole.log(myFunc(undefined)) // 10 -- โยนค่าเป็น undefined ไป ดังนั้นจะนำค่า default มาใช้ซึ่งก็คือ 10\nconsole.log(myFunc(null)) // null -- โยนค่า null เข้าไปจึงได้ค่า x เป็น null, ดูรายละเอียดเพิ่มเติมข้างล่าง\n```\n\nค่า default paramter จะถูกเรียกใช้ในสองกรณีนี้เท่านั้น:\n\n- ไม่โย parameter มาให้\n- รับค่า parameter เป็น *undefined*\n\nหรือในอีกความหมายนึงคือ ถ้าคุณส่งค่าเป็น *null* จะไม่มีการใช้งาน default parameter\n\n> **หมายเหตุ:** ค่า Default สามารถใช้ร่วมกับ destructured parameters ได้ (อันนี้จะอยู่ในเนื้อห้าถัดไป)\n\n#### ข้อมูลเพิ่มเติมจากภายนอก\n\n- [Default parameter value - ES6 Features](http://es6-features.org/#DefaultParameterValues)\n- [Default parameters - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters)\n\n### Destructuring objects และ arrays\n\n*Destructuring* เป็นวิธีในการสร้างตัวแปรใหม่จากการแยกค่าบางค่าจากข้างในของ objects หรือ arrays ซึ่งทำให้สะดวกมากยิ่งขึ้น\n\nยกตัวอย่างสำหรับการใช้งานเช่น *destructuring* สามารถใช้ในการแยกส่วน parameters ของฟังก์ชั่น หรือว่า *this.props* ที่มักเจอประจำในโปรเจ็คที่เป็น React\n\n#### อธิบายตัวอย่างโค้ด\n\n- Object\n\nลองพิจารณา object ข้างล่างเป็นตัวอย่าง:\n\n```js\nconst person = {\n  firstName: \"Nick\",\n  lastName: \"Anderson\",\n  age: 35,\n  sex: \"M\"\n}\n```\n\nเมื่อไม่ใช้ destructuring:\n\n```js\nconst first = person.firstName;\nconst age = person.age;\nconst city = person.city || \"Paris\";\n```\n\nเมื่อใช้ destructuring สามารถเขียนในบรรทัดเดียวได้แบบนี้:\n\n```js\nconst { firstName: first, age, city = \"Paris\" } = person; // แบบนี้ !\n\nconsole.log(age) // 35 -- ตัวแปร age ถูกสร้างขึ้นมาใหม่และมีค่าเท่ากับ person.age\nconsole.log(first) // \"Nick\" -- ตัวแปร first ถูกสร้างขึ้นมาใหม่และมีค่าเท่ากับ person.firstName\nconsole.log(firstName) // ReferenceError -- person.firstName มีอยู่จริง แต่ตัวแปรที่ถูกสร้างขึ้นใหม่ถูกตั้งชื่อว่า first\nconsole.log(city) // \"Paris\" -- ตัวแปร city ถูกสร้างขึ้นใหม่ และ person.city มีค่าเป็น undefined เพราะฉะนั้น city จะมีค่าเท่ากับ default ที่ระบุไว้คือ \"Paris\"\n```\n\n**หมายเหตุ :** ใน ```const { age } = person;```, ปีกกาหลังคีย์เวิร์ด *const* มีได้หมายถึงเป็นการประกาศ object หรือว่า block แต่มันหมายถึงเป็น *destructuring* syntax\n\n- Parameters ของฟังก์ชั่น\n\n*Destructuring* จะใช้บ่อยในการ destructure objects parameters ในฟังก์ชั่น\n\nถ้าไม่มี 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); // \"Nick-Anderson\"\n```\n\n*person* สามารถทำ destructuring เพื่อให้สั้นกระชับขึ้นได้ดังนี้:\n\n```js\nfunction joinFirstLastName({ firstName, lastName }) { // สร้างตัวแปร firstName กับ lastName โดยการ destructuring ตัวแปร\n  return firstName + '-' + lastName;\n}\n\njoinFirstLastName(person); // \"Nick-Anderson\"\n```\n\nDestructuring ยังถูกใช้บ่อยควบคู่กับ [arrow ฟังก์ชั่น](#arrow_func_concept):\n\n```js\nconst joinFirstLastName = ({ firstName, lastName }) => firstName + '-' + lastName;\n\njoinFirstLastName(person); // \"Nick-Anderson\"\n```\n\n- Array\n\nจาก array ข้างล่างต่อไปนี้:\n\n```js\nconst myArray = [\"a\", \"b\", \"c\"];\n```\n\nเมื่อไม่มี destructuring\n\n```js\nconst x = myArray[0];\nconst y = myArray[1];\n```\n\nเมื่อมี destructuring\n\n```js\nconst [x, y] = myArray; // แบบนี้ !\n\nconsole.log(x) // \"a\"\nconsole.log(y) // \"b\"\n```\n\n#### แหล่งข้อมูลที่มีประโยชน์\n\n- [ES6 Features - Destructuring Assignment](http://es6-features.org/#ArrayMatching)\n- [Destructuring Objects - WesBos](http://wesbos.com/destructuring-objects/)\n- [ExploringJS - Destructuring](http://exploringjs.com/es6/ch_destructuring.html)\n\n### Array methods - map / filter / reduce\n\n*Map*, *filter* และ *reduce* เป็น method ของ array ที่มาจาก programming paradigm ที่ชื่อว่า [*functional programming*](https://medium.com/javascript-scene/master-the-javascript-interview-what-is-functional-programming-7f218c68b3a0).\n\nสรุปแบบสั้นๆ:\n\n- **Array.prototype.map()** นำ array มาวนลูป ทำอะไรบางอย่างกับค่าของมันแต่ละค่าแล้ว return กลับกลายเป็น array ที่แปลงค่าแล้ว.\n- **Array.prototype.filter()** นำ array มาวนลูป เลิอกว่าค่าไหนเก็บไว้และค่าไหนทิ้ง และ return กลับไปเป็น array ที่ถูกเลือกแล้ว\n- **Array.prototype.reduce()** นำ array มาวนลูปและประกอบกันแต่ละค่าเหลือเพียงค่าเดียวเพื่อ return กลับไป\n\nแนะนำให้ใช้พวกนี้มากที่สุดเท่าที่จะทำได้ตามทฤษฐีของ functional programming เพราะว่ามันสั้นกระชับและสวยกว่า\n\nเมื่อมี 3 methods นี้ คุณสามารถละการใช้ *for* และ *forEach* ลูปในสถานการณ์ส่วนใหญ่ได้ เมื่อคุณจะใช้ *for* ลูป ลองเปลี่ยนมาใช้ *map*, *filter* และ *reduce* แทน แรกๆ อาจจะติดเพราะว่าต้องเปลี่ยนวิธีในการคิดแต่หลังจากเข้าใจและใช้ไปซักระยะจะสามารถใช้งานได้อย่างง่ายดาย\n\n#### ตัวอย่างโค้ด\n\n```js\nconst numbers = [0, 1, 2, 3, 4, 5, 6];\nconst doubledNumbers = numbers.map(n => n * 2); // [0, 2, 4, 6, 8, 10, 12]\nconst evenNumbers = numbers.filter(n => n % 2 === 0); // [0, 2, 4, 6]\nconst sum = numbers.reduce((prev, next) => prev + next, 0); // 21\n```\n\nคำนวณผลรวมเกรดทั้งหมดของนักเรียนโดยใช้ map, filter และ 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) // เรา map ข้อมูลนักเรียนให้กลายเป็น array ที่มีแต่เกรด\n  .filter(grade => grade >= 10) // เรา filter เกรดให้เก็บไว้เฉพาะที่มีค่ามากกว่าเท่ากับ 10\n  .reduce((prev, next) => prev + next, 0); // เรารวมผลรวมของทุกเกรดทีละคน\n\nconsole.log(aboveTenSum) // 44 -- 10 (Nick) + 15 (John) + 19 (Julia), Nathalie ได้เกรดต่ำกว่า 10 จะถูกข้ามไป\n```\n\n#### อธิบาย\n\nลองดู array ของตัวเลขต่อไปนี้ที่จะใช้ในตัวอย่าง:\n\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); // [0, 2, 4, 6, 8, 10, 12]\n```\n\nเกิดอะไรขึ้นในข้างบนบ้าง? เราใช้ .map กับ array ที่เก็บ *ตัวเลข* โดย map จะทำการวนรอบ (iterate) ทุกๆ ค่าที่อยู่ภายใน array และส่งค่าต่อเข้าไปในฟังก์ชั่นของเรา เป้าหมายของฟังก์ชั่นนี้คือต้องการสร้างค่าใหม่จากค่าเดิมที่ส่งเข้ามาและส่งกลับไป\n\nถ้ากระจายฟังก์ชั่นให้อ่านง่ายขึ้นจะเป็นตามภาพดังนี้:\n\n```js\nconst doubleN = function(n) { return n * 2; };\nconst doubledNumbers = numbers.map(doubleN);\nconsole.log(doubledNumbers); // [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)]``` จะเท่ากับ ```[0, 2, 4, 6, 8, 10, 12]```.\n\n> **หมายเหตุ:** ถ้าคุณไม่ต้องการ return array ใหม่ แต่ต้องการทำลูปที่สร้าง side effects การใช้ for / forEach ลูปน่าจะเหมาะมากกว่าใช้ map\n\n##### Array.prototype.filter()\n\n```js\nconst evenNumbers = numbers.filter(function(n) {\n  return n % 2 === 0; // ถ้า n เป็นเลขคู่จะเป็น true, และ false ถ้า n ไม่ใช่\n});\nconsole.log(evenNumbers); // [0, 2, 4, 6]\n```\n\nเราใช้ .filter กับ array ที่เก็บ *ตัวเลข* ชุดเดิม, filter จะทำการวนรอบ (iterate) ทุกค่าใน array และส่งเข้าไปในฟังก์ชั่นของเรา เป้าหมายของฟังก์ชั่นนี้คือการ return เป็น boolean ว่าค่านั้นๆ จะต้องการเก็บเอาไว้หรือทิ้ง ผลสุดท้ายของ filter จะ return array ที่เหลือแต่ค่าที่เลือกเก็บเท่านั้น\n\n##### Array.prototype.reduce()\n\nreduce method จะทำหน้าที่ *reduce* ทุกค่าใน array โดยมันจะวนรอบ (iterate) ค่าทั้งหมดให้กลายเหลือเป็นค่าเดียว โดยวิธีการประกอบค่าต่างๆ ยังไงอยู่ที่เรากำหนดในฟังก์ชั่น\n\n```js\nconst sum = numbers.reduce(\n  function(acc, n) {\n    return acc + n;\n  },\n  0 // ตัวสะสมค่าตัวแปรสำหรับการวนลูปรอบแรก\n);\n\nconsole.log(sum) //21\n```\n\nเหมือนกับ method ของ .map และ .filter เพียงแต่ว่า .reduce จะนำค่าที่ได้จากรอบก่อนหน้ามาส่งต่อเป็น parameter แรกของฟังก์ชั่น\n\nมาดูความแตกต่าง:\n\n- .reduce รับ parameter สองตัว\n\nparameter แรกจะเป็นฟังก์ชั่นสำหรับการวนรอบ (itelation)\n\nparameter ที่สองจะเป็นค่าตัวแปรสะสม (ในที่นี้หมายถึง *acc*) สำหรับการวนรอบรอบแรก (คำข้อถัดไปจะมีอธิบายว่าทำไมต้องมี)\n\n- Parameters ของฟังก์ชั่น\n\nฟังก์ชั่นที่ส่งเข้าไปใน parameter แรกของ .reduce จะได้รับ parameter ทั้งหมด 2 ตัว โดยตัวแรก (ในที่นี้คือ *acc*) คือตัวแปรสะสม ในขณะที่ตัวแปรที่สอง (*n*) คือค่าปัจจุบันของรอบลูปนั้นๆ\n\nตัวแปรสะสมจะเท่ากับค่าที่ return ในฟังก์ชั่นของการวนรอบ (iteration) ก่อนหน้า ในการวนรอบแรก *acc* จะมีค่าเท่ากับค่าที่คุณส่งเป็น parameter ที่สองให้กับ .reduce นั่นเลยจำเป็นต้องโยนค่า 0 เข้าไปเป็น parameter ที่สองของ reduce นั่นเอง\n\n###### ในการวนรอบรอบแรก\n\n```acc = 0``` เพราะเราส่งค่า 0 เป็น parameter ที่สองให้กับ reduce\n\n```n = 0``` ค่าแรกของ array ที่เก็บ *ตัวเลข*\n\nฟังก์ชั่นจะ returns *acc* + *n* --> 0 + 0 --> 0\n\n###### ในการวนรอบรอบที่สอง\n\n```acc = 0``` เพราะว่ามันคือค่าที่มาจากการ return ของฟังก์ชั่นในการวนรอบก่อนหน้า\n\n```n = 1``` ค่าที่สองของ array ที่เก็บ *ตัวเลข*\n\nฟังก์ชั่นจะ returns *acc* + *n* --> 0 + 1 --> 1\n\n###### ในการวนรอบรอบที่สาม\n\n```acc = 1``` เพราะว่ามันคือค่าที่มาจากการ return ของฟังก์ชั่นในการวนรอบก่อนหน้า\n\n```n = 2``` ค่าที่สามของ array ที่เก็บ *ตัวเลข*\n\nฟังก์ชั่นจะ returns *acc* + *n* --> 1 + 2 --> 3\n\n###### ในการวนรอบรอบที่สี่\n\n```acc = 3``` เพราะว่ามันคือค่าที่มาจากการ return ของฟังก์ชั่นในการวนรอบก่อนหน้า\n\n```n = 3``` ค่าที่สี่ของ array ที่เก็บ *ตัวเลข*\n\nฟังก์ชั่นจะ returns *acc* + *n* --> 3 + 3 --> 6\n\n###### [...] ในการวนรอบสุดท้าย\n\n```acc = 15``` เพราะว่ามันคือค่าที่มาจากการ return ของฟังก์ชั่นในการวนรอบก่อนหน้า\n\n```n = 6``` ค่าสุดท้ายของ array ที่เก็บ *ตัวเลข*\n\nฟังก์ชั่นจะ returns *acc* + *n* --> 15 + 6 --> 21\n\nในการวนรอบสุดท้าย **.reduce** จะคืนค่า 21 กลับไป\n\n#### ข้อมูลเพิ่มเติมภายนอก\n\n- [Understanding map / filter / reduce in JS](https://hackernoon.com/understanding-map-filter-and-reduce-in-javascript-5df1c7eee464)\n\n### Spread operator \"...\"\n\nspread operator ```...``` เป็นของใหม่ใน ES2015 และใช้สำหรับแผ่ขยายค่าของสิ่งที่สามารถนำมาวนรอบได้ (อย่างเช่น array) แตกออกเป็นชิ้นๆ และนำไปใส่ที่อื่น\n\n#### โค้ดตัวอย่าง\n\n```js\nconst arr1 = [\"a\", \"b\", \"c\"];\nconst arr2 = [...arr1, \"d\", \"e\", \"f\"]; // [\"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// \"a\"\n// \"b\"\n// [\"c\", \"d\", \"e\", \"f\"]\n```\n\n```js\nconst { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };\nconsole.log(x); // 1\nconsole.log(y); // 2\nconsole.log(z); // { a: 3, b: 4 }\n\nconst n = { x, y, ...z };\nconsole.log(n); // { x: 1, y: 2, a: 3, b: 4 }\n```\n\n#### อธิบาย\n\n##### ใช้กับสิ่งที่สามารถวนลูปได้ (iterables) (แบบ arrays)\n\nถ้าเรามี array สองตัวดังนี้:\n\n```js\nconst arr1 = [\"a\", \"b\", \"c\"];\nconst arr2 = [arr1, \"d\", \"e\", \"f\"]; // [[\"a\", \"b\", \"c\"], \"d\", \"e\", \"f\"]\n```\n\nใน *arr2* ค่าแรกจะเป็น array เพราะว่า *arr1* ถูกนำเข้าไปใส่ใน *arr2* แต่ถ้าเราต้องให้ *arr2* เป็น array ของตัวอักษรเพียงอย่างเดียว สิ่งที่เราต้องทำคือเราสามารถ *spread* ค่าต่างๆ ของ *arr1* เข้าไปสู่ *arr2*\n\nเมื่อใช้ spread operator\n\n```js\nconst arr1 = [\"a\", \"b\", \"c\"];\nconst arr2 = [...arr1, \"d\", \"e\", \"f\"]; // [\"a\", \"b\", \"c\", \"d\", \"e\", \"f\"]\n```\n\n##### Rest parameter ของฟังก์ชั่น\n\nใน parameter ของฟังก์ชั่นเราสามารถใช้ rest operator สำหรับรวม parameters เป็น array ที่เราสามารถนำไปวนลูปได้ ถ้าเทียบก็เหมือนการห่อ **arguments** ที่รับมาเป็น object เอาไว้\n\n```js\nfunction myFunc() {\n  for (var i = 0; i < arguments.length; i++) {\n    console.log(arguments[i]);\n  }\n}\n\nmyFunc(\"Nick\", \"Anderson\", 10, 12, 6);\n// \"Nick\"\n// \"Anderson\"\n// 10\n// 12\n// 6\n```\n\nแต่ถ้าเราต้องการให้ function นี้สร้าง student ใหม่พร้อมกับ grade ทั้งหมดของนักเรียนและค่าเฉลี่ยเกรด จะง่ายกว่าถ้าเราแยกให้สอง parameter แรกเป็นตัวแปรแยก และที่เหลือจากนั้นเป็น grade ที่เราสามารถนำไปวนรอบ (itelate) ได้มันน่าจะดีกว่ารึเปล่า?\n\nและ rest operator ทำให้เราสามารถทำแบบนั้นได้!\n\n```js\nfunction createStudent(firstName, lastName, ...grades) {\n  // firstName = \"Nick\"\n  // lastName = \"Anderson\"\n  // [10, 12, 6] -- \"...\" นำ paramters ที่รับเข้ามาที่เหลือสร้างเป็นตัวแปร array ชื่อ \"grades\"\n\n  const avgGrade = grades.reduce((acc, curr) => acc + curr, 0) / grades.length; // คำนวณค่าเฉลี่ยของ 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// {\n//   firstName: \"Nick\",\n//   lastName: \"Anderson\",\n//   grades: [10, 12, 6],\n//   avgGrade: 9,33\n// }\n```\n\n> **หมายเหตุ:** ฟังก์ชั่น createStudent ยังไม่ดีเท่าไหร่เพราะว่าเรายังไม่ได้เช็ก grades.length ในกรณีที่ไม่มีค่าอยู่จริงหรือไม่ใช่ 0 แต่มันง่ายกว่าถ้าเขียนแบบนี้เพื่อทำความเข้าใจ เพราะฉะนั้นในโค้ดตัวอย่างเลยจะไม่มีการจัดการกับกรณีนี้\n\n##### Object properties spreading\n\nก่อนจะเข้าเรื่องนี้ แนะนำให้อ่านคำอธิบายก่อนหน้าสำหรับ rest operator ที่ทำการห่อ parameter กลายเป็น object ที่สามารถทำการวนลูปได้ (itelable)\n\n```js\nconst myObj = { x: 1, y: 2, a: 3, b: 4 };\nconst { x, y, ...z } = myObj; // object destructuring ตรงนี้\nconsole.log(x); // 1\nconsole.log(y); // 2\nconsole.log(z); // { a: 3, b: 4 }\n\n// z จะได้ค่าที่เหลือของ object ที่ถูก destructured แล้ว: myObj object เมื่อลบค่า x และ y properties ที่ถูก destructured ออกไปแล้ว\n\nconst n = { x, y, ...z };\nconsole.log(n); // { x: 1, y: 2, a: 3, b: 4 }\n\n// เมื่อนำ z object มา spread กลับเข้าไปให้กับตัวแปร n จะได้ค่าดังเดิม\n```\n\n#### ข้อมูลเพิ่มเติมจากภายนอก\n\n- [TC39 - Object rest/spread](https://github.com/tc39/proposal-object-rest-spread)\n- [Spread operator introduction - WesBos](https://github.com/wesbos/es6-articles/blob/master/28%20-%20Spread%20Operator%20Introduction.md)\n- [JavaScript & the spread operator](https://codeburst.io/javascript-the-spread-operator-a867a71668ca)\n- [6 Great uses of the spread operator](https://davidwalsh.name/spread-operator)\n\n### Object property shorthand\n\nเมื่อ assign ค่าใช้ตัวแปรเป็น object property ถ้าชื่อตัวแปรมีค่าเท่ากับชื่อ property คุณสามารถทำแบบนี้ได้:\n\n```js\nconst x = 10;\nconst myObj = { x };\nconsole.log(myObj.x) // 10\n```\n\n#### อธิบาย\n\nปกติแล้ว (pre-ES2015) เมื่อคุณประกาศ *object literal* ใหม่ และต้องการใช้ค่าของตัวแปรไปเป็นค่าให้กับ object properties นั้นปกติแล้วต้องเขียนแบบนี้:\n\n```js\nconst x = 10;\nconst y = 20;\n\nconst myObj = {\n  x: x, // assign ค่าของตัวแปร x ให้เป็นค่าของ myObj.x\n  y: y // assign ค่าของตัวแปร y ให้เป็นค่าของ myObj.y\n};\n\nconsole.log(myObj.x) // 10\nconsole.log(myObj.y) // 20\n```\n\nจะเห็นว่ามันซ้ำซ้อนกันเพราะว่าชื่อ properties ของ myObj เป็นชื่อเดียวกับตัวแปรที่ต้องการ assign ให้กับ properties เหล่านั้น\n\nเมื่อเขียนด้วย ES2015 เมื่อชื่อตัวแปรเป็นชื่อเดียวกับชื่อ property สามารถเขียนให้สั้นลงเป็นแบบนี้ได้:\n\n```js\nconst x = 10;\nconst y = 20;\n\nconst myObj = {\n  x,\n  y\n};\n\nconsole.log(myObj.x) // 10\nconsole.log(myObj.y) // 20\n```\n\n#### ข้อมูลเพิ่มเติมจากภายนอก\n\n- [Property shorthand - ES6 Features](http://es6-features.org/#PropertyShorthand)\n\n### Promises\n\nPromise เป็น object ที่สามารถ return ค่าแบบ synchronous จากฟังก์ชั่นที่เป็น asynchronous ได้ ([ref](https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-promise-27fc71e77261#3cd0)).\n\nPromise สามารถใช้เพื่อแก้ปัญหาของ [callback hell](http://callbackhell.com/) และมันมักนำไปใช้ในโค้ด Javascript โปรเจ็คใหม่ๆ ที่ทันสมัย\n\n#### ตัวอย่างโค้ด\n\n```js\nconst fetchingPosts = new Promise((res, rej) => {\n  $.get(\"/posts\")\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#### อธิบาย\n\nเมื่อคุณสร้าง *Ajax request* จะได้รับ response ที่ไม่ synchronous เพราะว่ามันต้องใช้เวลาเพื่อจะได้ผลลัพธ์ที่กลับมา และมันอาจจะไม่ได้ค่าที่ต้องการกลับมาถ้า request ที่ส่งไปไม่สามารถใช้งานได้ด้วยเหตุบางประการ (404)\n\nเพื่อรับมือกับสถานการณ์แบบนั้น ES2015 ได้มี *promises* ซึ่ง promise มีทั้งหมด 3 states ด้วยกัน:\n\n- Pending\n- Fulfilled\n- Rejected\n\nหรือพูดอีกอย่างว่าเราต้องการใช้ promise ไปการจัดการกับพวก Ajax request เพื่อดึงข้อมูลจาก X\n\n##### การสร้าง promise\n\nก่อนที่เราจะใช้ promise เราจะใช้ jQuery สำหรับการทำ Ajax request ไปหา X\n\n```js\nconst xFetcherPromise = new Promise( // สร้าง promise โดยใช้คีย์เวิร์ด \"new\" และเก็บลงตัวแปร\n  function(resolve, reject) { // constructor ของ promise รับ parameter เป็นฟังก์ชั่นที่มี parameter ชื่อ resolve และ reject ด้วยตัวมันเอง\n    $.get(\"X\") // ส่ง Ajax request\n      .done(function(X) { // เมื่อ request เสร็จแล้ว ...\n        resolve(X); // ... resolve promise ด้วยค่า X กลับไปเป็น parameter\n      })\n      .fail(function(error) { // ถ้า request เกิดผิดพลาด...\n        reject(error); // ... reject promise แล้วส่ง error กลับไปเป็น parameter\n      });\n  }\n)\n```\n\nจากที่เห็นในตัวอย่างข้างบน Promise object จะรับ *executor* ฟังก์ชั่นที่รับ parameter สองตัวคือ **resolve** และ **reject** ซึ่งสองตัวนี้ถ้ามีการเรียกใช้จะเป็นการย้าย state ของ promise จาก *pending* ไปสู่ *fulfilled* หรือ *rejected*\n\npromise จะอยู่ใน pending state หลังสร้าง instance และฟังก์ชั่น *executor* ของมันจะทำงานทันที และเมื่อมีการเรียกใช้ฟังก์ชั่น *resolve* หรือ *reject* ภายใน *executor* ฟังก์ชั่นตัว promise จะมีสิ่งที่เรียกว่า handlers คอยจัดการกับสิ่งที่เกิดขึ้น\n\n##### การใช้งาน Promise handlers\n\nเพื่อที่จะรับผลลัพธ์ของ promise (หรือว่า error) เราจะสามารถควบคุมด้วย handlers โดยทำได้ดังนี้:\n\n```js\nxFetcherPromise\n  .then(function(X) {\n    console.log(X);\n  })\n  .catch(function(err) {\n    console.log(err)\n  })\n```\n\nถ้า promise ทำงานสมบูรณ์และเรียกใช้ *resolve* โดยจะส่งค่าที่ได้ไปเป็น parameter ในฟังก์ชั่นใน ```.then```\n\nถ้าเกิดข้อผิดพลาด *reject* จะถูกเรียกแล้วส่งค่าไปเป็น parameter ในฟังก์ชั่นใน ```.catch```\n\n> **หมายเหตุ :** ถ้า promise เข้าไปสู่ state fulfilled หรือ rejected โดยที่มีการใช้ handler แล้ว handler จะถูกเรียกใช้ ทำให้ไม่เกิด race condition ระหว่างรอ asynchronous เสร็จสมบูรณ์กับ handlers [(Ref: MDN)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise#Description)\n\n#### ข้อมูลเพิ่มเติมจากภายนอก\n\n- [JavaScript Promises for dummies - Jecelyn Yeen](https://scotch.io/tutorials/javascript-promises-for-dummies)\n- [JavaScript Promise API - David Walsh](https://davidwalsh.name/promises)\n- [Using promises - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises)\n- [What is a promise - Eric Elliott](https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-promise-27fc71e77261)\n- [JavaScript Promises: an Introduction - Jake Archibald](https://developers.google.com/web/fundamentals/getting-started/primers/promises)\n- [Promise documentation - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)\n\n### Template literals\n\nTemplate literals เป็น [*expression interpolation*](https://en.wikipedia.org/wiki/String_interpolation) สำหรับ strings ที่สามารถทำได้ตั้งแต่บรรทัดเดียวถึงหลายบรรทัด\n\nหรือในอีกกรณีนึงก็คือ มันเป็น syntax ของ string ที่สามารถใช้ JavaScript expesssions ข้างในได้อย่างสะดวกมากขึ้น (ยกตัวอย่างเช่นแทรกตัวแปรภายใน string)\n\n#### ตัวอย่างโค้ด\n\n```js\nconst name = \"Nick\";\n`Hello ${name}, the following expression is equal to four : ${2+2}`;\n\n// Hello Nick, the following expression is equal to four: 4\n```\n\n#### ข้อมูลเพิ่มเติมจากภายนอก\n\n- [String interpolation - ES6 Features](http://es6-features.org/#StringInterpolation)\n- [ES6 Template Strings - Addy Osmani](https://developers.google.com/web/updates/2015/01/ES6-Template-Strings)\n\n### Tagged template literals\n\nTemplate tags คือ *ฟังก์ชั่นที่สามารถกลายเป็นให้กับ [template literal](#template-literals) ได้*. ถ้าฟังก์ชั่นถูกเรียกใช้แบบนี้ parameter แรกจะเป็น array ของ *strings* ที่แสดงระหว่างตัวแปรของ template's interpolated และ parameter อื่นที่ตามมาคือค่า interpolated ดังนั้นถ้าใช้ spread operator `...` ก็จะสามารถรวบรวม parameter ที่เหลือทั้งหมดได้ [(Ref: MDN)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#Tagged_template_literals).\n\n> **หมายเหตุ :** Library ชื่อดังอย่าง [styled-components](https://www.styled-components.com/) ใช้ฟีเจอร์นี้อย่างเต็มรูปแบบ\n\nข้างล่างคือตัวอย่างของการนำไปใช้งาน\n```js\nfunction highlight(strings, ...values) {\n  const interpolation = strings.reduce((prev, current) => {\n    return prev + current + (values.length ? \"<mark>\" + values.shift() + \"</mark>\" : \"\");\n  }, \"\");\n\n  return interpolation;\n}\n\nconst condiment = \"jam\";\nconst meal = \"toast\";\n\nhighlight`I like ${condiment} on ${meal}.`;\n// \"I like <mark>jam</mark> on <mark>toast</mark>.\"\n```\n\nตัวอย่างที่น่าสนใจเพิ่มเติม:\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// \"I like apples, bananas, cherries to snack on.\"\n```\n\n#### ข้อมูลเพิ่มเติมจากภายนอก\n- [Wes Bos on Tagged Template Literals](http://wesbos.com/tagged-template-literals/)\n- [Library of common template tags](https://github.com/declandewet/common-tags)\n\n### Imports / Exports\n\nES6 modules สามารถเข้าถึงตัวแปรต่างๆ ของ modules ที่ทำการแยก export ค่าต่างๆ ได้ด้วยการ imports\n\nแนะนำให้ลองอ่านข้อมูลเพิ่มเติมใน MDN resources เกี่ยวกับเรื่อง import/export (ดูข้อมูลเพิ่มเติมภายนอกข้างล่าง) จะดีเป็นอย่างมาก เนื้อหาข้างในค่อนข้างอธิบายได้ตรงไปตรงมาและสมบูรณ์แบบ\n\n#### อธิบายตัวอย่างโค้ด\n\n##### Named exports\n\nNamed exports ใช้สำหรับการ export หลายๆ ค่าของ module\n\n> **หมายเหตุ :** สามารถ export แบบ name-export [first-class citizens](https://en.wikipedia.org/wiki/First-class_citizen) ได้เฉพาะกับของที่มีชื่อเท่านั้น.\n\n```js\n// mathConstants.js\nexport const pi = 3.14;\nexport const exp = 2.7;\nexport const alpha = 0.35;\n\n// -------------\n\n// myFile.js\nimport { pi, exp } from './mathConstants.js'; // Named import -- คล้ายๆ กับ syntax destructuring\nconsole.log(pi) // 3.14\nconsole.log(exp) // 2.7\n\n// -------------\n\n// mySecondFile.js\nimport * as constants from './mathConstants.js'; // ทำค่าทั้งหมดที่มีการ exports มาเป็นตัวแปร\nconsole.log(constants.pi) // 3.14\nconsole.log(constants.exp) // 2.7\n```\n\nnamed imports จะคล้ายกับ *destructuring* แต่ว่าจริงๆ แล้วมีความต่างและไม่เหมือนกัน มันไม่รองรับการใช้ default value หรือว่า *deep* destructuring\n\nนอกจากนี้คุณสามารถทำ alias ได้อยู่ เพียงแต่ว่า syntax จะแตกต่างกับ destructuring เป็นรูปแบบตามข้างล่าง\n\n```js\nimport { foo as bar } from 'myFile.js'; // foo ถูก import เข้ามาและเอาไปเป็นค่าตัวแปรใหม่ที่ชื่อว่า bar\n```\n\n##### Default import / export\n\nสำหรับ default export เราจะสามารถ export default ได้แค่ตัวเดียวต่อ module และค่า default ที่ export สามารถเป็นได้ทั้ง function, class, object หรืออะไรก็ตาม ค่านี้เป็นเหมือนค่า \"หลัก\" ในการ export และมันจะง่ายต่อการ import เวลานำไปใช้ [Ref: MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export#Description)\n\n```js\n// coolNumber.js\nconst ultimateNumber = 42;\nexport default ultimateNumber;\n\n// ------------\n\n// myFile.js\nimport number from './coolNumber.js';\n// Default export จะอิสระในการตั้งชื่อในหน้าที่ import เข้าไปใช้งาน อย่างข้างบนจะถูกเก็บลงตัวแปรชื่อ number ซึ่งเราสามารถตั้งเองได้\nconsole.log(number) // 42\n```\n\nExport ฟังก์ชั่น:\n\n```js\n// sum.js\nexport default function sum(x, y) {\n  return x + y;\n}\n// -------------\n\n// myFile.js\nimport sum from './sum.js';\nconst result = sum(1, 2);\nconsole.log(result) // 3\n```\n\n#### ข้อมูลเพิ่มเติมจากภายนอก\n\n- [ES6 Modules in bulletpoints](https://ponyfoo.com/articles/es6#modules)\n- [Export - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export)\n- [Import - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import)\n- [Understanding ES6 Modules](https://www.sitepoint.com/understanding-es6-modules/)\n- [Destructuring special case - import statements](https://ponyfoo.com/articles/es6-destructuring-in-depth#special-case-import-statements)\n- [Misunderstanding ES6 Modules - Kent C. Dodds](https://medium.com/@kentcdodds/misunderstanding-es6-modules-upgrading-babel-tears-and-a-solution-ad2d5ab93ce0)\n- [Modules in JavaScript](http://exploringjs.com/es6/ch_modules.html#sec_modules-in-javascript)\n\n### <a name=\"this_def\"></a> JavaScript *this*\n\n*this* operator จะแตกต่างกับาภาษาอื่นๆ และโดยกรณีส่วนมากเป็นกำหนดเองว่า this จะทำงานในบริบทไหนในฟังก์ชั่น ([Ref: MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this)).\n\nเนื้อหานี้จะมีรายละเอียดที่ค่อนข้างอ่อนไหวและยากอยู่พอสมควร แนะนำให้ลองอ่านข้อมูลภายนอกเพิ่มเติมข้างล่าง ดังนั้นในที่นี้จะเขียนโดยอิงจากความเข้าใจส่วนตัวจาก[บทความที่เขียนโดย Yehuda Katz](http://yehudakatz.com/2011/08/11/understanding-javascript-function-invocation-and-this/) อีกที\n\n```js\nfunction myFunc() {\n  ...\n}\n\n// ข้างล่างจะแสดงให้เห็นค่าของ *this* ใน myFunc\n\nmyFunc.call(\"myString\", \"hello\") // \"myString\" -- ค่า parameter แรกใน .call จะถูกกำหนดเป็น *this*\n\n// ในโหมด non-strict-mode\nmyFunc(\"hello\") // window -- myFunc() เป็น syntax เหมือนกับเรียก myFunc.call(window, \"hello\")\n\n// ในโหมด strict-mode\nmyFunc(\"hello\") // undefined -- myFunc() เป็น syntax เหมือนกับเรียก myFunc.call(undefined, \"hello\")\n```\n\n```js\nvar person = {\n  myFunc: function() { ... }\n}\n\nperson.myFunc.call(person, \"test\") // person Object -- ค่า parameter แรกใน .call จะถูกกำหนดเป็น *this*\nperson.myFunc(\"test\") // person Object -- person.myFunc() เป็น syntax เหมือนกับเรียก person.myFunc.call(person, \"test\")\n\nvar myBoundFunc = person.myFunc.bind(\"hello\") // สร้างฟังก์ชั่นใหม่ที่ผูก \"hello\" เป็นค่าของ *this*\nperson.myFunc(\"test\") // person Object -- bind method ไม่มีผลใดๆ กับ method ดั้งเดิม\nmyBoundFunc(\"test\") // \"hello\" -- myBoundFunc เป็น person.myFunc ที่มี \"hello\" เป็น *this*\n```\n\n#### ข้อมูลเพิ่มเติมจากภายนอก\n\n- [Understanding JavaScript Function Invocation and \"this\" - Yehuda Katz](http://yehudakatz.com/2011/08/11/understanding-javascript-function-invocation-and-this/)\n- [JavaScript this - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this)\n\n### Class\n\nJavaScript เป็นภาษาที่เป็น [prototype-based](https://en.wikipedia.org/wiki/Prototype-based_programming) (เมื่อเปรียบเทียบกับ Java ที่เป็นภาษาที่เป็น [class-based](https://en.wikipedia.org/wiki/Class-based_programming)). ES6 ได้ทำให้ JavaScript เสมือนมี class ขึ้นมา แต่จริงๆแล้วเกิดจากการสืบทอดจาก prototype-based และ **ไม่ใช่** class-based ([ref](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes)).\n\nคำว่า *class* จะไม่เหมือนกับ class ในภาษาอื่นๆ เป็นไปได้ควรทำความเข้าใจกับ class ใน JavaScript ก่อน assume ว่ามันจะเหมือนภาษาอื่น\n\nบทความนี้ไม่ได้สอนเรื่องภาษาตั้งแต่เริ่มต้น เราเชื่อคุณรู้อยู่แล้วว่า prototypes คืออะไรและทำหน้าที่อะไร แต่ถ้ายังไม่เข้าใจเรื่องพวกนี้เรามี link บางส่วนที่จะช่วยอธิบายเพื่อให้เรื่องเหล่านี้ได้ดีมากขึ้น\n\n- [Understanding Prototypes in JS - Yehuda Katz](http://yehudakatz.com/2011/08/12/understanding-prototypes-in-javascript/)\n- [A plain English guide to JS prototypes - Sebastian Porto](http://sporto.github.io/blog/2013/02/22/a-plain-english-guide-to-javascript-prototypes/)\n- [Inheritance and the prototype chain - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain)\n\n#### ตัวอย่าง\n\nก่อนจะมี 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\nเมื่อใช้ Syntax แบบ ES6:\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'm \" + this.age;\n  }\n}\n\nconst myPerson = new Person(\"Manu\", 23);\nconsole.log(myPerson.age) // 23\nconsole.log(myPerson.stringSentence()) // \"Hello, my name is Manu and I'm 23\n```\n\n#### ข้อมูลเพิ่มเติมจากภายนอก\n\nสำหรับทำความเข้าใจ prototype:\n\n- [Understanding Prototypes in JS - Yehuda Katz](http://yehudakatz.com/2011/08/12/understanding-prototypes-in-javascript/)\n- [A plain English guide to JS prototypes - Sebastian Porto](http://sporto.github.io/blog/2013/02/22/a-plain-english-guide-to-javascript-prototypes/)\n- [Inheritance and the prototype chain - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain)\n\nสำหรับทำความเข้าใจ classes:\n\n- [ES6 Classes in Depth - Nicolas Bevacqua](https://ponyfoo.com/articles/es6-classes-in-depth)\n- [ES6 Features - Classes](http://es6-features.org/#ClassDefinition)\n- [JavaScript Classes - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes)\n\n### Async Await\n\nเพิ่มเติมจาก [Promises](#promises) จะมี syntax รูปแบบใหม่ให้สำหรับจัดการกับ asynchronous ชื่อว่า *async / await*\n\nจุดประสงค์ของ async/await function คือทำให้สามารถจัดการกับการใช้ promise synchronous ได้ง่ายขึ้น และทำพฤติกรรมคล้ายๆ กับ Promises ถ้าให้เปรียบเทียบคือถ้า Promises มีโครงสร้างคล้ายคลึงกับ callback สำหรับ async/await จะมีโครงสร้างคล้าย generators ผสมกับ promises นั่นเอง ซึ่ง async function จะ return เป็น Promise *เสมอ* ([Ref: MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function))\n\n> **หมายเหตุ :** ต้องเข้าใจก่อนว่า promise คืออะไร และทำงานยังไง ก่อนที่จะพยายามทำความเข้าใจ async / await\n\n> **หมายเหตุ 2:** [*await* จะต้องใช้ใน *async* function](https://hackernoon.com/6-reasons-why-javascripts-async-await-blows-promises-away-tutorial-c7ec10518dd9#f3f0), นั่นหมายความว่าคุณไม่สามารถใช้ await ใน top level ของโค้ดได้ ถ้ามันไม่ได้อยู่ใน async function.\n\n#### ตัวอย่างโค้ด\n\n```js\nasync function getGithubUser(username) { // คีย์เวิร์ด async ทำให้สามารถใช้ await ภายในฟังก์ชั่นได้ นั่นหมายถึงฟังก์ชั่นนี้ return เป็น promise\n  const response = await fetch(`https://api.github.com/users/${username}`); // Execution จะหยุดที่ตรงนี้จนกว่า promise จะ return หลังจาก fetch แล้ว resolved\n  return response.json();\n}\n\ngetGithubUser('mbeaudru')\n  .then(user => console.log(user)) // log ข้อมูล response ของ user - ไม่สามารถใช้ syntax await ได้เพราะโค้ดไม่ได้เป็น async function\n  .catch(err => console.log(err)); // ถ้า error มีการ thrown ใน async function จะสามารถ catch ได้ที่นี่\n```\n\n#### อธิบายตัวอย่างโค้ด\n\n*Async / Await* สร้างมาจาก promise แต่ว่าออกแบบมาให้เขียนในรูปแบบที่ง่ายกว่า\n\n*async* operator จะเปลี่ยนฟังก์ชั่นเป็น asynchronous และจะ return เป็น *Promise* คุณสามารถใช้ *await* operator ใน *async* function เพื่อหยุดการ execution ที่บรรทัดนั้นๆ จนกว่า Promise จะ return ค่ากลับมาโดย resolves หรือ rejects\n\n```js\nasync function myFunc() {\n  // เราสามารถใช้ await operator เพราะฟังก์ชั่นนี้กำหนดเป็น async\n  return \"hello world\";\n}\n\nmyFunc().then(msg => console.log(msg)) // \"hello world\" -- ค่าที่คืนจากฟังก์ชั่น myFunc จะถูกเปลี่ยนไปเป็น promise เพราะว่ามีการใช้ async operator\n```\n\nเมื่อถึงบรรทัด *return* ของ async function ตัว Promise ที่ได้รับค่าแล้วจะ return กลับไป ถ้าเกิด error และมีการ thrown ข้างใน async function ตัว promise state จะถูกเปลี่ยนเป็น *rejected* และถ้ากรณีไม่มีค่า return จาก async function ตัว promise จะยังคง return และ resolve แบบไม่มีค่ากลับไปเมื่อ async function ทำงานเสร็จสมบูรณ์\n\n*await* operator จะใช้สำหรับรอ *Promise* จนกว่าจะได้รับค่า และสามารถใช้ได้เฉพาะในฟังก์ชั่นที่เป็น *async* เท่านั้น เมื่อโค้ด execution มาถึงจะหยุดจนกว่า promise จะได้รับการเติมเต็มข้อมูล (fulfilled)\n\n> **หมายเหตุ :** *fetch* เป็นฟังก์ชั่นที่ return เป็น Promise ที่สามารถทำ AJAX request ได้\n\nมาดูกันว่าเราสามารถใช้ fetch ข้อมูล github user ด้วย promises ยังไงได้บ้าง:\n\n```js\nfunction getGithubUser(username) {\n  return fetch(`https://api.github.com/users/${username}`).then(response => response.json());\n}\n\ngetGithubUser('mbeaudru')\n  .then(user => console.log(user))\n  .catch(err => console.log(err));\n```\n\nและอันนี้คือถ้ากรณีใช้ *async / await* จะเป็นยังไง:\n\n```js\nasync function getGithubUser(username) { // ใช้งาน promise + await ร่วมกัน\n  const response = await fetch(`https://api.github.com/users/${username}`); // Execution จะหยุดที่นี่จนกว่าข้อมูลใน Promise จะได้รับการเติมเต็ม (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 / await* syntax ทำให้เราสามารถเขียน promise แบบ chain ได้สะดวกสบายมากขึ้น\n\nยกตัวอย่างเช่น ถ้าเราต้องการเอาค่า token ก่อนเพื่อที่จะนำข้านี้ไป fetch ข้อมูล blog post ที่อยู่ใน database เพื่อเอาข้อมูลคนเขียน post เราจะสามารถให้มันทำงานตามลำดับได้:\n\n> **หมายเหตุ :** *await* ต้องครอบด้วยวงเล็บเพื่อรอให้เรียก resolve และได้รับค่าก่อน ถึงจะนำไปใช้ต่อได้ถ้าเขียนในบรรทัดเดียวกันหรือเขียนแบบ chain\n\n```js\nasync function fetchPostById(postId) {\n  const token = (await fetch('token_url')).json().token;\n  const post = (await fetch(`/posts/${postId}?token=${token}`)).json();\n  const author = (await fetch(`/users/${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\n\nนอกจากเพิ่ม *try / catch* blocks ครอบการใช้ *await* เพื่อดัก uncaught exceptions แล้ว -  ไม่ว่าอะไรก็ตามที่ thrown ภายใน *async* function หรือว่ามันโดนยกเลิกระหว่าง *await* – จะ reject ตัว promise กลับไปใน *async* function ดังนั้นถ้าใช้ `throw` ใน async function จะเหมือนกับ return ตัว Promise ที่ rejects นั่นเอง [(Ref: PonyFoo)](https://ponyfoo.com/articles/understanding-javascript-async-await#error-handling).\n\n> **หมายเหตุ :** Promises เป็นแบบเดียวกัน!\n\nเมื่อใช้ Promises เราจะสามารถจัดการกับ error chain ได้แบบนี้:\n\n```js\nfunction getUser() { // Promise อันนี้จะโดน 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)); // \"User not found !\"\n```\n\nกรณีถ้าใช้ *async / await*:\n\n```js\nasync function getUser() { // Promise ที่จะ return กลับไปจะ 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)); // \"User not found !\"\n```\n\n#### ข้อมูลเพิ่มเติมจากภายนอก\n\n- [Async/Await - JavaScript.Info](https://javascript.info/async-await)\n- [ES7 Async/Await](http://rossboucher.com/await/#/)\n- [6 Reasons Why JavaScript’s Async/Await Blows Promises Away](https://hackernoon.com/6-reasons-why-javascripts-async-await-blows-promises-away-tutorial-c7ec10518dd9)\n- [JavaScript awaits](https://dev.to/kayis/javascript-awaits)\n- [Using Async Await in Express with Node 8](https://medium.com/@Abazhenov/using-async-await-in-express-with-node-8-b8af872c0016)\n- [Async Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)\n- [Await](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await)\n- [Using async / await in express with node 8](https://medium.com/@Abazhenov/using-async-await-in-express-with-node-8-b8af872c0016)\n\n### Truthy / Falsy\n\nใน JavaScript ค่า truthy หรือ falsy เป็นค่าที่สามารถถูก casted ไปเป็น boolean เมื่ออยู่ในบริบทที่ต้องกระประเมินค่าเป็น boolean ยกตัวอย่างบริบทของ boolean เมื่อถูกนำไปใช้ใน ```if```:\n\nค่าทั้งหมดสามารถถูก casted ไปเป็น ```true``` ยกเว้นแต่ว่ามันจะเป็นค่าเหล่านี้:\n\n- false\n- 0\n- \"\" (empty string)\n- null\n- undefined\n- NaN\n\nนี่คือตัวอย่างของ *บริบทของ boolean*:\n\n- การประเมินค่าเมื่ออยู่ใน ```if``` condition\n\n```js\nif (myVar) {}\n```\n\n```myVar``` สามารถเป็นอะไรก็ได้ [first-class citizen](https://en.wikipedia.org/wiki/First-class_citizen) (ตัวแปร, ฟังก์ชั่น, boolean) แต่มันจะถูก casted ไปเป็น boolean เพราะว่ามันกำลังถูกประเมินอยู่ในบริบทของ boolean\n\n- การใช้ **NOT** ```!``` operator\n\noperator นี้จะ return false ถ้า operand สามารถถูก convert ไปเป็น true ได้\n\n```js\n!0 // true -- 0 เป็น falsy ดังนั้นมันจะ returns true\n!!0 // false -- 0 เป็น falsy ดังนั้น !0 จะ returns true และดังนั้น !(!0) จะ returns false\n!!\"\" // false -- string ว่างเป็น falsy ดังนั้น NOT (NOT false) จะเท่ากับ false\n```\n\n- เมื่อใช้ *Boolean* object constructor\n\n```js\nnew Boolean(0) // false\nnew Boolean(1) // true\n```\n\n- ในกรณีใช้ ternary evaluation\n\n```js\nmyVar ? \"truthy\" : \"falsy\"\n```\n\nmyVar ถูกประเมินให้อยู่ในบริบทของ boolean\n\n### Static Methods\n\n#### อธิบายสั้นๆ\n\nคีย์เวิร์ด `static` สามารถใช้ใน class เพื่อประกาศเป็น static method ได้ ตัว static method เป็นฟังก์ชั่นใน class ที่เป็นของ class object และจะไม่ใช่ของตัว instance ของ class นั้นๆ\n\n#### ตัวอย่างโค้ด\n\n```js\nclass Repo{\n  static getName() {\n    return \"Repo name is modern-js-cheatsheet\"\n  }\n}\n\n//หมายเหตุ เราไม่ได้มีการสร้าง instance จาก Repo class\nconsole.log(Repo.getName()) //Repo name คือ modern-js-cheatsheet\n\nlet r = new Repo();\nconsole.log(r.getName()) //Uncaught TypeError: repo.getName is not a function\n```\n\n#### อธิบายรายละเอียด\n\nStatic method สามารถเรียก static method ตัวอื่นโดยใช้คีย์เวิร์ด `this` ได้ซึ่งจะไม่สามารถทำได้สำหรับ non-static methods และ non-static methods จะไม่สามารถเข้าถึง static method อื่นโดยใช้คีย์เวิร์ด `this` ได้\n\n##### เรียก static methods อื่นจาก static method\n\nเพื่อจะเรียก static method จาก static method อื่น ใช้คีย์เวิร์ด `this` แบบนี้ได้:\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()) //Repo name คือ modern-js-cheatsheet-added-this\n```\n\n##### เรียก static methods อื่นจาก non-static method\n\nNon-static methods สามารถเรียก static methods ได้ใน 2 ทาง;\n1. ###### ใช้ชื่อ class.\n\nเพื่อที่จะใช้ static method จาก non-static method เราใช้ชื่อ class และเรียก static method เหมือนเป็น property ตัวอย่างเช่น `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// เราต้องสร้าง instance จาก class ขึ้นมาก่อนเพื่อใช้เป็น non-static methods\nlet r = new Repo()\nconsole.log(r.useName()) //Repo name คือ modern-js-cheatsheet and it contains some really important stuff\n```\n\n2. ###### ใช้ constructor\n\nStatic methods สามารถเรียกเหมือนเป็น properties ได้ใน constructor object\n\n```js\nclass Repo{\n  static getName() {\n    return \"Repo name is modern-js-cheatsheet\"\n  }\n\n  useName(){\n    //เรียก static method เหมือนเป็น property ของ constructor\n    return this.constructor.getName() + ' and it contains some really important stuff'\n  }\n}\n\n// เราต้องสร้าง instance จาก class ขึ้นมาก่อนเพื่อใช้เป็น non-static methods\nlet r = new Repo()\nconsole.log(r.useName()) //Repo name คือ modern-js-cheatsheet and it contains some really important stuff\n```\n\n#### ข้อมูลเพิ่มเติมจากภายนอก\n- [static keyword- MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/static)\n- [Static Methods- Javascript.info](https://javascript.info/class#static-methods)\n- [Static Members in ES6- OdeToCode](http://odetocode.com/blogs/scott/archive/2015/02/02/static-members-in-es6.aspx)\n\n## คำศัพธ์\n\n### <a name=\"scope_def\"></a> Scope\n\nบริบทที่ค่าหรือ expression นั้น \"มีตัวตน\" หรือว่าสามารถอ้างอิงถึงได้ ถ้าตัวแปรหรือ expression ไม่ได้เป็น \"อยู่ใน scope นั้นๆ\" จะไม่สามารถใช้ได้\n\nแหล่งอ้างอิง: [MDN](https://developer.mozilla.org/en-US/docs/Glossary/Scope)\n\n### <a name=\"mutation_def\"></a> Variable mutation\n\nหมายถึงตัวแปรที่ถูกการแปลงค่า (mutated) จากค่าตั้งต้นและถูกเปลี่ยนในภายหลัง\n\n```js\nvar myArray = [];\nmyArray.push(\"firstEl\") // myArray กำลังถูกแปลงค่า (mutated)\n```\n\nตัวแปรจะถูกเรียกว่า *immutable* ถ้ามันไม่สามารถแปลงค่า (mutated) ได้\n\n[อ่านบทความ MDN Mutable](https://developer.mozilla.org/en-US/docs/Glossary/Mutable) สำหรับข้อมูลเพิ่มเติม\n"
  },
  {
    "path": "translations/zh-CN.md",
    "content": "# Modern JavaScript Cheatsheet 简体中文版\n\n![Modern JavaScript cheatsheet](https://i.imgur.com/aexPxMb.png)\n<small>Image Credits: [Ahmad Awais ⚡️](https://github.com/ahmadawais)</small>\n\n## 简介\n\n### 初心\n\n这份文档整理了在当前前端项目中经常需要查阅的内容，并给出了最新的代码示例。\n\n你或许会因为不熟悉当前一些新的代码库（例如 React）所用到的 JavaScript 概念，而很难上手这些新框架。所以本文档的目的并非从零教你 JavaScript，而是帮助已经有一定编程基础的你。\n\n除此之外，我（作者：[Manuel Beaudru](https://github.com/mbeaudru)）偶尔会写上一些我的小技巧，也会注意提示这只是我的个人提议。\n\n> **注：** 这篇文档里提到的大多数概念来自于目前最新的 JavaScript（ES2015，即 ES6），你可以在[这里](http://es6-features.org)查看新增的特性，网站做得很棒。\n\n### 参考材料\n\n当你觉得有的概念不容易理解时，你可以在下面的链接里面寻找答案。\n\n- [MDN (Mozilla Developer Network)](https://developer.mozilla.org/zh-CN/search?q=)\n- [You don't know JS（书）](https://github.com/getify/You-Dont-Know-JS)\n- [ES6 新特性和例子](http://es6-features.org)\n- [WesBos 博客中 ES6 类别](http://wesbos.com/category/es6/)\n- [Reddit (JavaScript)](https://www.reddit.com/r/javascript/)\n- [Google](https://www.google.com/) 可直接查找特定的博客和资源\n- [StackOverflow](https://stackoverflow.com/questions/tagged/javascript)\n\n## 目录\n\n- [Modern JavaScript Cheatsheet 简体中文版](#Modern-JavaScript-Cheatsheet-简体中文版)\n  * [简介](#简介)\n    + [初心](#初心)\n    + [参考材料](#参考材料)\n  * [目录](#目录)\n  * [正文](#正文)\n    + [变量声明: var, const, let](#变量声明-var-const-let)\n      - [简述](#简述)\n      - [代码示例](#代码示例)\n      - [详述](#详述)\n      - [延伸资料](#延伸资料)\n    + [箭头函数](#箭头函数)\n      - [简述](#简述-1)\n      - [详述](#详述-1)\n          * [简洁性](#简洁性)\n          * [*this* 关键字](#this-关键字)\n      - [相关资料](#相关资料)\n    + [方法默认参数值](#方法默认参数值)\n\n## 正文\n\n### 变量声明： var, const, let\n\n在 JavaScript 中，声明变量时可以用三个不同的关键词，分别是 `var`，`let` 以及 `const` ，它们各有异同。\n\n#### 简述\n\n用 `const` 声明的变量，不能被重新赋值，而另两个 `var` 和 `let` 是可以的。\n\n所以我建议默认情况下你都用 `const` 来声明变量，在你需要 *改变* 或是声明之后再重新指派它的时候，才用 `let` 来声明变量。\n\n\n| -     | 作用域  | 是否可重新赋值 | 是否可变                       | [暂存死区](#tdz_sample) |\n| ----- | ---- | ------- | -------------------------- | ------------------- |\n| const | 块级   | ×       | [√](#const_mutable_sample) | √                   |\n| let   | 块级   | √       | √                          | √                   |\n| var   | 函数   | √       | √                          | ×                   |\n\n#### 代码示例\n\n```javascript\nconst person = \"Nick\";\nperson = \"John\" // 因为 person 不能被重新赋值，所以会报错\n```\n\n```javascript\nlet person = \"Nick\";\nperson = \"John\";\nconsole.log(person) // \"John\", 使用 let 声明的变量可以重新赋值\n```\n\n#### 详述\n\n简单来讲，变量的作用域（[*scope*](#scope_def)）是指“在这部分代码中可以访问到此变量”。\n\n##### var\n\n使用 `var` 定义的变量，其作用域是定义它的函数内部（*function scoped*），也就是说在函数内部创建一个 `var` 变量的时候，在此函数内部可以任意访问这个变量，但在函数之外，这样的局部变量是无法被访问的。\n\n我建议你这样理解，如果一个变量是 *X 作用域（scoped）* 类型的，那就是说这个变量是 X 的属性之一。（译注：X 有 function 和 block 两类，代表函数作用域和块级作用域。）\n\n```javascript\nfunction myFunction() {\n  var myVar = \"Nick\";\n  console.log(myVar); // \"Nick\" - 在这个函数中 myVar 可被访问到\n}\nconsole.log(myVar); // 抛出错误 ReferenceError, 在函数之外 myVar 则无法访问\n```\n\n继续来看变量的作用域，下面有更多精妙的例子：\n\n```javascript\nfunction myFunction() {\n  var myVar = \"Nick\";\n  if (true) {\n    var myVar = \"John\";\n    console.log(myVar); // \"John\"\n    // 实际上 myVar 是函数级作用域变量，重新声明的时候，相当于用 \"John\" 抹去了 myVar 之前的值 \"Nick\"\n  }\n  console.log(myVar); // \"John\" - 可见 if 块中的代码会如何影响变量\n}\nconsole.log(myVar); // 抛出错误 ReferenceError, 在函数之外 myVar 则无法访问\n```\n\n另外，*var* 声明的变量在执行的时候，就像会被移动到作用域的开始，这就是我们所说的[变量声明提升（var hoisting)](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/**var)。\n\n所以看下面这段代码：\n\n```javascript\nconsole.log(myVar) // undefined -- 没有提示错误\nvar myVar = 2;\n```\n\n之所以没有发生错误，是因为它执行时会被解释为这样：\n\n```javascript\nvar myVar;\nconsole.log(myVar) // undefined -- 没有提示错误\nmyVar = 2;\n```\n\n##### let\n\n`var` 和 `let` 几乎是一样的，但是用 `let` 声明的变量有如下特性：\n\n- *块级作用域*（ block scoped )\n- 在被赋值之前，是**无法**访问使用的\n- 在同一个作用域之下，不能被重新声明\n\n我们来看看之前例子中提到的块级作用域（ block scoping ）的效果：\n\n```javascript\nfunction myFunction() {\n  let myVar = \"Nick\";\n  if (true) {\n    let myVar = \"John\";\n    console.log(myVar); // \"John\"\n    // 实际上 myVar 是块级作用域的变量，在 if 块中，我们相当于是创建了一个新变量，\n    // 这个变量在此块之外是无法被访问的，而且它完全区别于我们创建的第一个 myVar 变量！\n  }\n  console.log(myVar); // \"Nick\", 可见 if 块中的代码，并没有影响到这个变量的值\n}\nconsole.log(myVar); // 抛出错误 ReferenceError，在函数外部无法访问到 myVar。\n```\n\n<a name=\"tdz_sample\"></a>现在，来看看 *let*（和 *const* ）声明的变量在赋值前无法访问是什么意思：\n\n```javascript\nconsole.log(myVar) // 提示错误 ReferenceError !\nlet myVar = 2;\n```\n\n这就是它们和 *var* 变量的区别，如果你在还未赋值给 *let* 或者 *const* 变量之前，就想读写它，是会提示错误的。这种情况常被称作暂存死区（[*Temporal dead zone*](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/let#let_的暂存死区与错误)）或者 *TDZ*。\n\n> **注意：** 从技术上讲，*let* 和 *const* 变量声明时也存在提升，但并不代表它们的赋值也会被提升。但由于它被设计成了赋值之前无法使用，所以我们直观感觉上它没有被提升，但其实是存在提升的。如果想了解更多细节，请看[这篇文章](http://jsrocks.org/2015/01/temporal-dead-zone-tdz-demystified)。\n\n\n另外，在同一作用域内你不能重新声明一个 *let* 变量。\n\n```js\nlet myVar = 2;\nlet myVar = 3; // 提示语法错误 SyntaxError\n```\n\n##### const\n\n`const` 声明的变量很像 `let`，但它不能被重新赋值。\n\n总结一下 `const` 变量的特点如下：\n\n- *块级作用域*\n- 赋值之前无法使用\n- 在同一个作用域内部，你不能重新声明一个变量\n- 不能被重新指派\n\n```Javascript\nconst myVar = \"Nick\";\nmyVar = \"John\" // 提示错误，不允许重新赋值 const 变量\n```\n\n<a name=\"const_mutable_sample\"></a>但这里有一个小细节：`const` 变量并非完全[不可变](#mutation_def)，如果这个变量是 `object` 和 `array` 类型的值，那它的值是**可以改变**的。assign\n\n对于对象类型来说：\n\n```js\nconst person = {\n  name: 'Nick'\n};\nperson.name = 'John' // 这会生效的！person 并非完全重新指派（ reassigned ），只是值变化了（ mutated ）\nconsole.log(person.name) // \"John\"\nperson = \"Sandra\" // 提示错误，因为用 const 声明的变量不能被重新指派\n```\n\n对于数组类型来说：\n\n```js\nconst person = [];\nperson.push('John'); // 这也会生效！person 并非完全重新指派（ reassigned ），只是值变化了（ mutated ）\nconsole.log(person[0]) // \"John\"\nperson = [\"Nick\"] // 提示错误，因为用 const 声明的变量不能被重新指派\n```\n\n#### 延伸资料\n\n- [How let and const are scoped in JavaScript - WesBos](http://wesbos.com/javascript-scoping/)\n- [Temporal Dead Zone (TDZ) Demystified](http://jsrocks.org/2015/01/temporal-dead-zone-tdz-demystified)\n\n### <a name=\"arrow_func_concept\"></a> 箭头函数\n\nES6 JS 的最新版本已经介绍了*箭头函数*， 箭头函数是以另一种方式声明和使用函数。以下是箭头函数带来的一些好处：\n\n- 更加简洁\n- 从上下文获取*this*\n- 隐式的返回方式\n\n#### 简述\n\n- 简洁性和隐式的返回方式\n\n```js\nfunction double(x) { return x * 2; } // 传统函数声明方式\nconsole.log(double(2)) // 4\n```\n\n```js\nconst double = x => x * 2; // 同样的函数，使用具有隐式返回方式的箭头函数来表示\nconsole.log(double(2)) // 4\n```\n- *this* 关键字\n\n在箭头函数中， *this*的值就等于函数所处的封闭的可执行上下文的*this*。简单来说，就是在箭头函数中，当你调用一个位于函数体内部的函数时，在内部函数中，你不需要使用\"that = this\" 这样的声明语句。\n\n```js\nfunction myFunc() {\n  this.myVar = 0;\n  setTimeout(() => {\n    this.myVar++;\n    console.log(this.myVar) // 1\n  }, 0);\n}\n```\n\n#### 详述\n\n##### 简洁性\n\n箭头函数从很多方面都比传统的函数简洁。案例如下：\n\n- 隐式返回 VS 显式返回\n\n**显式返回** 指的是函数的返回语句使用了return 关键字\n\n```js\n  function double(x) {\n    return x * 2; // 使用了*return*关键字，显式返回 x * 2\n  }\n```\n\n传统函数总是伴随着显式返回。使用箭头函数，你可以使用*隐式返回*，即不需要在函数体内使用return关键字就可以返回值。\n\n隐式返回需要将所需代码写在一条语句中。\n\n```js\n  const double = (x) => {\n    return x * 2; // 显式返回\n  }\n```\n\n鉴于只返回单值，我们可以使用隐式返回。\n\n```js\n  const double = (x) => x * 2;\n```\n\n为实现隐式返回，我们只需要 **移除花括号** 和 **return** 关键字。之所以被称为*隐式*返回，是因为*return*关键字不存在的情况下，函数仍可返回 ```x * 2```。\n\n> **注意:** 如果你的函数不是返回一个单值（伴有*连带值*），那么既不可以使用显式返回也不可以使用隐式返回。\n\n除此之外， 如果你想隐式返回一个*object* 则必须使用圆括号对其修饰， \n\n```js\nconst getPerson = () => ({ name: \"Nick\", age: 24 })\nconsole.log(getPerson()) // { name: \"Nick\", age: 24 } -- 箭头函数返回的对象\n```\n\n- 函数只有一个参数\n\n如果你的箭头函数只有一个参数，你可以省略修饰参数的圆括号，重新观察上面的代码：\n\n```js\n  const double = (x) => x * 2; // 箭头函数只有一个参数\n```\n\n参数外面的圆括号可以省略:\n\n```js\n  const double = x => x * 2; // 箭头函数只有一个参数\n```\n\n- 函数无参数\n\n当箭头函数无参数时，必须使用圆括号，否则会出现语法错误.\n\n```js\n  () => { // 必须提供圆括号\n    const x = 2;\n    return x;\n  }\n```\n\n```js\n  => { // 无圆括号，错误!\n    const x = 2;\n    return x;\n  }\n```\n\n##### *this* 关键字\n\n要理解箭头函数中this的微妙之处，你必须首先了解JavaScript中[this](#this_def) 的行为。\n\n在箭头函数中， *this*的值就等于函数所处的封闭可执行上下文的*this*。这句话的意思就是箭头函数不创建一个新的*this*， 而是从其所处的上下文环境中获取。\n\n没有箭头函数，如果你想要从*this*访问函数内部的函数中的一个变量，你必须使用*that = this*或者*self = this*这样的技巧。\n\n例如, 使用位于myFunc内部的函数setTimeout:\n\n```js\nfunction myFunc() {\n  this.myVar = 0;\n  var that = this; // that = this \n  setTimeout(\n    function() { // 在函数的内部创建一个新的\n      that.myVar++;\n      console.log(that.myVar) // 1\n\n      console.log(this.myVar) // 未定义 -- 请参照上面的函数this定义\n    },\n    0\n  );\n}\n```\n\n但是一旦使用箭头函数, *this* 将从包含这个箭头函数的上下文中获取:\n\n```js\nfunction myFunc() {\n  this.myVar = 0;\n  setTimeout(\n    () => { // 从上下文中获取this, 在这里就是 myFunc\n      this.myVar++;\n      console.log(this.myVar) // 1\n    },\n    0\n  );\n}\n```\n\n#### 相关资料\n\n- [Arrow functions introduction - WesBos](http://wesbos.com/arrow-functions/)\n- [JavaScript arrow function - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions)\n- [Arrow function and lexical *this*](https://hackernoon.com/javascript-es6-arrow-functions-and-lexical-this-f2a3e2a5e8c4)\n\n#### 方法默认参数值\n\n从 ES2015 以后开始，你可以使用下面的语法，给你的方法参数来设置默认值\n\n```js\nfunction myFunc(x = 10) {\n  return x;\n}\nconsole.log(myFunc()) // 10 -- 没有值传入，所以默认的值10传给了myFunc\nconsole.log(myFunc(5)) // 5 -- 一个值被传入，所以x等于5 \nconsole.log(myFunc(undefined)) // 10 -- undefined 值提供了，所以默认值关联了x\nconsole.log(myFunc(null)) // null -- 提供了 (null) , 见一下详细解释\n```\n默认参数有且只有在以下两种情况下才会生效：\n- 没有参数提供的时候\n- *undefined* 参数被提供的时候\n\n换句话说，如果你传入*NULL* 默认值**将不会生效**\n"
  },
  {
    "path": "translations/zh-TW.md",
    "content": "<a name=\"#modern-javascript-cheatsheet\"></a>\n# Modern JavaScript Cheatsheet 繁體中文版\n\n![Modern JavaScript cheatsheet](https://i.imgur.com/aexPxMb.png)\n<small>圖片來源: [Ahmad Awais ⚡️](https://github.com/ahmadawais)</small>\n\n### 譯者的話\n> 原標題：[mbeaudru/modern-js-cheatsheet](https://github.com/mbeaudru/modern-js-cheatsheet)\n>\n> 原作者：[BEAUDRU Manuel](https://github.com/mbeaudru)\n> \n> 對於現代 JavaScript 開發而言，這篇文章整理了不少知識點，當作複習或是學習都很不錯。自己一直以來都是做為讀者的角色，很少主動為整個開源社群做些實際貢獻，這點一直感到蠻慚愧的，就像是 Sublime 是啟蒙你寫程式的第一個 editor，當你開始工作賺錢後卻遲遲不買 license 是類似的道理。趁著短暫的假日譯者盡可能的把翻譯做到盡善盡美，畢竟不是專業的，要做到信達雅的程度其實不太可能，但過程中確實查閱了不少相關資料，部分關鍵字因為怕超譯所以會在後頭括號保留原文。\n>\n> 另外也想藉著這回翻譯的經驗說點八股的，英文真的天殺的重要，能夠直接閱讀原文始終是最能理解原意的方式。整篇 cheatsheet 從意譯的角度出發，詞意有所疑問或是理解錯誤都煩請發個 Pull Request 謝謝。\n>\n> 2017/09/30 Update\n>\n> 昨天晚上收到簡體中文譯者的來信提醒，才發現原來 Issue 內早已有社群朋友 @BirkhoffLee 正在做繁體中文的翻譯 ([詳情可見此討論串](https://github.com/mbeaudru/modern-js-cheatsheet/issues/15))，真的很抱歉昨天才驚覺這件事，譯者在這裡推薦大家如果有空也可以多多瀏覽  @BirkhoffLee 翻譯過的 [機器學習動手玩](https://github.com/humphd/have-fun-with-machine-learning/blob/master/README_zh-tw.md) 以及相關專案，他也是位對於開源社群推廣非常積極的開發者。最後關於這份繁體中文文件，譯者會在這一兩天回顧下文件翻譯用詞有無需要調整的地方，確認過後便會 merge 回原作者的 repo，大概是醬。\n\n<a name=\"introduction\"></a>\n## 介紹\n\n<a name=\"motivation\"></a>\n### 動機\n\n本文檔整理了各種現代化 JavaScript 開發過程中經常使用到的腳本。\n\n該份指南的目標並不是放在幫助初學者從零基礎到入門，而是為了幫助那些因為 JavaScript 新式語法導致可能很難熟悉現代函數庫使用方式 (以 React 做為舉例) 的開發人員。\n\n此外我也會偶爾提供一些個人主觀的建議和技巧，而這些建議可能會造成部分的爭議性，但請務必留意，當我做出這些舉例時這僅僅是出自於個人的推薦作法。\n\n> **注意:** 此處介紹的大部分概念出自於 JavaScript 的語言更新 (ES2015，更多人稱其作 ES6)。你可以在[這個好地方](http://es6-features.org)找到更多添加的新功能。\n\n<a name=\"complementary-resources\"></a>\n### 配套資源\n\n當你在試圖理解一個新概念時，我建議你可以去瀏覽以下這些資源尋找解答：\n\n- [MDN (Mozilla Developer Network)](https://developer.mozilla.org/fr/search?q=)\n- [You don't know JS (book)](https://github.com/getify/You-Dont-Know-JS)\n- [ES6 Features with examples](http://es6-features.org)\n- [WesBos blog (ES6)](http://wesbos.com/category/es6/)\n- [Reddit (JavaScript)](https://www.reddit.com/r/javascript/)\n- [Google](https://www.google.com/) 搜尋特定相關主題的部落格文章和資源\n\n<a name=\"table-of-contents\"></a>\n## 目錄\n\n- [Modern JavaScript cheatsheet 繁體中文版](#modern-javascript-cheatsheet)\n  * [介紹](#introduction)\n    + [動機](#motivation)\n    + [配套資源](#complementary-resources)\n  * [目錄](#table-of-contents)\n  * [概念](#notions)\n    + [變數聲明： var, const, let](#variable-declaration-var-const-let)\n      - [簡短解釋](#short-explanation-1)\n      - [範例程式碼](#sample-code-2)\n      - [詳細說明](#detailed-explanation-3)\n      - [外部資源](#external-resource-4)\n    + [箭頭函數](#-arrow-function-4)\n      - [範例程式碼](#sample-code-5)\n      - [詳細說明](#detailed-explanation-6)\n        * [簡潔性](#concision-7)\n        * [*this* 關鍵字參照](#this-reference-8)\n      - [有用資源](#useful-resources-9)\n    + [函數預設值](#function-default-parameter-value-10)\n      - [外部資源](#external-resource-11)\n    + [objects 和 arrays 的解構](#destructuring-objects-and-arrays-12)\n      - [說明和範例程式碼](#explanation-with-sample-code-13)\n      - [有用資源](#useful-resources-14)\n    + [Array 的操作方法 - map / filter / reduce](#array-methods---map--filter--reduce-15)\n      - [範例程式碼](#sample-code-16)\n      - [說明](#explanation-17)\n        * [Array.prototype.map()](#arrayprototypemap-18)\n        * [Array.prototype.filter()](#arrayprototypefilter-19)\n        * [Array.prototype.reduce()](#arrayprototypereduce-20)\n      - [外部資源](#external-resource-21)\n    + [展開運算子 \"...\"](#spread-operator-22)\n      - [範例程式碼](#sample-code-23)\n      - [說明](#explanation-24)\n        * [迭代用法 (如同 array)](#in-iterables-like-array-25)\n        * [不定參數](#function-rest-parameter-26)\n        * [Object 屬性擴展](#object-properties-spreading-27)\n      - [外部資源](#external-resources-28)\n    + [Object 屬性簡寫](#object-property-shorthand-29)\n      - [說明](#explanation-30)\n      - [外部資源](#external-resources-31)\n    + [Promises](#promises-32)\n      - [範例程式碼](#sample-code-33)\n      - [說明](#explanation-34)\n        * [創造 promise](#create-the-promise-35)\n        * [使用 promise](#use-the-promise-36)\n      - [外部資源](#external-resources-37)\n    + [模板字符串](#template-literals-38)\n      - [範例程式碼](#sample-code-39)\n      - [外部資源](#external-resources-40)\n    + [Imports / Exports](#imports--exports-41)\n      - [說明與範例程式碼](#explanation-with-sample-code-42)\n      - [外部資源](#external-resources-43)\n    + [JavaScript *this*](#-javascript-this-44)\n      - [外部資源](#external-resources-45)\n    + [Class](#class-46)\n      - [範例](#samples-47)\n      - [外部資源](#external-resources-48)\n    + [Async Await](#async-await-49)\n      - [範例程式碼](#sample-code-50)\n      - [說明](#explanation-51)\n      - [外部資源](#external-resources-52)\n  * [術語詞彙](#glossary-53)\n    + [作用域範圍](#-scope-54)\n    + [變數變異](#-variable-variance-55)\n\n<a name=\"notions\"></a>\n## 概念\n\n<a name=\"variable-declaration-var-const-let\"></a>\n### 變數聲明： var, const, let\n\n在 JavaScript 中有三個不同關鍵字可用於宣告一個變數，分別是 ```var```， ```let``` 和 ```const```。\n\n<a name=\"short-explanation-1\"></a>\n#### 簡短解釋\n\n使用 ```const``` 關鍵字宣告的變數無法被重新指派, 而 ```let``` 和 ```var``` 是可以的。\n\n我會建議在默認情況下一律使用 ```const``` ，當你需要<i>改變</i>它或是稍後才重新指派時才使用 ```let``` 。\n\n<table>\n  <tr>\n    <th></th>\n    <th>作用域範圍</th>\n    <th>是否可重新指派</th>\n    <th>狀態變更</th>\n   <th><a href=\"#tdz_sample\">暫時性死區 (Temporal Dead Zone)</a></th>\n  </tr>\n  <tr>\n    <th>const</th>\n    <td>區塊</td>\n    <td>不是</td>\n    <td><a href=\"#const_mutable_sample\">是</a></td>\n    <td>是</td>\n  </tr>\n  <tr>\n    <th>let</th>\n    <td>區塊</td>\n    <td>是</td>\n    <td>是</td>\n    <td>是</td>\n  </tr>\n   <tr>\n    <th>var</th>\n    <td>函數</td>\n    <td>是</td>\n    <td>是</td>\n    <td>不是</td>\n  </tr>\n</table>\n\n<a name=\"sample-code-2\"></a>\n#### 範例程式碼\n\n```javascript\nconst person = \"Nick\";\nperson = \"John\" // 會有錯誤跳出，person 不能被重新指派\n```\n\n```javascript\nlet person = \"Nick\";\nperson = \"John\";\nconsole.log(person) // \"John\" 在 let 的使用下允許被重新指派\n```\n\n<a name=\"detailed-explanation-3\"></a>\n#### 詳細說明\n\n變數的 [*作用域範圍 (scope)*](#scope_def) 大致上意味著 \"這個變數的效力可被作用在哪段程式碼 (where is this variable available in the code)\"。\n\n##### var\n\n```var``` 宣告的變數是 *函數範圍 (function scoped)* 的，這表示當函數中創造變數的時候，該函數中的所有內容都可以訪問並使用該變數。相反的，在函數外創造的 *區塊範圍 (block scoped)* 變數則無法被使用。\n\n我會建議你把它看作是一個 *X scoped* 範圍的變數代表著這個變數是 X 的屬性之一。\n\n```javascript\nfunction myFunction() {\n  var myVar = \"Nick\";\n  console.log(myVar); // \"Nick\" - myVar 可以在函數範圍之內被使用\n}\nconsole.log(myVar); // Undefined, myVar 在函數範圍外部無法被使用\n```\n\n持續觀察變數的作用域範圍，這裡有個更細微的範例：\n\n```javascript\nfunction myFunction() {\n  var myVar = \"Nick\";\n  if (true) {\n    var myVar = \"John\";\n    console.log(myVar); // \"John\"\n    // actually, myVar 是函數範圍之內的，我們剛剛覆蓋了之前的 myVar 變數，值從 \"Nick\" 變成 \"John\"\n  }\n  console.log(myVar); // \"John\" - 印出來看看區塊如何影響 myVar 這個變數的值\n}\nconsole.log(myVar); // Undefined, myVar 在函數範圍外部無法被使用\n```\n\n此外， *var* 宣告出來的變數在程式執行之時就會被移到作用域的頂部。這個就是我們所說的[變數提升 (var hoisting)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var#var_hoisting)。\n\n這段程式碼：\n\n```js\nconsole.log(myVar) // undefined -- 沒有錯誤發生\nvar myVar = 2;\n```\n\n在程式執行過程中被解讀為：\n\n```js\nvar myVar;\nconsole.log(myVar) // undefined -- 沒有錯誤發生\nmyVar = 2;\n```\n\n##### let\n\n```var``` 和 ```let ``` 大致上行為相同， ```let``` 在宣告變數時\n\n- 作用域是 *區塊範圍 (block scoped)*\n- 在被指派值以前 **無法** 被存取使用\n- 同一個作用域之下不能被重新宣告\n\n採用我們前面的例子來看看區塊範圍 (block scoped) 的影響：\n\n```javascript\nfunction myFunction() {\n  let myVar = \"Nick\";\n  if (true) {\n    let myVar = \"John\";\n    console.log(myVar); // \"John\"\n    // 事實上，myVar 是區塊範圍之內的，我們剛剛創造了一個全新的 myVar 變數\n    // 這個變數是無法從區塊範圍以外的地方存取，\n    // 而且它也是完全獨立於我們創造的第一個 myVar 變數！\n  }\n  console.log(myVar); // \"Nick\", 查看 if 區塊中的程式會不會影響到 myVar 這個值\n}\nconsole.log(myVar); // Undefined, myVar 在函數範圍外部無法被使用\n```\n\n<a name=\"tdz_sample\"></a> 現在我們來看看 *let* ( 和 *const* ) 變數在被賦值以前無法被使用是什麼意思：\n\n```js\nconsole.log(myVar) // 觸發 ReferenceError 錯誤!\nlet myVar = 2;\n```\n\n和 *var* 變數比較之下，如果在指派 *let* 或是 *const* 變數的值之前嘗試讀取或是寫入的動作是會引發錯誤的。這種現象通常被稱之為 [*Temporal dead zone*](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let#Temporal_Dead_Zone_and_errors_with_let) 或者是 *TDZ*。\n\n> **注意：** 技術上而言， *let* 和 *const* 變數在聲明時也是會被提升的，但並不是指它們的賦值。因為他們在被指派之前是不能使用的，所以直觀上就像是沒有提升一樣，但它們其實是有的。如果你想知道更多的話請查看 [更加詳細解釋的這篇文章](http://jsrocks.org/2015/01/temporal-dead-zone-tdz-demystified)。\n\n此外，你不能重新宣告一個 *let* 變數：\n\n```js\nlet myVar = 2;\nlet myVar = 3; // 跳出 SyntaxError 錯誤\n```\n\n##### const\n\n```const``` 宣告出來的行為如同 *let* 變數，但它們同樣都不能被重新宣告。\n\n總結一下， *const* 變數：\n\n- 作用域是 *區塊範圍 (block scoped)*\n- 在被指派值以前 **無法** 被存取使用\n- 同一個作用域之下不能被重新宣告\n- 無法被重新指派新值\n\n```js\nconst myVar = \"Nick\";\nmyVar = \"John\" // 跳出錯誤，不允許重新指派新值\n```\n\n```js\nconst myVar = \"Nick\";\nconst myVar = \"John\" // 跳出錯誤， 重新宣告是不被允許的\n```\n\n<a name=\"const_mutable_sample\"></a> 但有個精妙之處 : ```const``` 變數不是[**不可變的**](#mutation_def) ! 更具體而言，這代表著 *object* 和 *array* 中由 ```const``` 宣告出來的變數是 **可以** 被改變的。\n\n對於 objects：\n\n```js\nconst person = {\n  name: 'Nick'\n};\nperson.name = 'John' // 這完全可行！ person 這個變數尚未完全被重新指派，但它確實改變了\nconsole.log(person.name) // \"John\"\nperson = \"Sandra\" // 跳出錯誤，因為重新指派時是不允許使用 const 宣告出來的變數的\n```\n\n對於 arrays：\n\n```js\nconst person = [];\nperson.push('John'); // 這完全可行！ person 這個變數尚未完全被重新指派，但它確實改變了 \nconsole.log(person[0]) // \"John\"\nperson = [\"Nick\"] // 跳出錯誤，因為重新指派時是不允許使用 const 宣告出來的變數的\n```\n\n<a name=\"external-resource-4\"></a>\n#### 外部資源\n\n- [How let and const are scoped in JavaScript - WesBos](http://wesbos.com/javascript-scoping/)\n- [Temporal Dead Zone (TDZ) Demystified](http://jsrocks.org/2015/01/temporal-dead-zone-tdz-demystified)\n\n### <a name=\"-arrow-function-4\"></a> 箭頭函數\n\nES6 的更新正式引入了 *箭頭函數 (arrow functions)*，這是另外一種宣告和使用函數的方法。以下是它們所帶來的好處：\n\n- 更為簡潔\n- *this* 的值繼承自外圍作用域 (*this* is picked up from surroundings)\n- 隱式回傳 (implicit return)\n\n<a name=\"sample-code-5\"></a>\n#### 範例程式碼\n\n- 簡潔性和隱式回傳 (implicit return)\n\n```js\nfunction double(x) { return x * 2; } // 傳統作法\nconsole.log(double(2)) // 4\n```\n\n```js\nconst double = x => x * 2; // 仍然是同樣的函數，寫成帶有隱式回傳的作法\nconsole.log(double(2)) // 4\n```\n\n- *this* 關鍵字參照\n\n在箭頭函數中， *this* 意味著封閉執行上下文的 *這個值*。基本上，透過使用箭頭函數，在函數中調用函數之前，你不需要去使用像是 \"that = this\" 這樣的用法。\n\n```js\nfunction myFunc() {\n  this.myVar = 0;\n  setTimeout(() => {\n    this.myVar++;\n    console.log(this.myVar) // 1\n  }, 0);\n}\n```\n\n<a name=\"detailed-explanation-6\"></a>\n#### 詳細說明\n\n<a name=\"concision-7\"></a>\n##### 簡潔性\n\n箭頭函數在諸多方面都較傳統函數來的更為簡潔。讓我們來看看所有可能的情況：\n\n- 隱式回傳 VS 顯式回傳\n\n **顯式回傳 (explicit return)** 是指在函數中明確的使用 *return* 這個關鍵字。\n\n```js\n  function double(x) {\n    return x * 2; // 這個函數顯式回傳了 x * 2，並且使用了 return 這個關鍵字\n  }\n```\n\n以傳統的作法撰寫，return 永遠都會是顯式的。但是如果是使用箭頭函數，你可以執行隱式回傳，這同時代表著你不需要使用關鍵字 return 去取得回傳值。\n\n要做隱式回傳，程式碼必須用一行句子撰寫。\n\n```js\n  const double = (x) => {\n    return x * 2; // 此處顯示 return 值\n  }\n```\n\n由於這裡只有一個回傳值，我們可以做一個隱式回傳。\n\n```js\n const double = (x) => x * 2;\n```\n\n做到上述的轉換，我們只需要 **移除括號** 以及 **return** 這個關鍵字。這就是為什麼它會被稱為 *隱式* 回傳，*return* 關鍵字不在了，但是這個函數確實會回傳 ```x * 2```。\n\n> **注意：** 如果你的函數沒有回傳一個值 (這種作法有 *副作用*)，那麼它將不屬於顯式或是隱式返回中的任一種。\n\n- 只有一個參數\n\n如果你的函數只接受一個參數，你可以省略它周圍的括號。如果我們拿上述的 *double* 程式碼做為舉例：\n\n```js\n const double = (x) => x * 2; // 這個箭頭函數只接受一個參數\n```\n\n括號是可以被省略的：\n\n```js\n const double = x => x * 2; // 這個箭頭函數只接受一個參數\n```\n\n- 沒有參數\n\n當沒有為箭頭函數提供任何參數時，你就必須加上括號，否則語法將會出錯。\n\n```js\n  () => { // 有加上括號，一切都正常運作\n    const x = 2;\n    return x;\n  }\n```\n\n```js\n  => { // 沒有括號，這樣的語法是行不通的！\n    const x = 2;\n    return x;\n  }\n```\n\n<a name=\"this-reference-8\"></a>\n##### *this* 關鍵字參照\n\n要理解箭頭函數的精妙之處，你一定要清楚 [this](#this_def) 在 JavaScript 中是如何運作的。\n\n在一個箭頭函數當中，*this* 等同於封閉執行上下文的 *這個值* 。意思就是說，一個箭頭函數並不會創造一個新的 *this*，而是從它的外圍作用域一併抓起。\n\n沒有箭頭函數的這項功能，如果你想要取得位於函數的函數內部由 *this* 參照的變數，你就只能使用 *that = this* 或者是 *self = this* 這樣的技巧。\n\n舉例來說，你在 myFunc 函數中使用 setTimeout 函數：\n\n```js\nfunction myFunc() {\n  this.myVar = 0;\n  var that = this; // 使用 that = this 這個技巧\n  setTimeout(\n    function() { // 創造了一個新的 this \n      that.myVar++;\n      console.log(that.myVar) // 1\n\n      console.log(this.myVar) // undefined -- 詳見上述的函數宣告\n    },\n    0\n  );\n}\n```\n\n但如果你使用了箭頭函數，*this* 的範圍將會是它的外圍作用域：\n\n```js\nfunction myFunc() {\n  this.myVar = 0;\n  setTimeout(\n    () => { // this 的值來自於它的外圍作用域，也就是 myFunc 函數\n      this.myVar++;\n      console.log(this.myVar) // 1\n    },\n    0\n  );\n}\n```\n\n<a name=\"useful-resources-9\"></a>\n#### 有用資源\n\n- [Arrow functions introduction - WesBos](http://wesbos.com/arrow-functions/)\n- [JavaScript arrow function - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions)\n- [Arrow function and lexical *this*](https://hackernoon.com/javascript-es6-arrow-functions-and-lexical-this-f2a3e2a5e8c4)\n\n<a name=\"function-default-parameter-value-10\"></a>\n### 函數預設值\n\n從 ES2015 JavaScript 更新之後，你可以透過下列的語法為函數中的參數設定預設值：\n\n```js\nfunction myFunc(x = 10) {\n  return x;\n}\nconsole.log(myFunc()) // 10 -- 沒有提供任何值，所以 10 在 myFunc 中做為預設值指派給 x\nconsole.log(myFunc(5)) // 5 -- 有提供一個參數值，所以 x 在 myFunc 中等於 5   \n\nconsole.log(myFunc(undefined)) // 10 -- 未定義的值，所以預設值被指派給 x\nconsole.log(myFunc(null)) // null -- 提供一個值 (null)，詳細資料請見下文\n```\n\n預設值若且為若應用在兩種情況：\n\n- 沒有傳入任何參數\n- 傳入 *undefined* 這個參數\n\n換句話說，如果你傳入的是 *null* ，那麼預設值的機制是不會被觸發的。\n\n> **注意：** 預設值的指派可以搭配解構參數一同使用 (參照下一個概念的實際例子)\n\n<a name=\"external-resource-11\"></a>\n#### 外部資源\n\n- [Default parameter value - ES6 Features](http://es6-features.org/#DefaultParameterValues)\n- [Default parameters - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters)\n\n<a name=\"destructuring-objects-and-arrays-12\"></a>\n### objects 和 arrays 的解構\n\n*解構 (Destructuring)* 的概念是從 objects 或是 arrays 當中提取部分用值一種相當方便的方法。\n\n舉個簡單的實例，*destructuring* 可以被用來解構函數中的參數或者像是 React 專案中 *this.props* 這樣的用法。\n\n<a name=\"explanation-with-sample-code-13\"></a>\n#### 說明和範例程式碼\n\n- Object\n\n試著想想以下這個 object：\n\n```js\nconst person = {\n  firstName: \"Nick\",\n  lastName: \"Anderson\",\n  age: 35,\n  sex: \"M\"\n}\n```\n\n沒有解構的作法，你只能這樣做：\n\n```js\nconst first = person.firstName;\nconst age = person.age;\nconst city = person.city || \"Paris\";\n```\n\n使用解構，你只需要一行：\n\n```js\nconst { firstName: first, age, city = \"Paris\" } = person; // 這樣就搞定了！\n\nconsole.log(age) // 35 -- 一個名為 age 的新變數被創建出來了，其值等同於 person.age\nconsole.log(first) // \"Nick\" -- 一個名為 first 的新變數被創建出來了，其值等同於person.firstName\nconsole.log(firstName) // ReferenceError -- person.firstName 雖然存在，但其值是存在名叫 first 的新變數\nconsole.log(city) // \"Paris\" -- 一個名為 city 的新變數被創建出來了，同時因為 person.city 是未被定義的，所以 city 將等同於預設值也就是 \"Paris\"。\n```\n\n**注意：** 在 ```const { age } = person;```當中， *const* 後的括號並不是用來宣告 object 或者是區塊，僅僅是 *解構 (destructuring)* 的使用語法。\n\n- 帶有參數的函數用法\n\n*解構 (Destructuring)* 經常被用來解 objects 中的參數。\n\n沒有解構的作法，你只能這樣做：\n\n```js\nfunction joinFirstLastName(person) {\n  const firstName = person.firstName;\n  const lastName = person.lastName;\n  return firstName + '-' + lastName;\n}\n\njoinFirstLastName(person); // \"Nick-Anderson\"\n```\n\n在解構 obejct 當中 *person* 這個參數時，我們可以得到一個更簡潔的函數：\n\n```js\nfunction joinFirstLastName({ firstName, lastName }) { \n  // 我們透過解構 person 分別創造了 firstName 和 lastName 這兩個變數\n  return firstName + '-' + lastName;\n}\n\njoinFirstLastName(person); // \"Nick-Anderson\"\n```\n\n解構搭配[箭頭函數](#arrow_func_concept)使得開發過程更加愉快：\n\n```js\nconst joinFirstLastName = ({ firstName, lastName }) => firstName + '-' + lastName;\n\njoinFirstLastName(person); // \"Nick-Anderson\"\n```\n\n- Array\n\n讓我們來想想下列這個 array：\n\n```js\nconst myArray = [\"a\", \"b\", \"c\"];\n```\n\n沒有解構的作法，你只能這樣做：\n\n```js\nconst x = myArray[0];\nconst y = myArray[1];\n```\n\n使用解構的作法：\n\n```js\nconst [x, y] = myArray; // 就是這麼簡單！\n\nconsole.log(x) // \"a\"\nconsole.log(y) // \"b\"\n```\n\n<a name=\"useful-resources-14\"></a>\n#### 有用資源\n\n- [ES6 Features - Destructuring Assignment](http://es6-features.org/#ArrayMatching)\n- [Destructuring Objects - WesBos](http://wesbos.com/destructuring-objects/)\n- [ExploringJS - Destructuring](http://exploringjs.com/es6/ch_destructuring.html)\n\n<a name=\"array-methods---map--filter--reduce-1\"></a>\n### Array 的操作方法 - map / filter / reduce\n\n*Map*，*filter* 和 *reduce* 都是 array 提供的方法，它們源自於 [*functional programming*](https://medium.com/javascript-scene/master-the-javascript-interview-what-is-functional-programming-7f218c68b3a0) 開發範式。\n\n總結一下：\n\n- **Array.prototype.map()** 接受一組 array，針對其中的元素進行某些操作和轉換的動作。\n- **Array.prototype.filter()** 接受一組 array，依照元素本身決定是否保留，並且將會回傳一個僅含有保留元素的 array\n- **Array.prototype.reduce()** 接受一組 array，將這些元素合併成一個值並回傳\n\n我會建議在開發時盡可能的遵循函數式編程 (functional programming) 的原則，因為它們是可組合的，簡潔且優雅的。\n\n透過這三種方法，你將可以避免在大多數情況下使用 *for* 和 *forEach*。當你想做一個 *for* 迴圈時，試著用 *map*，*filter* 和 *reduce* 組合看看。起初你可能會覺得窒礙難行，因為它需要你學習一種新的思維方式，但一旦你掌握它了，事情也將變得更加容易。\n\n<a name=\"sample-code-16\"></a>\n#### 範例程式碼\n\n```js\nconst numbers = [0, 1, 2, 3, 4, 5, 6];\nconst doubledNumbers = numbers.map(n => n * 2); // [0, 2, 4, 6, 8, 10, 12]\nconst evenNumbers = numbers.filter(n => n % 2 === 0); // [0, 2, 4, 6]\nconst sum = numbers.reduce((prev, next) => prev + next, 0); // 21\n```\n\n透過 map，filter 和 reduce 這幾種組合技去計算出學生成績 >= 10 的總和：\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) // map the students array to an array of their grades\n  .filter(grade => grade >= 10) // we filter the grades array to keep those 10 or above\n  .reduce((prev, next) => prev + next, 0); // we sum all the grades 10 or above one by one\n\nconsole.log(aboveTenSum) // 44 -- 10 (Nick) + 15 (John) + 19 (Julia), Nathalie below 10 is ignored\n```\n\n<a name=\"explanation-17\"></a>\n#### 說明\n\n讓我們來思考下列這個 array：\n\n```js\nconst numbers = [0, 1, 2, 3, 4, 5, 6];\n```\n\n<a name=\"arrayprototypemap-18\"></a>\n##### Array.prototype.map()\n\n```js\nconst doubledNumbers = numbers.map(function(n) {\n  return n * 2;\n});\nconsole.log(doubledNumbers); // [0, 2, 4, 6, 8, 10, 12]\n```\n發生了什麼事？我們在 *numbers* 這個 array 中使用了 .map 方法，map 將會去迭代 array 中的每一個元素並且回傳給我們的函數。該函數的目標是生成並回傳一個新的值使得 map 可以替換掉原本的 array。\n\n讓我們提取這個函數以便讓解釋更清楚：\n\n```js\nconst doubleN = function(n) { return n * 2; };\nconst doubledNumbers = numbers.map(doubleN);\nconsole.log(doubledNumbers); // [0, 2, 4, 6, 8, 10, 12]\n```\n\n```numbers.map(doubleN)``` 將會產生 ```[doubleN(0), doubleN(1), doubleN(2), doubleN(3), doubleN(4), doubleN(5), doubleN(6)]``` ，而它們分別等同於 ```[0, 2, 4, 6, 8, 10, 12]```。\n\n> **注意：** 如果你不需要回傳一個新的 array 且只想實作一個帶有副作用的迴圈，使用 for / forEach 迴圈會更為符合你所需。\n\n<a name=\"arrayprototypefilter-19\"></a>\n##### Array.prototype.filter()\n\n```js\nconst evenNumbers = numbers.filter(function(n) {\n  return n % 2 === 0; // true if \"n\" is par, false if \"n\" isn't\n});\nconsole.log(evenNumbers); // [0, 2, 4, 6]\n```\n\n我們在這個充滿 *numbers* 的 array 上使用 .filter 方法，過濾器將會遍歷當中的每一個元素並回傳給我們的函數。函數的目標是回傳一個布林值，它將會確定當前值是否被保留。過濾之後回傳的是一個僅保留所需值的 array。\n\n<a name=\"arrayprototypereduce-20\"></a>\n##### Array.prototype.reduce()\n\nreduce 方法的目標是將進行迭代的 array 中的所有元素 *減少* 到只留下單一值。計算這些元素的方式將取決於你的需求。\n\n```js\nconst sum = numbers.reduce(\n  function(acc, n) {\n    return acc + n;\n  },\n  0 // 進行迭代計算的初始值\n);\n\nconsole.log(sum) //21\n```\n\n就像 .map 和 .filter 方法一樣， .reduce 方法被應用在 array 上並將函數做為第一個參數。\n\n\n這次有些變化了：\n\n- .reduce 接受兩個參數\n\n第一個參數是在每個迭代步驟中調用的函數。\n\n第二個參數是在第一個迭代步驟（讀取下一個之用）的累加器變數的值（此處是 *acc*）。\n\n- 帶有參數的函數用法\n\n做為 .reduce 的第一個參數所傳遞的函數需要兩個參數。第一個（此處是 *acc*）是累加器變數，而第二個參數（*n*）則是當前元素。\n\n累加器變數的值等於 **上一次** 迭代步驟中函數的回傳值。在迭代過程的第一步，*acc* 等於你做為 .reduce 時第二個參數所傳遞的值。\n\n###### 進行第一次迭代\n\n```acc = 0``` 因為我們把 0 做為 reduce 的第二個參數\n\n```n = 0```  *number* array 的第一個元素\n\n函數回傳 *acc* + *n* --> 0 + 0 --> 0\n\n###### 進行第二次迭代\n\n```acc = 0``` 因為它是上次迭代所回傳的值 \n\n```n = 1``` *number* array 的第二個元素\n\n函數回傳 *acc* + *n* --> 0 + 1 --> 1\n\n###### 進行第三次迭代\n\n```acc = 1``` 因為它是上次迭代所回傳的值 \n\n```n = 2``` *number* array 的第三個元素\n\n函數回傳 *acc* + *n* --> 1 + 2 --> 3\n\n###### 進行第四次迭代\n\n```acc = 3``` 因為它是上次迭代所回傳的值\n\n```n = 3``` *number* array 的第四個元素\n\n函數回傳 *acc* + *n* --> 3 + 3 --> 6\n\n###### [...] 進行最後一次迭代\n\n```acc = 15``` 因為它是上次迭代所回傳的值\n\n```n = 6``` *number* array 的最後一個元素\n\n函數回傳 *acc* + *n* --> 15 + 6 --> 21\n\n因為它是最後一個迭代步驟了， **.reduce** 將回傳 21。\n\n<a name=\"external-resource-21\"></a>\n#### 外部資源\n\n- [Understanding map / filter / reduce in JS](https://hackernoon.com/understanding-map-filter-and-reduce-in-javascript-5df1c7eee464)\n\n<a name=\"spread-operator-22\"></a>\n### 展開運算子 \"...\"\n\n展開運算子 ```...``` 的語法在 ES2015 之下已經支援了，而它將會被用於把可迭代的元素 (像是 array) 擴展到容納更多元素。\n\n<a name=\"sample-code-23\"></a>\n#### 範例程式碼\n\n```js\nconst arr1 = [\"a\", \"b\", \"c\"];\nconst arr2 = [...arr1, \"d\", \"e\", \"f\"]; // [\"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// \"a\"\n// \"b\"\n// [\"c\", \"d\", \"e\", \"f\"]\n```\n\n```js\nconst { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };\nconsole.log(x); // 1\nconsole.log(y); // 2\nconsole.log(z); // { a: 3, b: 4 }\n\nconst n = { x, y, ...z };\nconsole.log(n); // { x: 1, y: 2, a: 3, b: 4 }\n```\n\n<a name=\"explanation-24\"></a>\n#### 說明\n\n<a name=\"in-iterables-like-array-25\"></a>\n##### 迭代用法 (如同 array)\n\n如果我們有以下兩個 arrays：\n\n```js\nconst arr1 = [\"a\", \"b\", \"c\"];\nconst arr2 = [arr1, \"d\", \"e\", \"f\"]; // [[\"a\", \"b\", \"c\"], \"d\", \"e\", \"f\"]\n```\n\n*arr2* 中的第一個元素是 array ，因為 *arr1* 是被注入到 *arr2* 之中的。但我們真正想要得到的 *arr2* 是一個純字母的 array。為了做到這點，我們可以將 *arr1* *擴展 (spread)* 到 *arr2*。\n\n透過展開運算子\n\n```js\nconst arr1 = [\"a\", \"b\", \"c\"];\nconst arr2 = [...arr1, \"d\", \"e\", \"f\"]; // [\"a\", \"b\", \"c\", \"d\", \"e\", \"f\"]\n```\n\n<a name=\"function-rest-parameter-26\"></a>\n##### 不定參數\n\n在有著不定參數的函數當中，我們可以使用 rest 運算子將參數注入到我們可以進行迴圈操作的 array。這裡已經有一個名為 **arguments** 的 object 被綁定在函數上，等同於把 array 中的所有參數都傳遞給函數。\n\n```js\nfunction myFunc() {\n  for (var i = 0; i < arguments.length; i++) {\n    console.log(arguments[i]);\n  }\n}\n\nmyFunc(\"Nick\", \"Anderson\", 10, 12, 6);\n// \"Nick\"\n// \"Anderson\"\n// 10\n// 12\n// 6\n```\n\n但是如果說我們希望創造的是一個包含他的各科成績和平均成績的新學生，提取前兩個參數 (firstName 和 lastName)並把剩下的元素迭代生成一個 array 的作法是否會更有效率呢？\n\n這正是 rest 運算子允許我們做的事！\n\n```js\nfunction createStudent(firstName, lastName, ...grades) {\n  // firstName = \"Nick\"\n  // lastName = \"Anderson\"\n  // [10, 12, 6] -- \"...\" 運算子會把 firstName 和 lastName 以外的參數傳入，同時創造一個包含這些元素，叫做 \"grades\" 的 array\n\n  const avgGrade = grades.reduce((acc, curr) => acc + curr, 0) / grades.length; // 計算平均成績\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// {\n//   firstName: \"Nick\",\n//   lastName: \"Anderson\",\n//   grades: [10, 12, 6],\n//   avgGrade: 9,33\n// }\n```\n\n> **注意：** createStudent 這個函數的舉例其實並不太好，因為我們並沒有去檢查 grades.length 是否存在又或者它根本等於 0。但是這個例子的確能夠幫助我們更為容易理解其中運作，所以我並沒有花額外的時間處理這個情況，請見諒。\n\n<a name=\"object-properties-spreading-27\"></a>\n##### Object 屬性擴展\n\n關於這點，我建議你去閱讀先前有關 rest 運算子，迭代運作和帶有不定參數的函數等相關說明。\n\n```js\nconst myObj = { x: 1, y: 2, a: 3, b: 4 };\nconst { x, y, ...z } = myObj; // object 在此處被解構\nconsole.log(x); // 1\nconsole.log(y); // 2\nconsole.log(z); // { a: 3, b: 4 }\n\n// 解構後剩餘的部分都放在 z : 也就是 myObj 這個物件經過解構後鎖剩下的東西\n\nconst n = { x, y, ...z };\nconsole.log(n); // { x: 1, y: 2, a: 3, b: 4 }\n\n// 把 z 所包含的屬性擴展到 n 當中\n```\n\n<a name=\"external-resources-28\"></a>\n#### 外部資源\n\n- [TC39 - Object rest/spread](https://github.com/tc39/proposal-object-rest-spread)\n- [Spread operator introduction - WesBos](https://github.com/wesbos/es6-articles/blob/master/28%20-%20Spread%20Operator%20Introduction.md)\n- [JavaScript & the spread operator](https://codeburst.io/javascript-the-spread-operator-a867a71668ca)\n- [6 Great uses of the spread operator](https://davidwalsh.name/spread-operator)\n\n<a name=\"object-property-shorthand-29\"></a>\n### Object 屬性簡寫\n\n當我們想要把某個物件屬性指派給變數，如果變數名稱等同於屬性名稱，你可以試著執行以下操作：\n\n```js\nconst x = 10;\nconst myObj = { x };\nconsole.log(myObj.x) // 10\n```\n\n<a name=\"explanation-30\"></a>\n#### 說明\n\n通常 (pre-ES2015) 當你宣告一個新的 *物件實體語法 (object literal)* 並且想要使用變數做為物件屬性的值時，你可能會寫出以下類似的程式碼：\n\n```js\nconst x = 10;\nconst y = 20;\n\nconst myObj = {\n  x: x, // 將變數 x 賦值給 myObj.x\n  y: y // 將變數 y 賦值給 myObj.y\n};\n\nconsole.log(myObj.x) // 10\nconsole.log(myObj.y) // 20\n```\n\n你可以發現，這樣的作法其實相當繁瑣，因為 myObj 的屬性名和要指派給這些屬性的變數名稱都是相同的。\n\n透過使用 ES2015，當變數名稱和屬性名稱相同時，你可以把程式碼這樣簡寫：\n\n```js\nconst x = 10;\nconst y = 20;\n\nconst myObj = {\n  x,\n  y\n};\n\nconsole.log(myObj.x) // 10\nconsole.log(myObj.y) // 20\n```\n\n<a name=\"external-resources-31\"></a>\n#### 外部資源\n\n- [Property shorthand - ES6 Features](http://es6-features.org/#PropertyShorthand)\n\n<a name=\"promises-32\"></a>\n### Promises\n\npromise 是一個可以從異步函數 ([參考](https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-promise-27fc71e77261#3cd0)) 同步回傳的函數。\n\nPromises 可以被用來避開 [回調地獄 (callback hell)](http://callbackhell.com/)，而且它們在現代 JavaScript 專案中也越來越常被使用到。\n\n<a name=\"sample-code-33\"></a>\n#### 範例程式碼\n\n```js\nconst fetchingPosts = new Promise((res, rej) => {\n  $.get(\"/posts\")\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<a name=\"explanation-34\"></a>\n#### 說明\n\n當你在進行 *Ajax 請求* 時，回傳絕對是非同步的，因為資源請求需要時間。如果你要的資源由於某些原因 (404) 而不能使用，請求的資源可能永遠都不會出現。\n\n為了處理這類情況，ES2015 為我們提供了 *promises*。Promises 可以有三種不同的狀態：\n\n- 等待中 (Pending)\n- 達成 (Fulfilled)\n- 拒絕 (Rejected)\n\n假設我們希望使用 promises 去進行 Ajax 請求以獲取 X 這項資源。\n\n<a name=\"create-the-promise-35\"></a>\n##### 創造 promise\n\n首先要創造一個 promise。我們將會使用 jQuery 的 get 方法去進行資源 X 的 Ajax 請求。\n\n```js\nconst xFetcherPromise = new Promise( // 使用 \"new\" 這個關鍵字並把它存至一個變數\n  function(resolve, reject) { // Promise 建構子需要一個有著 resolve 和 reject 這兩個參數的函數作為參數\n    $.get(\"X\") // 執行 Ajax 請求\n      .done(function(X) { // 一旦請求完成...\n        resolve(X); // ... 把 X 做為參數去 resolve promise\n      })\n      .fail(function(error) { // 如果請求失敗...\n        reject(error); // ... 把 error 做為參數去 reject promise\n      });\n  }\n)\n```\n\n如上所示，Promise 物件需要一個帶有兩個參數 ( **resolve** 以及 **reject** ) 的函數。這兩個參數會把 *pending* 狀態的 promise 分別進行 *fulfilled* 和 *rejected* 的處理。\n\n但在此時此刻，promise 尚未被使用，它僅僅是被宣告並且儲存到 *xFetcherPromise* 這個變數當中！所以它並不存在當前的狀態。\n\n<a name=\"use-the-promise-36\"></a>\n##### 使用 promise\n\n為了使用 promise，我們可以進行以下的實作：\n\n```js\nxFetcherPromise\n  .then(function(X) {\n    console.log(X);\n  })\n  .catch(function(err) {\n    console.log(err)\n  })\n```\n\n```.then``` 是一種方法，一旦被調用將會把 xFetcherPromise 調整至 **pending** 狀態。當被調用時，promise 本體會運行，在這個範例當中，Ajax 請求正在進行中。\n\n如果成功，將會調用 *resolve*，並且 ```.then``` 將會執行做為參數傳遞的函數。\n\n如果失敗，將會調用 *reject*，並且 ```.catch``` 將會執行做為參數傳遞的函數。\n\n<a name=\"external-resources-37\"></a>\n#### 外部資源\n\n- [JavaScript Promises for dummies - Jecelyn Yeen](https://scotch.io/tutorials/javascript-promises-for-dummies)\n- [JavaScript Promise API - David Walsh](https://davidwalsh.name/promises)\n- [Using promises - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises)\n- [What is a promise - Eric Elliott](https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-promise-27fc71e77261)\n- [JavaScript Promises: an Introduction - Jake Archibald](https://developers.google.com/web/fundamentals/getting-started/primers/promises)\n- [Promise documentation - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)\n\n<a name=\"template-literals-38\"></a>\n### 模板字符串\n\n模板字符串是一種單行和多行字符串的 [*表達式差值 (expression interpolation)*](https://en.wikipedia.org/wiki/String_interpolation)。\n\n換句話說，它是一種新的字符串語法，你可以更方便地在 JavaScript 表達式中使用 (例如變數)。\n\n<a name=\"sample-code-39\"></a>\n#### 範例程式碼\n\n```js\nconst name = \"Nick\";\n`Hello ${name}, the following expression is equal to four : ${2+2}`;\n\n// Hello Nick, the following expression is equal to four: 4\n```\n\n<a name=\"external-resources-40\"></a>\n#### 外部資源\n\n- [String interpolation - ES6 Features](http://es6-features.org/#StringInterpolation)\n- [ES6 Template Strings - Addy Osmani](https://developers.google.com/web/updates/2015/01/ES6-Template-Strings)\n\n<a name=\"imports--exports-41\"></a>\n### Imports / Exports\n\nES6 模組被用來存取顯式輸出 (explicitly export)的變數或是函數。\n\n我強烈建議你去瀏覽 MDN 上有關 import/export (請參考下面的外部資源) 的文章，它們寫的既簡潔又完整。\n\n<a name=\"explanation-with-sample-code-42\"></a>\n#### 說明與範例程式碼\n\n- Named exports\n\nNamed exports 被用於從模組中輸出多個值的情況。你只能命名將要輸出的變數 (不能是函數或是類別)，所以當你想要輸出一個函數時，你必須先把它儲存在一個變數中。\n\n```js\n// mathConstants.js\nexport const pi = 3.14;\nexport const exp = 2.7;\nexport const alpha = 0.35;\n\n// -------------\n\n// myFile.js\nimport { pi, exp } from './mathConstants.js'; // 對 import 進行解構\nconsole.log(pi) // 3.14\nconsole.log(exp) // 2.7\n\n// -------------\n\n// mySecondFile.js\nimport * as constants from './mathConstants.js'; // 把所有的值輸出到 constants 這個變數\nconsole.log(constants.pi) // 3.14\nconsole.log(constants.exp) // 2.7\n```\n\n- 預設 import / export\n\n關於輸出，每個模組在預設下只能有一個輸出。一個預設的輸出可以是函數，類別，物件又或者是任何東西。這個值被認為是 \"主要的\" 輸出值，因為它將會是最簡單純粹的輸出。[參考： MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export#Description)\n\n```js\n// coolNumber.js\nconst ultimateNumber = 42;\nexport default ultimateNumber;\n\n// ------------\n\n// myFile.js\nimport number from './coolNumber.js';\n// 預設輸出將獨立於其名稱， 將被自動注入到 number 這個變數;\nconsole.log(number) // 42\n```\n\n函數輸出：\n\n```js\n// sum.js\nexport default function sum(x, y) {\n  return x + y;\n}\n// -------------\n\n// myFile.js\nimport sum from './sum.js';\nconst result = sum(1, 2);\nconsole.log(result) // 3\n```\n\n<a name=\"external-resources-43\"></a>\n#### 外部資源\n\n- [Export - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export)\n- [Import - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import)\n- [Understanding ES6 Modules](https://www.sitepoint.com/understanding-es6-modules/)\n- [Modules in JavaScript](http://exploringjs.com/es6/ch_modules.html#sec_modules-in-javascript)\n\n### <a name=\"-javascript-this-44\"></a> JavaScript *this*\n\n*this* 這個運算子的行為和其他語言是不太一樣的，在大多數情況之下是由函數的調用方式決定。([參考： MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this)).\n\n這個概念有很多精妙之處，並不是那麼容易理解，我強烈建議你好好研讀下面的外部資源。因此，我將會提供我個人對於 *this* 的一點理解和想法。我是從 [Yehuda Katz 寫的這篇文章](http://yehudakatz.com/2011/08/11/understanding-javascript-function-invocation-and-this/) 學到了這個技巧。\n\n```js\nfunction myFunc() {\n  ...\n}\n\n// 在每個述句後頭，你都可以在 myFunc 中找到 this 的值\n\nmyFunc.call(\"myString\", \"hello\") // \"myString\" -- 首先， .call 參數的值被注入到 this\n\n// 非嚴格模式下\nmyFunc(\"hello\") // window -- myFunc() 是 myFunc.call(window, \"hello\") 的語法糖\n\n// 嚴格模式下\nmyFunc(\"hello\") // undefined -- myFunc() 是 myFunc.call(undefined, \"hello\") 的語法糖\n```\n\n```js\nvar person = {\n  myFunc: function() { ... }\n}\n\nperson.myFunc.call(person, \"test\") // person 物件 -- 調用參數注入 this\nperson.myFunc(\"test\") // person Object -- person.myFunc() 是 person.myFunc.call(person, \"test\") 的語法糖\n\nvar myBoundFunc = person.myFunc.bind(\"hello\") // 創造了一個函數，並且把 \"hello\" 注入到 this\nperson.myFunc(\"test\") // person Object -- 綁定方法對原有方法並無造成影響\nmyBoundFunc(\"test\") // \"hello\" -- myBoundFunc 是把帶有 \"hello\" 的 person.myFunc 綁定到 this\n```\n\n<a name=\"external-resources-45\"></a>\n#### 外部資源\n\n- [Understanding JavaScript Function Invocation and \"this\" - Yehuda Katz](http://yehudakatz.com/2011/08/11/understanding-javascript-function-invocation-and-this/)\n- [JavaScript this - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this)\n\n<a name=\"class-46\"></a>\n### Class\n\nJavaScript 是一個 [基於原型](https://en.wikipedia.org/wiki/Prototype-based_programming) 的語言 (然而 Java 是 [基於類別](https://en.wikipedia.org/wiki/Class-based_programming) 的語言)。 ES6 引入了 JavaScript 類別，它們是基於原型繼承的語法糖，而 **不是** 真正意義上基於類別的繼承模型。([參考](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes)).\n\n\n*類別 (class)* 一詞的確容易出錯，尤其是你同時也熟悉其他語言的情況下。如果真的有此困擾，請避免在這樣的認知下思考 JavaScript 的類別行為，並把它當作一個完全不同的新概念。\n\n由於此份文件的目標不在於從頭教會你 JavaScript，我相信你早已知道什麼是原型，以及它們的行為模式。不過這裡還是有一些參考連結，以方便你去理解這些概念：\n\n- [Understanding Prototypes in JS - Yehuda Katz](http://yehudakatz.com/2011/08/12/understanding-prototypes-in-javascript/)\n- [A plain English guide to JS prototypes - Sebastian Porto](http://sporto.github.io/blog/2013/02/22/a-plain-english-guide-to-javascript-prototypes/)\n- [Inheritance and the prototype chain - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain)\n\n<a name=\"samples-47\"></a>\n#### 範例\n\nES6 之前的原型語法：\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\nES6 之後的類型語法：\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'm \" + this.age;\n  }\n}\n\nconst myPerson = new Person(\"Manu\", 23);\nconsole.log(myPerson.age) // 23\nconsole.log(myPerson.stringSentence()) // \"Hello, my name is Manu and I'm 23\n```\n\n<a name=\"external-resources-48\"></a>\n#### 外部資源\n\n更好的理解原型：\n\n- [Understanding Prototypes in JS - Yehuda Katz](http://yehudakatz.com/2011/08/12/understanding-prototypes-in-javascript/)\n- [A plain English guide to JS prototypes - Sebastian Porto](http://sporto.github.io/blog/2013/02/22/a-plain-english-guide-to-javascript-prototypes/)\n- [Inheritance and the prototype chain - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain)\n\n更好的理解類別：\n\n- [ES6 Classes in Depth - Nicolas Bevacqua](https://ponyfoo.com/articles/es6-classes-in-depth)\n- [ES6 Features - Classes](http://es6-features.org/#ClassDefinition)\n- [JavaScript Classes - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes)\n\n<a name=\"async-await-49\"></a>\n### Async Await\n\n除了 [Promises](#promises) 以外，還有一種新語法你可能會遇到，那就是被稱作非同步的 *async / await*。\n\nasync/await 的目的在於簡化同步使用 promise 的行為，並對一組 promise 執行一些處理。正如同Promises 類似於結構化之後的回調 (callback)，async/await 同樣類似於組合生成器 (combining generators) 和 promises。 ([參考： MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function))\n\n> **注意：** 你必須先行了解到什麼是 promises 和它們是如何運作的，然後再去嘗試理解 async / await 的概念，因為後者是基於前者的進一步延伸。\n\n> **注意：** [*await* must be used in an *async* function](https://hackernoon.com/6-reasons-why-javascripts-async-await-blows-promises-away-tutorial-c7ec10518dd9#f3f0) 意味著你不能程式碼的頂部使用 await，因為它並不在異步函數之內。\n\n<a name=\"sample-code-50\"></a>\n#### 說明與範例程式碼\n\n*Async / Await* 是基於 promises 之上的新概念，但它們更允許你使用命令式風格 (imperative style)去撰寫程式。\n\n\n`await` 表達式使 `async` 函數暫停執行，直到 promise 被成功解析才會繼續執行。任何 `async` 函數堆將回傳 `Promise`，並將其解析為回傳值。\n\n```js\nasync function getGithubUser(handle) { // async 這個關鍵字允許在函數中使用 await，並且意味著函數將回傳一個 promise \n  try { // 這是 async / await 使用的方式\n    const url = `https://api.github.com/users/${handle}`;\n    const response = await fetch(url); // \"同步\" 等待 fetch 去解析 promise，然後才會跳轉到下一行\n    return response.json();\n  } catch (err) {\n    alert(err);\n  }\n}\n\ngetGithubUser('mbeaudru').then(user => console.log(user)); // 印出 user 的值 - 不能使用 await 語法，因為此段程式碼並不在 async 函數當中\n```\n\n<a name=\"external-resources-52\"></a>\n#### 外部資源\n\n- [Async/Await - JavaScript.Info](https://javascript.info/async-await)\n- [ES7 Async/Await](http://rossboucher.com/await/#/)\n- [6 Reasons Why JavaScript’s Async/Await Blows Promises Away](https://hackernoon.com/6-reasons-why-javascripts-async-await-blows-promises-away-tutorial-c7ec10518dd9)\n- [JavaScript awaits](https://dev.to/kayis/javascript-awaits)\n- [Using Async Await in Express with Node 8](https://medium.com/@Abazhenov/using-async-await-in-express-with-node-8-b8af872c0016)\n- [Async Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)\n- [Await](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await)\n\n<a name=\"glossary-53\"></a>\n## 術語詞彙\n\n### <a name=\"-scope-54\"></a> 作用域範圍 (scope)\n\n在上下文之中有著 \"明顯可見的 (visible)\" 值和表達式，又或者是可以被參照的。如果變數或是表達式並不在 \"當前作用域和範圍\"，那麼它將會是不能用的。\n\n資料來源： [MDN](https://developer.mozilla.org/en-US/docs/Glossary/Scope)\n\n### <a name=\"-variable-variance-55\"></a> 變數變異 (Variable mutation)\n\n一個變數在被宣告之後發生初始值變化的過程。\n\n```js\nvar myArray = [];\nmyArray.push(\"firstEl\") // myArray 正在變化\n```\n\n如果變數不能被改變的話，我們會說這個變數是 *不可變的 (immutable)* 。\n\n[查看 MDN Mutable 文章](https://developer.mozilla.org/en-US/docs/Glossary/Mutable) 了解更多詳細資料。\n"
  }
]