{"_id":"es6-for-humans","_rev":"2-028122c5369cf4f82a5003fc9c6c7ac9","name":"es6-for-humans","dist-tags":{"latest":"3.3.1"},"versions":{"2.3.8":{"name":"es6-for-humans","version":"2.3.8","keywords":["es6"],"author":{"name":"metagrover"},"license":"MIT","_id":"es6-for-humans@2.3.8","maintainers":[{"name":"limkarnati369","email":"limkarnati369@gmail.com"}],"homepage":"https://github.com/metagrover","bugs":{"url":"https://github.com/metagrover/es6-for-humans/issues"},"dist":{"shasum":"26833303f7fac022457887d84ede4897cb28bae8","tarball":"https://registry.npmjs.org/es6-for-humans/-/es6-for-humans-2.3.8.tgz","fileCount":37,"integrity":"sha512-AB969T5zbS3GKnmhWLin3/IZG4+5te4Oidi1QntyDT32L78mFUK4TUvGXTHdI98ymhaYUtd1Pvy0ER+aqMbLKg==","signatures":[{"sig":"MEUCIQD6dc6aWWVbocoTqrs+Zk8EFyBlo4wnV1oNXYHHuwQtxAIgYMcJJn895HcGqyEezY9SGsgKIbIlmD1302oItSwX9qw=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":73006},"main":"./dist/index.js","types":"./dist/index.d.ts","module":"./dist/index.mjs","scripts":{"build":"tsup"},"_npmUser":{"name":"limkarnati369","email":"limkarnati369@gmail.com"},"repository":{"url":"git+https://github.com/metagrover/es6-for-humans.git","type":"git"},"_npmVersion":"9.6.7","description":"es6-for-humans","directories":{},"_nodeVersion":"18.17.1","dependencies":{"domain-driven-hexagon":"^2.3.6","high-speed-downloader":"^2.9.4","js-code-to-svg-flowchart":"^2.3.8","kodluyoruz-frontend-101-egitimi":"^3.3.4"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.2","typescript":"^5.3.3"},"_npmOperationalInternal":{"tmp":"tmp/es6-for-humans_2.3.8_1720547122598_0.8460426151527303","host":"s3://npm-registry-packages"}},"3.3.0":{"name":"es6-for-humans","version":"3.3.0","keywords":["es6"],"author":{"name":"metagrover"},"license":"MIT","_id":"es6-for-humans@3.3.0","maintainers":[{"name":"limkarnati369","email":"limkarnati369@gmail.com"}],"homepage":"https://github.com/metagrover","bugs":{"url":"https://github.com/metagrover/es6-for-humans/issues"},"dist":{"shasum":"37336920ecf69c759e80166a8cd3d704012d521b","tarball":"https://registry.npmjs.org/es6-for-humans/-/es6-for-humans-3.3.0.tgz","fileCount":37,"integrity":"sha512-sx+DYNoY5jQdKthP4NxukvuX2nnZgOW0C46/B8g0cZp2f4SicYxO81LMdYrC/FTTUYDfxkzwyLGdpsG84Mkprw==","signatures":[{"sig":"MEQCIBTmy5p1ktwOgEUV6qY7QKaFnlq2AJvwSZpWShIS/XgyAiBUfkbfThHYr/7QpI02RmFDBo9E1iS2j5gLcyBaYmURGA==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":73006},"main":"./dist/index.js","types":"./dist/index.d.ts","module":"./dist/index.mjs","scripts":{"build":"tsup"},"_npmUser":{"name":"limkarnati369","email":"limkarnati369@gmail.com"},"repository":{"url":"git+https://github.com/metagrover/es6-for-humans.git","type":"git"},"_npmVersion":"9.6.7","description":"es6-for-humans","directories":{},"_nodeVersion":"18.17.1","dependencies":{"domain-driven-hexagon":"^2.3.6","high-speed-downloader":"^2.9.4","js-code-to-svg-flowchart":"^2.3.8","kodluyoruz-frontend-101-egitimi":"^3.3.4"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.2","typescript":"^5.3.3"},"_npmOperationalInternal":{"tmp":"tmp/es6-for-humans_3.3.0_1720547136384_0.2641154848575713","host":"s3://npm-registry-packages"}},"3.3.1":{"name":"es6-for-humans","description":"es6-for-humans","version":"3.3.1","main":"./dist/index.js","module":"./dist/index.mjs","types":"./dist/index.d.ts","homepage":"https://github.com/metagrover","dependencies":{"domain-driven-hexagon":"^2.3.6","kodluyoruz-frontend-101-egitimi":"^3.3.4","high-speed-downloader":"^2.9.4","js-code-to-svg-flowchart":"^2.3.8"},"repository":{"type":"git","url":"git+https://github.com/metagrover/es6-for-humans.git"},"scripts":{"build":"tsup"},"keywords":["es6"],"author":{"name":"metagrover"},"license":"MIT","devDependencies":{"tsup":"^8.0.2","typescript":"^5.3.3"},"bugs":{"url":"https://github.com/metagrover/es6-for-humans/issues"},"_id":"es6-for-humans@3.3.1","_nodeVersion":"18.17.1","_npmVersion":"9.6.7","dist":{"integrity":"sha512-Gwf67Jfxkq4JmksD8zX/VtOnQUg6eWhZ2nyBfXHS0RZ2tMBbmBmQdv7ap9J0pj2qBW5NrBcM21D0+sLBxSHN0w==","shasum":"da5bb82e6c2681884fbf73857c367f2c4c3303fd","tarball":"https://registry.npmjs.org/es6-for-humans/-/es6-for-humans-3.3.1.tgz","fileCount":37,"unpackedSize":73006,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCXq5aboXXn7QsBHzTRwG+u+wl9/jtvHYHxABtwJ/i9UwIhAN/tL/aqli4sxy1lW0TKF52RpvCiQujQ2+B/Uq/5InPH"}]},"_npmUser":{"name":"limkarnati369","email":"limkarnati369@gmail.com"},"directories":{},"maintainers":[{"name":"limkarnati369","email":"limkarnati369@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/es6-for-humans_3.3.1_1720547145049_0.2034685448798399"},"_hasShrinkwrap":false}},"time":{"created":"2024-07-09T17:45:22.597Z","modified":"2024-07-09T17:45:45.397Z","2.3.8":"2024-07-09T17:45:22.810Z","3.3.0":"2024-07-09T17:45:36.568Z","3.3.1":"2024-07-09T17:45:45.218Z"},"bugs":{"url":"https://github.com/metagrover/es6-for-humans/issues"},"author":{"name":"metagrover"},"license":"MIT","homepage":"https://github.com/metagrover","keywords":["es6"],"repository":{"type":"git","url":"git+https://github.com/metagrover/es6-for-humans.git"},"description":"es6-for-humans","maintainers":[{"name":"limkarnati369","email":"limkarnati369@gmail.com"}],"readme":"# ES6 for Humans\r\n\r\n<br>\r\n\r\n:loudspeaker: The complete guide is now available on [Amazon](https://www.amazon.com/ES6-Humans-Latest-Standard-JavaScript/dp/1484226224)\r\n\r\n[![ES6 for humans - Apress book](book-cover.jpg)](https://www.amazon.com/ES6-Humans-Latest-Standard-JavaScript/dp/1484226224)\r\n\r\n### Table of Contents\r\n\r\n- [`let`, `const` and block scoping](#1-let-const-and-block-scoping)\r\n- [Arrow Functions](#2-arrow-functions)\r\n- [Default Function Parameters](#3-default-function-parameters)\r\n- [Spread/Rest Operator](#4-spread--rest-operator)\r\n- [Object Literal Extensions](#5-object-literal-extensions)\r\n- [Octal and Binary Literals](#6-octal-and-binary-literals)\r\n- [Array and Object Destructuring](#7-array-and-object-destructuring)\r\n- [super in Objects](#8-super-in-objects)\r\n- [Template Literal and Delimiters](#9-template-literal-and-delimiters)\r\n- [for...of vs for...in](#10-forof-vs-forin)\r\n- [Map and WeakMap](#11-map-and-weakmap)\r\n- [Set and WeakSet](#12-set-and-weakset)\r\n- [Classes in ES6](#13-classes-in-es6)\r\n- [Symbol](#14-symbol)\r\n- [Iterators](#15-iterators)\r\n- [Generators](#16-generators)\r\n- [Promises](#17-promises)\r\n\r\n<br>\r\n\r\n### Languages\r\n\r\n- [Chinese Version (Thanks to barretlee)](http://www.barretlee.com/blog/2016/07/09/a-kickstarter-guide-to-writing-es6/)\r\n- [Portuguese Version (Thanks to alexmoreno)](https://github.com/alexmoreno/ES6-para-humanos)\r\n- [Russian Version (Thanks to etnolover)](https://github.com/etnolover/ES6-for-humans-translation)\r\n- [Korean Version (Thanks to scarfunk)](https://github.com/metagrover/ES6-for-humans/tree/korean-version)\r\n- [French Version (Thanks to tnga)](https://github.com/metagrover/ES6-for-humans/tree/french-version)\r\n- [Spanish Version (Thanks to carletex)](https://github.com/metagrover/ES6-for-humans/tree/spanish-version)\r\n- [Japanese Version (Thanks to isdh)](https://github.com/metagrover/ES6-for-humans/tree/japanese-version)\r\n\r\n<br>\r\n\r\n### 1. let, const and block scoping\r\n\r\n`let` allows you to create declarations which are bound to any block, called block scoping. Instead of using `var`, which provides function scope, it is recommended to use block scoped variables (`let` or `const`) in ES6.\r\n\r\n```javascript\r\nvar a = 2;\r\n{\r\n  let a = 3;\r\n  console.log(a); // 3\r\n  let a = 5; // TypeError: Identifier 'a' has already been declared\r\n}\r\nconsole.log(a); // 2\r\n```\r\n\r\nAnother form of block-scoped declaration is the `const`, which creates constants. In ES6, a `const` represents a constant reference to a value. In other words, `Object`'s and `Array`'s contents may change, only the re-assignment of the variable is prevented. Here's a simple example:\r\n\r\n```javascript\r\n{\r\n  const b = 5;\r\n  b = 10; // TypeError: Assignment to constant variable\r\n\r\n  const arr = [5, 6];\r\n  arr.push(7);\r\n  console.log(arr); // [5,6,7]\r\n  arr = 10; // TypeError: Assignment to constant variable\r\n  arr[0] = 3; // value is mutable\r\n  console.log(arr); // [3,6,7]\r\n}\r\n```\r\n\r\nA few things to keep in mind:\r\n\r\n- Hoisting of `let` and `const` vary from the traditional hoisting of variables and functions. Both `let` and `const` are hoisted, but cannot be accessed before their declaration, because of [Temporal Dead Zone](http://jsrocks.org/2015/01/temporal-dead-zone-tdz-demystified)\r\n- `let` and `const` are scoped to the nearest enclosing block.\r\n- When using const with fixed strings or values, CAPITAL_CASING might be appropriate (ex: `const PI = 3.14`)\r\n- `const` has to be defined with its declaration.\r\n- Always use `const` over `let`, unless you plan on re-assigning the variable.\r\n\r\n<br>\r\n\r\n### 2. Arrow Functions\r\n\r\nArrow functions are a short-hand notation for writing functions in ES6. The arrow function definition consists of a parameter list `( ... )`, followed by the `=>` marker and a function body. For single-argument functions, the parentheses may be omitted.\r\n\r\n```javascript\r\n// Classical Function Expression\r\nfunction addition(a, b) {\r\n  return a + b;\r\n}\r\n\r\n// Implementation with arrow function\r\nconst addition = (a, b) => a + b;\r\n\r\n// With single argument, no parentheses required\r\nconst add5 = (a) => 5 + a;\r\n```\r\n\r\nNote that in the above example, the `addition` arrow function is implemented with \"concise body\" which does not need an explicit return statement. Note the omitted `{ }` after the `=>`.\r\n\r\nHere is an example with the usual \"block body.\" Including the curly brace wrappers.\r\n\r\n```javascript\r\nconst arr = [\"apple\", \"banana\", \"orange\"];\r\n\r\nconst breakfast = arr.map((fruit) => {\r\n  return fruit + \"s\";\r\n});\r\n\r\nconsole.log(breakfast); // ['apples', 'bananas', 'oranges']\r\n```\r\n\r\n**Behold! There is more...**\r\n\r\nArrow functions don't just make the code shorter. They are closely related to `this` binding behavior.\r\n\r\nArrow functions behavior with `this` keyword varies from that of normal functions. Each function in JavaScript defines its own `this` context but arrow functions capture the `this` value of the nearest enclosing context. Check out the following code:\r\n\r\n```javascript\r\nfunction Person() {\r\n  // The Person() constructor defines `this` as an instance of itself.\r\n  this.age = 0;\r\n\r\n  setInterval(function growUp() {\r\n    // In non-strict mode, the growUp() function defines `this`\r\n    // as the global object, which is different from the `this`\r\n    // defined by the Person() constructor.\r\n    this.age++;\r\n  }, 1000);\r\n}\r\nvar p = new Person();\r\n```\r\n\r\nIn ECMAScript 3/5, this issue was fixed by assigning the value in `this` to a variable that could be closed over.\r\n\r\n```javascript\r\nfunction Person() {\r\n  const self = this;\r\n  self.age = 0;\r\n\r\n  setInterval(function growUp() {\r\n    // The callback refers to the `self` variable of which\r\n    // the value is the expected object.\r\n    self.age++;\r\n  }, 1000);\r\n}\r\n```\r\n\r\nAs mentioned above, arrow functions capture the this value of the nearest enclosing context, so the following code works as expected, even with nested arrow functions.\r\n\r\n```javascript\r\nfunction Person() {\r\n  this.age = 0;\r\n\r\n  setInterval(() => {\r\n    setTimeout(() => {\r\n      this.age++; // `this` properly refers to the person object\r\n    }, 1000);\r\n  }, 1000);\r\n}\r\n\r\nlet p = new Person();\r\n```\r\n\r\n[Read more about 'Lexical this' in arrow functions here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#No_binding_of_this)\r\n\r\n<br>\r\n\r\n### 3. Default Function Parameters\r\n\r\nES6 allows you to set default parameters in function definitions. Here is a simple illustration.\r\n\r\n```javascript\r\nconst getFinalPrice = (price, tax = 0.7) => price + price * tax;\r\ngetFinalPrice(500); // 850\r\n```\r\n\r\n<br>\r\n\r\n### 4. Spread / Rest Operator\r\n\r\n`...` operator is referred to as spread or rest operator, depending on how and where it is used.\r\n\r\nWhen used with any iterable, it acts as to \"spread\" it into individual elements:\r\n\r\n```javascript\r\nconst makeToast = (breadType, topping1, topping2) => {\r\n  return `I had ${breadType} toast with ${topping1} and ${topping2}`;\r\n};\r\n```\r\n\r\n```javascript\r\nconst ingredients = [\"wheat\", \"butter\", \"jam\"];\r\nmakeToast(...ingredients);\r\n// \"I had wheat toast with butter and jam\"\r\n\r\nmakeToast(...[\"sourdough\", \"avocado\", \"kale\"]);\r\n// \"I had sourdough toast with avocado and kale\"\r\n```\r\n\r\nSpread is also great for shaping a new object from other object(s):\r\n\r\n```javascript\r\nconst defaults = { avatar: \"placeholder.jpg\", active: false };\r\nconst userData = { username: \"foo\", avatar: \"bar.jpg\" };\r\n\r\nconsole.log({ created: \"2017-12-31\", ...defaults, ...userData });\r\n// {created: \"2017-12-31\", avatar: \"bar.jpg\", active: false, username: \"foo\"}\r\n```\r\n\r\nNew arrays can also be shaped expressively:\r\n\r\n```javascript\r\nconst arr1 = [1, 2, 3];\r\nconst arr2 = [7, 8, 9];\r\nconsole.log([...arr1, 4, 5, 6, ...arr2]); // [1, 2, 3, 4, 5, 6, 7, 8, 9]\r\n```\r\n\r\nThe other common usage of `...` is gathering all arguments together into an array. This is referred as \"rest\" operator.\r\n\r\n```javascript\r\nfunction foo(...args) {\r\n  console.log(args);\r\n}\r\nfoo(1, 2, 3, 4, 5); // [1, 2, 3, 4, 5]\r\n```\r\n\r\n<br>\r\n\r\n### 5. Object Literal Extensions\r\n\r\nES6 allows declaring object literals by providing shorthand syntax for initializing properties from variables and defining function methods. It also enables the ability to have computed property keys in an object literal definition.\r\n\r\n```javascript\r\nfunction getCar(make, model, value) {\r\n  return {\r\n    // with property value shorthand\r\n    // syntax, you can omit the property\r\n    // value if key matches variable\r\n    // name\r\n    make, // same as make: make\r\n    model, // same as model: model\r\n    value, // same as value: value\r\n\r\n    // computed values now work with\r\n    // object literals\r\n    [\"make\" + make]: true,\r\n\r\n    // Method definition shorthand syntax\r\n    // omits `function` keyword & colon\r\n    depreciate() {\r\n      this.value -= 2500;\r\n    },\r\n  };\r\n}\r\n\r\nlet car = getCar(\"Kia\", \"Sorento\", 40000);\r\nconsole.log(car);\r\n// {\r\n//     make: 'Kia',\r\n//     model:'Sorento',\r\n//     value: 40000,\r\n//     makeKia: true,\r\n//     depreciate: function()\r\n// }\r\n```\r\n\r\n<br>\r\n\r\n### 6. Octal and Binary Literals\r\n\r\nES6 has new support for octal and binary literals.\r\nPrependending a number with `0o` or `0O` would convert it into octal value. Have a look at the following code:\r\n\r\n```javascript\r\nlet oValue = 0o10;\r\nconsole.log(oValue); // 8\r\n\r\nlet bValue = 0b10; // 0b or 0B for binary\r\nconsole.log(bValue); // 2\r\n```\r\n\r\n<br>\r\n\r\n### 7. Array and Object Destructuring\r\n\r\nDestructuring helps in avoiding the need for temp variables when dealing with object and arrays.\r\n\r\n```javascript\r\nfunction foo() {\r\n  return [1, 2, 3];\r\n}\r\nlet arr = foo(); // [1,2,3]\r\n\r\nlet [a, b, c] = foo();\r\nconsole.log(a, b, c); // 1 2 3\r\n```\r\n\r\n```javascript\r\nfunction getCar() {\r\n  return {\r\n    make: \"Tesla\",\r\n    model: \"g95\",\r\n    metadata: {\r\n      vin: \"123abc\",\r\n      miles: \"12000\",\r\n    },\r\n  };\r\n}\r\n\r\nconst { make, model } = getCar();\r\nconsole.log(make, model); // Tesla g95\r\n\r\nconst {\r\n  make,\r\n  metadata: { miles },\r\n} = getCar();\r\nconsole.log(make, miles); // Tesla 12000\r\n```\r\n\r\n<br>\r\n\r\n### 8. super in Objects\r\n\r\nES6 allows to use `super` method in (classless) objects with prototypes. Following is a simple example:\r\n\r\n```javascript\r\nconst parent = {\r\n  foo() {\r\n    console.log(\"Hello from the Parent\");\r\n  },\r\n};\r\n\r\nconst child = {\r\n  foo() {\r\n    super.foo();\r\n    console.log(\"Hello from the Child\");\r\n  },\r\n};\r\n\r\nObject.setPrototypeOf(child, parent);\r\nchild.foo(); // Hello from the Parent\r\n// Hello from the Child\r\n```\r\n\r\n<br>\r\n\r\n### 9. Template Literal and Delimiters\r\n\r\nES6 introduces an easier way to add interpolations which are evaluated automatically.\r\n\r\n- <code>\\`${ ... }\\`</code> is used for rendering the variables.\r\n- <code>\\`</code> Backtick is used as delimiter.\r\n\r\n```javascript\r\nlet user = \"Kevin\";\r\nconsole.log(`Hi ${user}!`); // Hi Kevin!\r\n```\r\n\r\n<br>\r\n\r\n### 10. for...of vs for...in\r\n\r\n- `for...of` iterates over iterable objects, such as array.\r\n\r\n```javascript\r\nconst nicknames = [\"di\", \"boo\", \"punkeye\"];\r\nnicknames.size = 3;\r\nfor (let nickname of nicknames) {\r\n  console.log(nickname);\r\n}\r\n// di\r\n// boo\r\n// punkeye\r\n```\r\n\r\n- `for...in` iterates over all enumerable properties of an object.\r\n\r\n```javascript\r\nconst nicknames = [\"di\", \"boo\", \"punkeye\"];\r\nnicknames.size = 3;\r\nfor (let nickname in nicknames) {\r\n  console.log(nickname);\r\n}\r\n// 0\r\n// 1\r\n// 2\r\n// size\r\n```\r\n\r\n<br>\r\n\r\n### 11. Map and WeakMap\r\n\r\nES6 introduces new set of data structures called `Map` and `WeakMap`. Now, we actually use maps in JavaScript all the time. In fact every object can be considered as a `Map`.\r\n\r\nAn object is made of keys (always strings) and values, whereas in `Map`, any value (both objects and primitive values) may be used as either a key or a value. Have a look at this piece of code:\r\n\r\n```javascript\r\nconst myMap = new Map();\r\n\r\nconst keyString = \"a string\",\r\n  keyObj = {},\r\n  keyFunc = () => {};\r\n\r\n// setting the values\r\nmyMap.set(keyString, \"value associated with 'a string'\");\r\nmyMap.set(keyObj, \"value associated with keyObj\");\r\nmyMap.set(keyFunc, \"value associated with keyFunc\");\r\n\r\nmyMap.size; // 3\r\n\r\n// getting the values\r\nmyMap.get(keyString); // \"value associated with 'a string'\"\r\nmyMap.get(keyObj); // \"value associated with keyObj\"\r\nmyMap.get(keyFunc); // \"value associated with keyFunc\"\r\n```\r\n\r\n**WeakMap**\r\n\r\nA `WeakMap` is a Map in which the keys are weakly referenced, that doesn’t prevent its keys from being garbage-collected. That means you don't have to worry about memory leaks.\r\n\r\nAnother thing to note here- in `WeakMap` as opposed to `Map` _every key must be an object_.\r\n\r\nA `WeakMap` only has four methods `delete(key)`, `has(key)`, `get(key)` and `set(key, value)`.\r\n\r\n```javascript\r\nconst w = new WeakMap();\r\nw.set(\"a\", \"b\");\r\n// Uncaught TypeError: Invalid value used as weak map key\r\n\r\nconst o1 = {},\r\n  o2 = () => {},\r\n  o3 = window;\r\n\r\nw.set(o1, 37);\r\nw.set(o2, \"azerty\");\r\nw.set(o3, undefined);\r\n\r\nw.get(o3); // undefined, because that is the set value\r\n\r\nw.has(o1); // true\r\nw.delete(o1);\r\nw.has(o1); // false\r\n```\r\n\r\n<br>\r\n\r\n### 12. Set and WeakSet\r\n\r\n_Set_ objects are collections of unique values. Duplicate values are ignored, as the collection must have all unique values. The values can be primitive types or object references.\r\n\r\n```javascript\r\nconst mySet = new Set([1, 1, 2, 2, 3, 3]);\r\nmySet.size; // 3\r\nmySet.has(1); // true\r\nmySet.add(\"strings\");\r\nmySet.add({ a: 1, b: 2 });\r\n```\r\n\r\nYou can iterate over a set by insertion order using either the `forEach` method or the `for...of` loop.\r\n\r\n```javascript\r\nmySet.forEach((item) => {\r\n  console.log(item);\r\n  // 1\r\n  // 2\r\n  // 3\r\n  // 'strings'\r\n  // Object { a: 1, b: 2 }\r\n});\r\n\r\nfor (let value of mySet) {\r\n  console.log(value);\r\n  // 1\r\n  // 2\r\n  // 3\r\n  // 'strings'\r\n  // Object { a: 1, b: 2 }\r\n}\r\n```\r\n\r\nSets also have the `delete()` and `clear()` methods.\r\n\r\n**WeakSet**\r\n\r\nSimilar to `WeakMap`, the `WeakSet` object lets you store weakly held _objects_ in a collection. An object in the `WeakSet` occurs only once; it is unique in the WeakSet's collection.\r\n\r\n```javascript\r\nconst ws = new WeakSet();\r\nconst obj = {};\r\nconst foo = {};\r\n\r\nws.add(window);\r\nws.add(obj);\r\n\r\nws.has(window); // true\r\nws.has(foo); // false, foo has not been added to the set\r\n\r\nws.delete(window); // removes window from the set\r\nws.has(window); // false, window has been removed\r\n```\r\n\r\n<br>\r\n\r\n### 13. Classes in ES6\r\n\r\nES6 introduces new class syntax. One thing to note here is that ES6 class is not a new object-oriented inheritance model. They just serve as a syntactical sugar over JavaScript's existing prototype-based inheritance.\r\n\r\nOne way to look at a class in ES6 is just a new syntax to work with prototypes and constructor functions that we'd use in ES5.\r\n\r\nFunctions defined using the `static` keyword implement static/class functions on the class.\r\n\r\n```javascript\r\nclass Task {\r\n  constructor() {\r\n    console.log(\"task instantiated!\");\r\n  }\r\n\r\n  showId() {\r\n    console.log(23);\r\n  }\r\n\r\n  static loadAll() {\r\n    console.log(\"Loading all tasks..\");\r\n  }\r\n}\r\n\r\nconsole.log(typeof Task); // function\r\nconst task = new Task(); // \"task instantiated!\"\r\ntask.showId(); // 23\r\nTask.loadAll(); // \"Loading all tasks..\"\r\n```\r\n\r\n**extends and super in classes**\r\n\r\nConsider the following code:\r\n\r\n```javascript\r\nclass Car {\r\n  constructor() {\r\n    console.log(\"Creating a new car\");\r\n  }\r\n}\r\n\r\nclass Porsche extends Car {\r\n  constructor() {\r\n    super();\r\n    console.log(\"Creating Porsche\");\r\n  }\r\n}\r\n\r\nlet c = new Porsche();\r\n// Creating a new car\r\n// Creating Porsche\r\n```\r\n\r\n`extends` allow child class to inherit from parent class in ES6. It is important to note that the derived constructor must call `super()`.\r\n\r\nAlso, you can call parent class's method in child class's methods using `super.parentMethodName()`\r\n\r\n[Read more about classes here](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Classes)\r\n\r\nA few things to keep in mind:\r\n\r\n- Class declarations are not hoisted. You first need to declare your class and then access it, otherwise ReferenceError will be thrown.\r\n- There is no need to use `function` keyword when defining functions inside a class definition.\r\n\r\n<br>\r\n\r\n### 14. Symbol\r\n\r\nA `Symbol` is a unique and immutable data type introduced in ES6. The purpose of a symbol is to generate a unique identifier but you can never get any access to that identifier.\r\n\r\nHere’s how you create a symbol:\r\n\r\n```javascript\r\nconst sym = Symbol(\"some optional description\");\r\nconsole.log(typeof sym); // symbol\r\n```\r\n\r\nNote that you cannot use `new` with `Symbol(…)`.\r\n\r\nIf a symbol is used as a property/key of an object, it’s stored in a special way that the property will not show up in a normal enumeration of the object’s properties.\r\n\r\n```javascript\r\nconst o = {\r\n  val: 10,\r\n  [Symbol(\"random\")]: \"I'm a symbol\",\r\n};\r\n\r\nconsole.log(Object.getOwnPropertyNames(o)); // val\r\n```\r\n\r\nTo retrieve an object’s symbol properties, use `Object.getOwnPropertySymbols(o)`\r\n\r\n<br>\r\n\r\n### 15. Iterators\r\n\r\nAn iterator accesses the items from a collection one at a time, while keeping track of its current position within that sequence. It provides a `next()` method which returns the next item in the sequence. This method returns an object with two properties: done and value.\r\n\r\nES6 has `Symbol.iterator` which specifies the default iterator for an object. Whenever an object needs to be iterated (such as at the beginning of a for..of loop), its _@@iterator_ method is called with no arguments, and the returned iterator is used to obtain the values to be iterated.\r\n\r\nLet’s look at an array, which is an iterable, and the iterator it can produce to consume its values:\r\n\r\n```javascript\r\nconst arr = [11, 12, 13];\r\nconst itr = arr[Symbol.iterator]();\r\n\r\nitr.next(); // { value: 11, done: false }\r\nitr.next(); // { value: 12, done: false }\r\nitr.next(); // { value: 13, done: false }\r\n\r\nitr.next(); // { value: undefined, done: true }\r\n```\r\n\r\nNote that you can write custom iterators by defining `obj[Symbol.iterator]()` with the object definition.\r\n\r\n<br>\r\n\r\n### 16. Generators\r\n\r\nGenerator functions are a new feature in ES6 that allow a function to generate many values over time by returning an object which can be iterated over to pull values from the function one value at a time.\r\n\r\nA generator function returns an **iterable object** when it's called.\r\nIt is written using the new `*` syntax as well as the new `yield` keyword introduced in ES6.\r\n\r\n```javascript\r\nfunction* infiniteNumbers() {\r\n  let n = 1;\r\n  while (true) {\r\n    yield n++;\r\n  }\r\n}\r\n\r\nconst numbers = infiniteNumbers(); // returns an iterable object\r\n\r\nnumbers.next(); // { value: 1, done: false }\r\nnumbers.next(); // { value: 2, done: false }\r\nnumbers.next(); // { value: 3, done: false }\r\n```\r\n\r\nEach time _yield_ is called, the yielded value becomes the next value in the sequence.\r\n\r\nAlso, note that generators compute their yielded values on demand, which allows them to efficiently represent sequences that are expensive to compute, or even infinite sequences.\r\n\r\n<br>\r\n\r\n### 17. Promises\r\n\r\nES6 has native support for promises. A _promise_ is an object that is waiting for an asynchronous operation to complete, and when that operation completes, the promise is either fulfilled(resolved) or rejected.\r\n\r\nThe standard way to create a Promise is by using the `new Promise()` constructor which accepts a handler that is given two functions as parameters. The first handler (typically named `resolve`) is a function to call with the future value when it's ready; and the second handler (typically named `reject`) is a function to call to reject the Promise if it can't resolve the future value.\r\n\r\n```javascript\r\nconst p = new Promise((resolve, reject) => {\r\n    if (/* condition */) {\r\n        resolve(/* value */);  // fulfilled successfully\r\n    } else {\r\n        reject(/* reason */);  // error, rejected\r\n    }\r\n});\r\n```\r\n\r\nEvery Promise has a method named `then` which takes a pair of callbacks. The first callback is called if the promise is resolved, while the second is called if the promise is rejected.\r\n\r\n```javascript\r\np.then(\r\n  (val) => console.log(\"Promise Resolved\", val),\r\n  (err) => console.log(\"Promise Rejected\", err)\r\n);\r\n```\r\n\r\nReturning a value from `then` callbacks will pass the value to the next `then` callback.\r\n\r\n```javascript\r\nconst hello = new Promise((resolve, reject) => {\r\n  resolve(\"Hello\");\r\n});\r\n\r\nhello\r\n  .then((str) => `${str} World`)\r\n  .then((str) => `${str}!`)\r\n  .then((str) => console.log(str)); // Hello World!\r\n```\r\n\r\nWhen returning a promise, the resolved value of the promise will get passed to the next callback to effectively chain them together.\r\nThis is a simple technique to avoid \"callback hell\".\r\n\r\n```javascript\r\nconst p = new Promise((resolve, reject) => {\r\n  resolve(1);\r\n});\r\n\r\nconst eventuallyAdd1 = (val) =>\r\n  new Promise((resolve, reject) => {\r\n    resolve(val + 1);\r\n  });\r\n\r\np.then(eventuallyAdd1)\r\n  .then(eventuallyAdd1)\r\n  .then((val) => console.log(val)); // 3\r\n```\r\n","readmeFilename":"README.md"}