├── .gitignore ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── banner.png ├── snippets-images ├── 01-object-search.png ├── 02-array-map-reduce.png ├── 03-methods-for-merging-arrays.png ├── 04-map-vs-object-literals.png ├── 05-weakmap.png ├── 06-sets-in-es6.png ├── 07-promises.png ├── 08-promises-async-await.png ├── 09-promise-all-vs-promise-allsettled.png ├── 10-promise-race-any-join.png ├── 11-proxies-part-1.png ├── 12-proxies-part-2-with-reflect.png ├── 13-proxies-part-3.png ├── 14-flat-flatmap.png ├── 15-fun-with-emoji.png ├── 16-bizarre-javascript.png ├── 17-breaking-nested-loops.png ├── 18-eventemitter.png ├── 19-implement-eventemitter-part1.png ├── 20-implement-eventemitter-part2.spec.png ├── 21-tips-underscore-number.png ├── 22-map-vs-filter-vs-reduce.png ├── 23-generator-function-yield-usage.png ├── 24-usage-of-switch-with-numeric-ranges.png ├── 25-symbols-property-keys-without-name-collisions.png ├── 26-void-operator.png ├── 27-set-duplicate-values-array.png └── 28-object-destructuring-array.png └── snippets ├── 01-object-search.js ├── 02-array-map-reduce.js ├── 03-methods-for-merging-arrays.js ├── 04-map-vs-object-literals.js ├── 05-weakmap.js ├── 06-sets-in-es6.js ├── 07-promises.js ├── 08-promises-async-await.js ├── 09-promise-all-vs-promise-allsettled.js ├── 10-promise-race-any-join.js ├── 11-proxies-part-1.js ├── 12-proxies-part-2-with-reflect.js ├── 13-proxies-part-3.js ├── 14-flat-flatmap.js ├── 15-fun-with-emoji.js ├── 16-bizarre-javascript.js ├── 17-breaking-nested-loops.js ├── 18-eventemitter.js ├── 19-implement-eventemitter-part1.js ├── 20-implement-eventemitter-part2.spec.js ├── 21-tips-underscore-number.js ├── 22-map-vs-filter-vs-reduce.js ├── 23-generator-function-yield-usage.js ├── 24-usage-of-switch-with-numeric-ranges.js ├── 25-symbols-property-keys-without-name-collisions.js ├── 26-void-operator.js ├── 27-set-duplicate-values-array.js └── 28-object-destructuring-array.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | me@olivier.codes. 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.0, available at 119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 120 | 121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 122 | enforcement ladder](https://github.com/mozilla/diversity). 123 | 124 | [homepage]: https://www.contributor-covenant.org 125 | 126 | For answers to common questions about this code of conduct, see the FAQ at 127 | https://www.contributor-covenant.org/faq. Translations are available at 128 | https://www.contributor-covenant.org/translations. 129 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Olivier 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![MIT License][license-shield]][license-url] 2 | [![Stargazers][stars-shield]][stars-url] [![Forks][forks-shield]][forks-url] [![Issues][issues-shield]][issues-url] 3 | 4 | 5 | 6 |
7 |

8 | 9 | Logo 10 | 11 | 12 |

{ Minutes of Javascript }

13 |

14 | Report Bug 15 | · 16 | Request Feature 17 |

18 |

19 | 20 | 21 | 22 | 23 |
24 |

Table of Contents

25 |
    26 |
  1. About The Project
  2. 27 |
  3. Minutes listing
  4. 28 |
  5. Contributing
  6. 29 |
  7. License
  8. 30 |
  9. Contact
  10. 31 |
  11. Acknowledgements
  12. 32 |
33 |
34 | 35 | 36 | 37 | 38 | ## 👋 About The Project 39 | 40 | Javascript pieces of code to make you discover new exciting features, useful tips or anything that will give you a better understanding of the subtleties of JS. This repository serves as a central location for all theses snippets. 41 | 42 | 43 | ## ⭐ Minutes listing 44 | 45 | 1. [Switch statement vs Object Search](snippets/01-object-search.js) 46 | 2. [.map() & .reduce()](snippets/02-array-map-reduce.js) 47 | 3. [Methods for merging (aka concatenating) arrays](snippets/03-methods-for-merging-arrays.js) 48 | 4. [Using Map() vs Object literals](snippets/04-map-vs-object-literals.js) 49 | 5. [Weakmap()](snippets/05-weakmap.js) 50 | 6. [Sets in ES6](snippets/06-sets-in-es6.js) 51 | 7. [Promises](snippets/07-promises.js) 52 | 8. [Promises Part 2.](snippets/08-promises-async-await.js) 53 | 9. [Promise.all vs Promise.allSettled](snippets/09-promise-all-vs-promise-allsettled.js) 54 | 10. [Promise.race](snippets/10-promise-race-any-join.js) 55 | 11. [Proxies Part 1. introduction](snippets/11-proxies-part-1.js) 56 | 12. [Proxies Part 2. (with Reflect)](snippets/12-proxies-part-2-with-reflect.js) 57 | 13. [Proxies Part 3. makeReadOnly example](snippets/13-proxies-part-3.js) 58 | 14. [flat() and flatMap()](snippets/14-flat-flatmap.js) 59 | 15. [ Fun with Emoji!](snippets/15-fun-with-emoji.js) 60 | 16. [Some bizarre things in Javascript](snippets/16-bizarre-javascript.js) 61 | 17. [Breaking in nested loops](snippets/17-breaking-nested-loops.js) 62 | 18. [EventEmitter](snippets/18-eventemitter.js) 63 | 19. [How to implement a local EventEmitter? (part 1.)](snippets/19-implement-eventemitter-part1.js) 64 | 20. [How to implement a local EventEmitter? (part 2.)](snippets/20-implement-eventemitter-part2.spec.js) 65 | 21. [Using "_" in numbers for better readability](snippets/21-tips-underscore-number.js) 66 | 22. [Array: .map() vs .filter() vs .reduce()](snippets/22-map-vs-filter-vs-reduce.js) 67 | 23. [Generator function* and yield usage](snippets/23-generator-function-yield-usage.js) 68 | 24. [Usage of switch (true), an example with numeric ranges](snippets/24-usage-of-switch-with-numeric-ranges.js) 69 | 25. [Symbols: property keys without name collisions](snippets/25-symbols-property-keys-without-name-collisions.js) 70 | 26. [The void operator](snippets/26-void-operator.js) 71 | 27. [Using new Set() to get rid of duplicate values in array](snippets/27-set-duplicate-values-array.js) 72 | 28. [Object destructuring on Array](snippets/28-object-destructuring-array.js) 73 | 74 | 75 | ## 🌈 Contributing 76 | 77 | Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**. 78 | 79 | 1. Fork the Project 80 | 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) 81 | 3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) 82 | 4. If you're writing a new snippet, do not forget to update the Minutes listing section accordingly 83 | 5. Push to the Branch (`git push origin feature/AmazingFeature`) 84 | 6. Open a Pull Request 85 | 86 | 87 | 88 | 89 | ## 💾 License 90 | 91 | Distributed under the MIT License. See `LICENSE` for more information. 92 | 93 | 94 | 95 | 96 | ## ✉️ Contact 97 | [![Twitter][twitter-shield]][twitter-url] 98 | [![Linkedin][linkedin-shield]][linkedin-url] 99 | 100 | 101 | 102 | ## 🙏 Acknowledgements 103 | 104 | * [Carbon](https://carbon.now.sh/) - Create and share beautiful images of your source code 105 | 106 | 107 | [contributors-shield]: https://img.shields.io/github/contributors/olivierloverde/minutes-of-javascript.svg?style=for-the-badge 108 | [contributors-url]: https://github.com/olivierloverde/minutes-of-javascript/graphs/contributors 109 | [forks-shield]: https://img.shields.io/github/forks/olivierloverde/minutes-of-javascript.svg?style=for-the-badge 110 | [forks-url]: https://github.com/olivierloverde/minutes-of-javascript/network/members 111 | [stars-shield]: https://img.shields.io/github/stars/olivierloverde/minutes-of-javascript.svg?style=for-the-badge 112 | [stars-url]: https://github.com/olivierloverde/minutes-of-javascript/stargazers 113 | [issues-shield]: https://img.shields.io/github/issues/olivierloverde/minutes-of-javascript.svg?style=for-the-badge 114 | [issues-url]: https://github.com/olivierloverde/minutes-of-javascript/issues 115 | [license-shield]: https://img.shields.io/github/license/olivierloverde/minutes-of-javascript.svg?style=for-the-badge 116 | [license-url]: https://github.com/olivierloverde/minutes-of-javascript/blob/main/LICENSE 117 | [linkedin-shield]: https://img.shields.io/badge/-LinkedIn-black.svg?style=for-the-badge&logo=linkedin&colorB=555 118 | [linkedin-url]: https://linkedin.com/in/olivierloverde 119 | [twitter-shield]: https://img.shields.io/badge/-Twitter-black.svg?style=for-the-badge&logo=Twitter&colorB=555 120 | [twitter-url]: https://twitter.com/loverdeolivier 121 | -------------------------------------------------------------------------------- /banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olivierloverde/minutes-of-javascript/dc54411699b7d30901c93049e7e158d55cac4932/banner.png -------------------------------------------------------------------------------- /snippets-images/01-object-search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olivierloverde/minutes-of-javascript/dc54411699b7d30901c93049e7e158d55cac4932/snippets-images/01-object-search.png -------------------------------------------------------------------------------- /snippets-images/02-array-map-reduce.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olivierloverde/minutes-of-javascript/dc54411699b7d30901c93049e7e158d55cac4932/snippets-images/02-array-map-reduce.png -------------------------------------------------------------------------------- /snippets-images/03-methods-for-merging-arrays.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olivierloverde/minutes-of-javascript/dc54411699b7d30901c93049e7e158d55cac4932/snippets-images/03-methods-for-merging-arrays.png -------------------------------------------------------------------------------- /snippets-images/04-map-vs-object-literals.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olivierloverde/minutes-of-javascript/dc54411699b7d30901c93049e7e158d55cac4932/snippets-images/04-map-vs-object-literals.png -------------------------------------------------------------------------------- /snippets-images/05-weakmap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olivierloverde/minutes-of-javascript/dc54411699b7d30901c93049e7e158d55cac4932/snippets-images/05-weakmap.png -------------------------------------------------------------------------------- /snippets-images/06-sets-in-es6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olivierloverde/minutes-of-javascript/dc54411699b7d30901c93049e7e158d55cac4932/snippets-images/06-sets-in-es6.png -------------------------------------------------------------------------------- /snippets-images/07-promises.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olivierloverde/minutes-of-javascript/dc54411699b7d30901c93049e7e158d55cac4932/snippets-images/07-promises.png -------------------------------------------------------------------------------- /snippets-images/08-promises-async-await.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olivierloverde/minutes-of-javascript/dc54411699b7d30901c93049e7e158d55cac4932/snippets-images/08-promises-async-await.png -------------------------------------------------------------------------------- /snippets-images/09-promise-all-vs-promise-allsettled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olivierloverde/minutes-of-javascript/dc54411699b7d30901c93049e7e158d55cac4932/snippets-images/09-promise-all-vs-promise-allsettled.png -------------------------------------------------------------------------------- /snippets-images/10-promise-race-any-join.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olivierloverde/minutes-of-javascript/dc54411699b7d30901c93049e7e158d55cac4932/snippets-images/10-promise-race-any-join.png -------------------------------------------------------------------------------- /snippets-images/11-proxies-part-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olivierloverde/minutes-of-javascript/dc54411699b7d30901c93049e7e158d55cac4932/snippets-images/11-proxies-part-1.png -------------------------------------------------------------------------------- /snippets-images/12-proxies-part-2-with-reflect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olivierloverde/minutes-of-javascript/dc54411699b7d30901c93049e7e158d55cac4932/snippets-images/12-proxies-part-2-with-reflect.png -------------------------------------------------------------------------------- /snippets-images/13-proxies-part-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olivierloverde/minutes-of-javascript/dc54411699b7d30901c93049e7e158d55cac4932/snippets-images/13-proxies-part-3.png -------------------------------------------------------------------------------- /snippets-images/14-flat-flatmap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olivierloverde/minutes-of-javascript/dc54411699b7d30901c93049e7e158d55cac4932/snippets-images/14-flat-flatmap.png -------------------------------------------------------------------------------- /snippets-images/15-fun-with-emoji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olivierloverde/minutes-of-javascript/dc54411699b7d30901c93049e7e158d55cac4932/snippets-images/15-fun-with-emoji.png -------------------------------------------------------------------------------- /snippets-images/16-bizarre-javascript.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olivierloverde/minutes-of-javascript/dc54411699b7d30901c93049e7e158d55cac4932/snippets-images/16-bizarre-javascript.png -------------------------------------------------------------------------------- /snippets-images/17-breaking-nested-loops.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olivierloverde/minutes-of-javascript/dc54411699b7d30901c93049e7e158d55cac4932/snippets-images/17-breaking-nested-loops.png -------------------------------------------------------------------------------- /snippets-images/18-eventemitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olivierloverde/minutes-of-javascript/dc54411699b7d30901c93049e7e158d55cac4932/snippets-images/18-eventemitter.png -------------------------------------------------------------------------------- /snippets-images/19-implement-eventemitter-part1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olivierloverde/minutes-of-javascript/dc54411699b7d30901c93049e7e158d55cac4932/snippets-images/19-implement-eventemitter-part1.png -------------------------------------------------------------------------------- /snippets-images/20-implement-eventemitter-part2.spec.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olivierloverde/minutes-of-javascript/dc54411699b7d30901c93049e7e158d55cac4932/snippets-images/20-implement-eventemitter-part2.spec.png -------------------------------------------------------------------------------- /snippets-images/21-tips-underscore-number.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olivierloverde/minutes-of-javascript/dc54411699b7d30901c93049e7e158d55cac4932/snippets-images/21-tips-underscore-number.png -------------------------------------------------------------------------------- /snippets-images/22-map-vs-filter-vs-reduce.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olivierloverde/minutes-of-javascript/dc54411699b7d30901c93049e7e158d55cac4932/snippets-images/22-map-vs-filter-vs-reduce.png -------------------------------------------------------------------------------- /snippets-images/23-generator-function-yield-usage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olivierloverde/minutes-of-javascript/dc54411699b7d30901c93049e7e158d55cac4932/snippets-images/23-generator-function-yield-usage.png -------------------------------------------------------------------------------- /snippets-images/24-usage-of-switch-with-numeric-ranges.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olivierloverde/minutes-of-javascript/dc54411699b7d30901c93049e7e158d55cac4932/snippets-images/24-usage-of-switch-with-numeric-ranges.png -------------------------------------------------------------------------------- /snippets-images/25-symbols-property-keys-without-name-collisions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olivierloverde/minutes-of-javascript/dc54411699b7d30901c93049e7e158d55cac4932/snippets-images/25-symbols-property-keys-without-name-collisions.png -------------------------------------------------------------------------------- /snippets-images/26-void-operator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olivierloverde/minutes-of-javascript/dc54411699b7d30901c93049e7e158d55cac4932/snippets-images/26-void-operator.png -------------------------------------------------------------------------------- /snippets-images/27-set-duplicate-values-array.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olivierloverde/minutes-of-javascript/dc54411699b7d30901c93049e7e158d55cac4932/snippets-images/27-set-duplicate-values-array.png -------------------------------------------------------------------------------- /snippets-images/28-object-destructuring-array.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olivierloverde/minutes-of-javascript/dc54411699b7d30901c93049e7e158d55cac4932/snippets-images/28-object-destructuring-array.png -------------------------------------------------------------------------------- /snippets/01-object-search.js: -------------------------------------------------------------------------------- 1 | // Minutes of Javascript #01 - Switch statement vs Object Search 2 | // See: https://playcode.io/609280/ 3 | function handleSuccess(){} 4 | function handleUnauthorized(){} 5 | function handleNotFound(){} 6 | function handleUnknownError(){} 7 | const status = 200; 8 | 9 | // Switch statement 10 | switch (status) { 11 | case 200: 12 | handleSuccess() 13 | break 14 | case 401: 15 | handleUnauthorized() 16 | break 17 | case 404: 18 | handleNotFound() 19 | break 20 | default: 21 | handleUnknownError() 22 | break 23 | } 24 | 25 | // Equivalent using object key search in O(1) time 26 | const hashmap = { 27 | 200: handleSuccess, 28 | 401: handleUnauthorized, 29 | 404: handleNotFound, 30 | default: handleUnknownError 31 | }; 32 | const hashmapResult = hashmap.hasOwnProperty(status) ? hashmap[status] : hashmap.default; 33 | console.info(hashmapResult()); -------------------------------------------------------------------------------- /snippets/02-array-map-reduce.js: -------------------------------------------------------------------------------- 1 | // Minutes of Javascript #02 - .map() & .reduce() 2 | // See: https://playcode.io/609277/ 3 | const myArray = [1,2,3,4,5,6]; 4 | 5 | // Use .map() for applying a transformation on each elements 6 | const mutipliedArray = myArray.map((element) => element*2); 7 | console.info(mutipliedArray); // [ 2, 4, 6, 8, 10, 12 ] 8 | 9 | // Use .reduce() for merging together each element of the array 10 | const sumOfArray = myArray.reduce((previous, current) => previous+current); 11 | console.info(sumOfArray); // 21 12 | 13 | // These methods can be chained together 14 | const sumOfMultipliedArray = myArray.map((el) => el*2).reduce((prev, cur) => prev+cur); 15 | console.info(sumOfMultipliedArray); // 42 -------------------------------------------------------------------------------- /snippets/03-methods-for-merging-arrays.js: -------------------------------------------------------------------------------- 1 | // Minutes of Javascript #03 - Methods for merging (aka concatenating) arrays 2 | // See: https://playcode.io/609806/ 3 | const arr1 = ['a', 'b', 'c']; 4 | const arr2 = ['1', '2', '3']; 5 | 6 | // Using .concat() 7 | console.info(arr1.concat(arr2)); // ["a","b","c","1","2","3"] 8 | 9 | // Using spread operators 10 | console.info([...arr1, ...arr2]); // ["a","b","c","1","2","3"] 11 | 12 | // This works too: 13 | console.info(['a', 'b', 'c', ...arr2]); // ["a","b","c","1","2","3"] 14 | 15 | // Using Array.of 16 | console.info(Array.of(...arr1, ...arr2)); // ["a","b","c","1","2","3"] 17 | 18 | // With reduce 19 | console.info(arr2.reduce(function(array,value) { 20 | array.push(value); 21 | return array; 22 | }, arr1)); // ["a","b","c","1","2","3"] -------------------------------------------------------------------------------- /snippets/04-map-vs-object-literals.js: -------------------------------------------------------------------------------- 1 | // Minutes of Javascript #04 - Using Map() vs Object literals 2 | // See: https://playcode.io/610224/ 3 | 4 | // Drawback #1 of object literals (i.e {}): All keys can only be strings 5 | const obj = {} 6 | obj[['a','b',1]] = "value" 7 | console.info(obj) // {a,b,1:"value"} => key has been converted to string "a,b,1" 8 | 9 | // Drawback #2: property/key orders are not guaranteed 10 | const obj2 = {} 11 | obj2['1'] = '' 12 | obj2['2'] = '' 13 | for(key in obj2) console.log(key) // return 1 2 but not order not guaranteed 14 | 15 | // Drawback #3: forEach() can not be called return error "obj.forEach is not a function" 16 | 17 | // Map() addresses these drawbacks 18 | // Init using methods .set() 19 | const m = new Map() 20 | m.set('first', 1) 21 | m.set(obj, 2) 22 | // Init using 2D arrays 23 | const m2 = new Map([ 24 | ['second', 3], 25 | [obj, '4'] 26 | ]); 27 | 28 | m.forEach(function(value, key) { 29 | console.info(key, value) 30 | }) // returned in order 31 | console.info(m.get(obj)) // return 2 32 | 33 | // Merging two arrays using spread operators 34 | const m3 = new Map([...m, ...m2]); // last key wins 35 | console.info(Array.from(m3)) // Display in 2D arrays 36 | 37 | // Cheatsheet 38 | console.info(m.size) // return the size of the map 39 | console.info(m.keys()) // return the keys of the map 40 | m.delete('first') // Deletes a key and returns if the delete was successful.') 41 | m.clear() // Clears the map of all entries -------------------------------------------------------------------------------- /snippets/05-weakmap.js: -------------------------------------------------------------------------------- 1 | // Minutes of Javascript #05 - Weakmap() ? 2 | // See: https://playcode.io/610831/ 3 | 4 | // In WeakMap, the key has to be an Object 5 | // A Weakmap holds a weak reference to the key inside of the map. 6 | // It means if the object is destroyed, GC will remove the entire entry from the Weakmap too 7 | 8 | let myWeakMap = new WeakMap(); 9 | let element2 = { foo: 'bar'}; 10 | myWeakMap.set(element2, 'hello'); 11 | console.info(myWeakMap.get(element2)) // prints "hello" 12 | 13 | element2 = null; 14 | console.info(myWeakMap.get(element2)) // prints undefined, Memory is free 15 | // Also, you can not get the size of a WeakMap and can not iterate on it 16 | 17 | // WeakMap Cheatsheet: 18 | WeakMap.set 19 | WeakMap.get 20 | WeakMap.has 21 | WeakMap.delete 22 | WeakMap.clear -------------------------------------------------------------------------------- /snippets/06-sets-in-es6.js: -------------------------------------------------------------------------------- 1 | // Minutes of Javascript #06 - Sets in ES6 2 | // See: https://playcode.io/611264/ 3 | 4 | // A set is a list of values that cannot contain duplicates. 5 | const set = new Set() 6 | console.log(set) // Set {} 7 | const set2 = new Set([1, 2, 3]) 8 | console.log(set2) // Set { 1, 2, 3 } 9 | const set3 = new Set([1, 2, 2, 2, 2, 2, 3, 3, 3]) 10 | console.log(set2) // Set { 1, 2, 3 } 11 | 12 | // Playing with add and size 13 | const set4 = new Set() 14 | set4.size // 0 15 | set4.add('hello') 16 | set4.size // 1 17 | set4.add('hello') // add is ignored if value is already in Set 18 | set4.size // 1 19 | 20 | // Iterations 21 | const set5 = new Set(['a', 'b', 'c']) 22 | set5.forEach((value, key, s) => { 23 | console.log(`${value} ${key}`) 24 | }) 25 | 26 | // Set to array 27 | const set6 = new Set([1, 2, 3]) 28 | const array = [...set6] 29 | console.log(array) // [ 1, 2, 3 ] -------------------------------------------------------------------------------- /snippets/07-promises.js: -------------------------------------------------------------------------------- 1 | // Minutes of Javascript #07 - Promises 2 | // See: https://playcode.io/612623/ 3 | 4 | // Promise takes two functions as arguments 5 | // You call resolve when the function succeeds 6 | const okPromise = new Promise(function(resolve, reject) { 7 | resolve({result: ['1','2']}) // you can pass data to the callback 8 | }); 9 | 10 | // You call reject when it fails 11 | const koPromise = new Promise(function(resolve, reject) { 12 | reject(new Error('not found')) // you can pass data to the callback 13 | }); 14 | 15 | // The promise rejects if you throw an error 16 | const throwedPromise = new Promise(function(resolve, reject) { 17 | throw new Error('not found') // you can pass data to the callback 18 | }); 19 | 20 | // Promise can be created using "async" keyword 21 | // It resolves with returned value 22 | // Rejects if an error is thrown 23 | const asyncPromise = async function() { 24 | return true; 25 | } 26 | 27 | // You can call other promises by using .then for getting the result 28 | okPromise.then(function(result) { 29 | console.info(result) // {result: ['1','2']} 30 | }).catch((err) => console.info(err)) // nothing displayed 31 | // Use .catch for catch the error of a promise 32 | koPromise.then(function(result) { 33 | console.info(result) // nothing displayed 34 | }).catch((err) => console.info(err)) // Error: not found -------------------------------------------------------------------------------- /snippets/08-promises-async-await.js: -------------------------------------------------------------------------------- 1 | // Minutes of Javascript #08 - Promises Part 2. (Part 1. is available here: https://bit.ly/2XD6FnC) 2 | // See: https://playcode.io/612911/ 3 | // Init variables for playground 4 | const p1 = new Promise((resolve, reject) => setTimeout(resolve({'foo': 'bar'}), 500)); 5 | const p2 = new Promise((resolve, reject) => setTimeout(resolve({'foo2': 'bar2'}), 500)); 6 | const p3 = new Promise((resolve, reject) => setTimeout(reject(new Error('oops')), 500)); 7 | 8 | // Chaining promises using then() and catch() 9 | p1.then((r) => { // r = {'foo': 'bar'} (resolved from p1) 10 | console.info(r) 11 | return p2; 12 | }).then((r1) => { // r1 = {'foo2': 'bar2'} (resolved from p2) 13 | console.info(r1) 14 | return p3; 15 | }).then((r2) => { // r2 = undefined , p3 throws an error 16 | console.info(r2) 17 | }).catch((err) => { // error is catched here 18 | console.info(err); // display Error: oops (rejected from p3) 19 | }); 20 | 21 | // Using async/await 22 | (async function() { 23 | try { 24 | const r = await p1; 25 | const r2 = await p2; 26 | const r3 = await p3; 27 | } catch(err) { 28 | console.info(err); // display Error: oops (rejected from p3) 29 | } 30 | })(); -------------------------------------------------------------------------------- /snippets/09-promise-all-vs-promise-allsettled.js: -------------------------------------------------------------------------------- 1 | // Minutes of Javascript #09 - Promise.all vs Promise.allSettled 2 | // See: https://playcode.io/613524/ 3 | const p1 = new Promise((resolve, reject) => setTimeout(resolve({'foo': 'bar'}), 500)); 4 | const p2 = new Promise((resolve, reject) => setTimeout(resolve({'moe': 'hey'}), 1500)); 5 | const p3 = new Promise((resolve, reject) => setTimeout(reject(new Error('ko')), 800)); 6 | 7 | (async function() { 8 | const p = [p1,p2,p3]; 9 | // Promise.allSettled waits for all promises to be done (rejected or resolved/fulfilled) 10 | const settledPromises = await Promise.allSettled(p); 11 | console.info(settledPromises); 12 | /*[ 13 | { status: 'fulfilled', value: { foo: 'bar' } }, 14 | { status: 'fulfilled', value: { moe: 'hey' } }, 15 | { status: 'rejected', reason: Error: ko} 16 | ]*/ 17 | // Promise.all resolves if and only if all promises are resolved/fulfilled 18 | // Promise.all rejects if one of the promises rejects 19 | const okPromises = [p1,p2]; 20 | try { 21 | // Promise.all(okPromises) resolves because p1 and p2 resolves and no promise rejects 22 | const okResolvedPromises = await Promise.all(okPromises); 23 | console.info('all promises resolved !', okResolvedPromises); 24 | 25 | // Promise.all(p) won't resolve because p3 rejects 26 | const allResolvedPromises = await Promise.all(p); 27 | console.info('all promises resolved !', allResolvedPromises); 28 | } catch(err) { 29 | console.info(err); // returns Error: ko from the second Promise.all 30 | } 31 | })(); 32 | -------------------------------------------------------------------------------- /snippets/10-promise-race-any-join.js: -------------------------------------------------------------------------------- 1 | // Minutes of Javascript #10 - Promise.race 2 | // See: https://playcode.io/613524/ 3 | const Promise = require('bluebird'); // very complete promises library 4 | 5 | const p1 = new Promise((resolve, reject) => setTimeout(resolve({'foo': 'bar'}), 500)); 6 | const p2 = new Promise((resolve, reject) => setTimeout(resolve({'moe': 'hey'}), 1500)); 7 | 8 | (async function() { 9 | // Promise.race resolves the first promise to resolve 10 | const res1 = await Promise.race([p1,p2]); 11 | console.info(res1); // As p1 resolves before p2, it returns {'foo': 'bar'} 12 | 13 | // Promise.any resolve the first promises to resolve 14 | // and keep resolving the others unless all within the iterable object reject 15 | const res2 = await Promise.any([p1,p2]); 16 | console.info(res2); // returns {'foo': 'bar'} 17 | 18 | // More performant than Promise.all if you have a static amount of discrete promises to resolves 19 | const res3 = await Promise.join(p1,p2) 20 | console.info(res3); // returns [ { foo: 'bar' }, { moe: 'hey' } ] 21 | })(); 22 | -------------------------------------------------------------------------------- /snippets/11-proxies-part-1.js: -------------------------------------------------------------------------------- 1 | // Minutes of Javascript #11 - Proxies Part 1. 2 | // See: https://playcode.io/648685/ 3 | 4 | // The Proxy object enables you to create a proxy for another object, 5 | // which can intercept and redefine fundamental operations for that object. 6 | let target = {}, handler = {}; 7 | let proxy = new Proxy(target, handler); // All of proxy’s internal methods are forwarded to target. 8 | proxy.name = 'Joe'; // will call handler.[[Set]]() if defined else fallback to target.[[Set]]() 9 | console.info(target.person) // Returns "Joe" 10 | console.info(proxy === target) // Return false /!\ proxy !== target 11 | 12 | // Now let's redefine proxy.[[set]]() 13 | target = {}, handler = { 14 | set: function (target, key, value, receiver) { 15 | throw new Error("You can't set properties on this object."); 16 | } 17 | }; 18 | proxy = new Proxy(target, handler); 19 | proxy.name = 'Joe'; // will throw 'Error: You can't set properties on this object.' 20 | -------------------------------------------------------------------------------- /snippets/12-proxies-part-2-with-reflect.js: -------------------------------------------------------------------------------- 1 | // Minutes of Javascript #12 - Proxies Part 2. (with Reflect) 2 | // See: https://playcode.io/648696/ 3 | 4 | // You can't set a deep object value directly without creating each level of the object 5 | // Let's make it possible with Proxy and Reflect! 6 | function SuperObject() { 7 | const handler = { 8 | // Before calling [[set]](), Proxy will call [[get]]() 9 | // So let's implement the creation logic in the get 10 | get: function (target, key, receiver) { 11 | if (!target[key]) { 12 | target[key] = SuperObject(); // if key does not exists, we call SuperObject recursively 13 | } 14 | // now we can call the default behavior of delegating to target[[get]]() 15 | // this is what Reflect is meant for 16 | return Reflect.get(target, key, receiver); 17 | } 18 | }; 19 | return new Proxy({}, handler); 20 | } 21 | 22 | // Example! 23 | let myObject = SuperObject(); 24 | myObject.prop1.prop2.prop3 = "values"; 25 | console.info(myObject); // returns { prop1: { prop2: { prop3: 'values' } } } -------------------------------------------------------------------------------- /snippets/13-proxies-part-3.js: -------------------------------------------------------------------------------- 1 | // Minutes of Javascript #13 - Proxies Part 3. 2 | // See: https://playcode.io/648707/ 3 | 4 | // Let's explore full power of Proxies by implementing a readOnly functions 5 | // This function will turn any object in read-only mode 6 | function makeReadOnly(target) { 7 | // Making sure `target` is an object before going further 8 | if (target === undefined || target === null || typeof(target) != 'object') return target; 9 | 10 | const reflectMethod = (method) => (target, key, receiver) => { 11 | var result = Reflect[method](target, key, receiver); 12 | if (Object(result) === result) { 13 | return makeReadOnly(result); 14 | } 15 | return result; 16 | } 17 | const handler = { 18 | set: () => false, 19 | setPrototypeOf: () => false, 20 | defineProperty: () => false, 21 | deleteProperty: () => false, 22 | preventExtensions: () => false, 23 | getPrototypeOf: reflectMethod('getPrototypeOf'), 24 | getOwnPropertyDescriptor: reflectMethod('getOwnPropertyDescriptor'), 25 | get: reflectMethod('get'), 26 | } 27 | 28 | return new Proxy(target, handler); 29 | } 30 | 31 | // Example 32 | let myObject = makeReadOnly({a: {b: 'value'}}); 33 | 34 | myObject.a = 'newValue'; // on direct property 35 | console.info(myObject); // returns { a: { b: 'value' } } 36 | 37 | myObject.a.b = 'newValue'; // on sub-property 38 | console.info(myObject); // returns { a: { b: 'value' } } 39 | 40 | var proto = Object.getPrototypeOf(myObject); // also works on prototype 41 | console.info(proto) // return {} 42 | proto.bar = function() { 43 | console.log("bar - new method"); 44 | }; 45 | console.info(proto); // returns {} -------------------------------------------------------------------------------- /snippets/14-flat-flatmap.js: -------------------------------------------------------------------------------- 1 | // Minutes of Javascript #14 - flat() and flatMap() 2 | // See: https://playcode.io/651129/ 3 | 4 | /* 5 | arr.flat([depth]); where depth is a number; defaults to 1; can equal Infinity 6 | The depth level specifying how deep a nested array structure should be flattened. 7 | It returns a new array with the sub-array elements concatenated into it. 8 | */ 9 | const flat = ['New Delhi', ['Bombay', 'Bangalore', ['Paris']]].flat(); 10 | console.info(flat); // [ 'New Delhi', 'Bombay', 'Bangalore', [ 'Paris' ] ] 11 | 12 | const flat2 = ['New Delhi', ['Bombay', 'Bangalore', ['Paris']]].flat(2); 13 | console.info(flat2); // [ 'New Delhi', 'Bombay', 'Bangalore', 'Paris' ] 14 | 15 | // Using Infinity for deep flattening 16 | const flatInf = ['New Delhi', ['Bombay', ['Bangalore', [['Paris']]]]].flat(Infinity); 17 | console.info(flatInf); // [ 'New Delhi', 'Bombay', 'Bangalore', 'Paris' ] 18 | 19 | /* 20 | arr.flatMap(callback); with callback(currentValue[, index[, array]]) 21 | Callback is applied to each element of the array (identical to a map()) then flat(1) is applied. 22 | flatMap() is often quite useful as merging both into one method is slightly more efficient. 23 | */ 24 | const flatMap = ['I love this', 'javascript snippets.'].flatMap(words => words.split(' ')); 25 | console.info(flatMap); // [ 'I', 'love', 'this', 'javascript', 'snippets.' ] -------------------------------------------------------------------------------- /snippets/15-fun-with-emoji.js: -------------------------------------------------------------------------------- 1 | // Minutes of Javascript #14 - Fun with Emoji! 2 | // See: https://playcode.io/651693/ 3 | 4 | // Interesting features of Emoji and Javascript 5 | // It’s possible to spread emoji sequences into their single parts 6 | console.info([...'👩‍👩‍👧‍👦‍']); // returns ['👩', '‍', '👩', '‍', '👧', '‍','👦', '‍'] 7 | console.info([...'👨‍👧‍👧']); // returns [ '👨', '‍', '👧', '‍', '👧' ] 8 | console.info([...'👨‍❤️‍💋‍👨']) // ['👨', '‍', '❤', '️', '‍', '💋', '‍', '👨'] 9 | 10 | // You can also combine Emoji 11 | console.info(["👨", "‍", "👩", "‍", "👧"].reduce((prev, curr) => prev + curr)) // returns "👨‍👩‍👧" 12 | 13 | // Zero-width joiner (ZWJ) "\u200d" acts as the glue between Emoji 14 | function combineEmoji(arr) { 15 | return arr.reduce((a,b) => a + '\u200d' + b); 16 | } 17 | console.info(combineEmoji(['🏳','🌈'])); // returns "🏳‍🌈" -------------------------------------------------------------------------------- /snippets/16-bizarre-javascript.js: -------------------------------------------------------------------------------- 1 | // Minutes of Javascript #16 - Some bizarre things in Javascript 2 | // See: https://playcode.io/652366/ 3 | 4 | // null is an Object 5 | console.info(typeof null); 6 | console.info(null instanceof Object); // returns false 🤔 7 | 8 | // NaN is not equal to anything. You can use isNan() to check NaN value 9 | console.info(typeof NaN); // NaN is a Number 10 | console.info(NaN instanceof Number); // returns false 11 | console.info(NaN === NaN); // returns false 12 | console.info(isNaN(NaN)); // returns true 13 | 14 | // About number 15 | console.info(0.1 + 0.2 === 0.3); // return false; 16 | console.info(0.1+0.2); // returns 0.30000000000000004 -------------------------------------------------------------------------------- /snippets/17-breaking-nested-loops.js: -------------------------------------------------------------------------------- 1 | // Minutes of Javascript #17 - Breaking in nested loops 2 | // See: https://playcode.io/652649/ 3 | 4 | /* In Javascript you can specify labels to break from a specific nested loop. */ 5 | 6 | const arr1 = [1,2,3,4,5,6]; 7 | const arr2 = [1,2,3,4,5,6]; 8 | const arr3 = [1,2,3,4,5,6]; 9 | 10 | loop1: 11 | for (const i of arr1) { 12 | loop2: 13 | for (const j of arr2) { 14 | loop3: 15 | for (const k of arr3) { 16 | console.info(i,j,k); // returns only 1 1 1 as the loop is stopped by the `break loop1` statement 17 | break loop1; 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /snippets/18-eventemitter.js: -------------------------------------------------------------------------------- 1 | // Minutes of Javascript #18 - EventEmitter 2 | // See: https://playcode.io/655960/ 3 | /* 4 | In Node.js aal objects that emit events are instances of the EventEmitter class. 5 | */ 6 | const EventEmitter = require('events'); 7 | 8 | /* 9 | First useful method is .on('event', callback). 10 | The callback is called when 'event' is emitted, callback is a 'listener' for that event. 11 | */ 12 | const myEventEmitter = new EventEmitter(); 13 | myEventEmitter.on('event', (data) => console.info('1st listener', data)); 14 | 15 | /* 16 | .on() is conjointly used with .emit('event', data). 17 | .emit() will trigger the listeners already declared with .on(). 18 | */ 19 | myEventEmitter.emit('event', {'foo': 'bar'}); // returns "1st listener { foo: 'bar' }" 20 | 21 | /* 22 | .once() registers a listener that is called at most once for a particular event. 23 | Once the event is emitted, the listener is unregistered and then called. 24 | */ 25 | myEventEmitter.once('2ndEvent', (data) => console.info('Once listener', data)); 26 | myEventEmitter.emit('2ndEvent', {'foo': 'bar'}); // returns "Once listener { foo: 'bar' }" 27 | myEventEmitter.emit('2ndEvent', {'foo': 'bar'}); // ignored -------------------------------------------------------------------------------- /snippets/19-implement-eventemitter-part1.js: -------------------------------------------------------------------------------- 1 | // Minutes of Javascript #19 - How to implement a local EventEmitter? (part 1.) 2 | // See: https://playcode.io/655981/ 3 | 4 | // First create a new class called "EventEmitter" 5 | class EventEmitter { 6 | constructor() { // Let's register a Map() for storing (event, callbacks[]) values 7 | this.callbackMap = new Map(); // We use a map so we can pass anything as key (an object uses string as key) 8 | } 9 | 10 | // The .on() method is storing (event, callback) in our in-memory map 11 | on(event, cb) { 12 | const callbacks = this.callbackMap.get(event); 13 | this.callbackMap.set(event, callbacks ? [...callbacks, cb] : [cb]); 14 | } 15 | 16 | // The .emit() method is calling all registered callbacks for a given event 17 | emit(event, data) { 18 | const callbacks = this.callbackMap.get(event); 19 | if (!Array.isArray(callbacks)) return; // returns early 20 | 21 | callbacks.map((callback) => callback(data)); 22 | } 23 | } 24 | module.exports = EventEmitter; 25 | 26 | // Now let's use it 27 | const myEventEmitter = new EventEmitter(); 28 | myEventEmitter.on('event', (data) => console.info('listener #1', data)); 29 | myEventEmitter.on('event', (data) => console.info('listener #2', data)); 30 | myEventEmitter.emit('event', {'foo': 'bar'}); 31 | /* 32 | listener #1 { foo: 'bar' } 33 | listener #2 { foo: 'bar' } 34 | */ -------------------------------------------------------------------------------- /snippets/20-implement-eventemitter-part2.spec.js: -------------------------------------------------------------------------------- 1 | // Minutes of Javascript #20 - How to implement a local EventEmitter? (part 2.) 2 | // See: https://playcode.io/655996/ 3 | 4 | // use your own path to the code of the first part 5 | const EventEmitter = require('./19-implement-eventemitter-part1'); 6 | 7 | describe('EventEmitter', () => { 8 | let cb1, cb2, cb3, eventEmitter; 9 | beforeEach(() => { 10 | cb1 = jest.fn(); 11 | cb2 = jest.fn(); 12 | cb3 = jest.fn(); 13 | eventEmitter = new EventEmitter(); 14 | eventEmitter.on('event', cb1); 15 | }); 16 | 17 | it('Register a listener', () => { 18 | expect(eventEmitter.callbackMap.size).toBe(1); 19 | expect(eventEmitter.callbackMap.get('event')).toStrictEqual([cb1]); 20 | }); 21 | 22 | it('Stack listeners if same key used', () => { 23 | eventEmitter.on('event', cb2); 24 | 25 | expect(eventEmitter.callbackMap.size).toBe(1); 26 | expect(eventEmitter.callbackMap.get('event')).toStrictEqual([cb1,cb2]); 27 | }); 28 | 29 | it('Separate listeners if keys are different', () => { 30 | eventEmitter.on('event2', cb2); 31 | 32 | expect(eventEmitter.callbackMap.size).toBe(2); 33 | expect(eventEmitter.callbackMap.get('event')).toStrictEqual([cb1]); 34 | expect(eventEmitter.callbackMap.get('event2')).toStrictEqual([cb2]); 35 | }); 36 | 37 | it('trigger all callbacks when event is emitted', () => { 38 | const data = {'foo': 'bar'}; 39 | eventEmitter.on('event', cb2); 40 | eventEmitter.on('event2', cb3); 41 | eventEmitter.emit('event', data); 42 | 43 | expect(cb1).toHaveBeenCalledWith(data); 44 | expect(cb2).toHaveBeenCalledWith(data); 45 | expect(cb3).not.toHaveBeenCalled(); 46 | }); 47 | }); 48 | -------------------------------------------------------------------------------- /snippets/21-tips-underscore-number.js: -------------------------------------------------------------------------------- 1 | // Minutes of Javascript #21 - Using "_" in numbers for better readability 2 | // See: https://playcode.io/661188/ 3 | 4 | const NUMBER_OF_JS_DEV_ON_EARTH = 11700000; 5 | const NUMBER_OF_JS_DEV_ON_EARTH_EASY_READING = 11_700_000; 6 | 7 | console.info(NUMBER_OF_JS_DEV_ON_EARTH); // returns "11700000" 8 | console.info(NUMBER_OF_JS_DEV_ON_EARTH_EASY_READING); // returns "11700000" -------------------------------------------------------------------------------- /snippets/22-map-vs-filter-vs-reduce.js: -------------------------------------------------------------------------------- 1 | // Minutes of Javascript #22 - Array: .map() vs .filter() vs .reduce() 2 | // Source: https://github.com/olivierloverde/minutes-of-javascript/blob/main/snippets/22-map-vs-filter-vs-reduce.js 3 | 4 | const arr = [26, 86, 45, 69, 25, 45]; // Taking random array 5 | 6 | // Map function 7 | // Defination:- it returns the new array from the base array after implementing some logic on int. 8 | // length of the new array is always equal to length of the base array 9 | const mapArr = arr.map((value) => value * 2); 10 | console.log(mapArr); // [ 52, 172, 90, 138, 50, 90 ] 11 | console.log(arr.length === mapArr.length); // true 12 | 13 | // Filter function 14 | // Defination:- it returns the new array from the base array only if some condition is true 15 | // length of the new can be less than the length of the base array 16 | const filterArr = arr.filter((value) => value > 50); 17 | console.log(filterArr); // [ 86, 69 ] 18 | 19 | // Reduce function 20 | // Defination:- it returns the single value from the array. 21 | const reduceArr = arr.reduce((accumulator, value) => accumulator + value, 0); 22 | console.log(reduceArr); // 296 23 | 24 | // Bonus for reduce 25 | const pets = ["dog", "chicken", "cat", "dog", "chicken", "chicken", "rabbit"]; 26 | // lets count animals with reduce 27 | 28 | const petCount = pets.reduce((obj, pet) => { 29 | obj[pet] ? obj[pet]++ : (obj[pet] = 1); // explenation:- if object has Dog in it than increase its count else add Dog and assign the value of 1 30 | return obj; 31 | }, {}); 32 | 33 | console.log(petCount); // { dog: 2, chicken: 3, cat: 1, rabbit: 1 } 34 | 35 | // CheatSheet 36 | // map([🌽, 🐮, 🐔], cook) 37 | // => [🍿, 🍔, 🍳] 38 | 39 | // filter([🍿, 🍔, 🍳], isVegetarian) 40 | // => [🍿, 🍳] 41 | 42 | // reduce([🍿, 🍳], eat) 43 | // => 💩 44 | -------------------------------------------------------------------------------- /snippets/23-generator-function-yield-usage.js: -------------------------------------------------------------------------------- 1 | // Minutes of Javascript #23 - Generator function* and yield usage 2 | // Source: https://github.com/olivierloverde/minutes-of-javascript/blob/main/snippets/23-generator-function-yield-usage.js 3 | 4 | // Generators are a special class of functions that simplify the task of writing iterators. 5 | // A generator is a function that generates a series of values. 6 | function* generatorFunction() { 7 | let i = 0; 8 | while (i < 2) { 9 | yield ++i; 10 | } 11 | return i; 12 | } 13 | 14 | const fn = generatorFunction(); 15 | console.info(fn); // Object [Generator] {} 16 | 17 | // Generator stops execution at first yield instruction 18 | // Use .next() to start execution again from the last stop point 19 | console.info(fn.next()); // { value: 1, done: false } // i = 0, return ++0 = 1 20 | console.info(fn.next()); // { value: 2, done: false } // i = 1, return ++1 = 2 21 | console.info(fn.next()); // { value: 2, done: true } // i = 2, exit loop, return i = 2 22 | console.info(fn.next()); // { value: undefined, done: true } // already done, return undefined 23 | 24 | // You can use for...of statement on generator 25 | const fn2 = generatorFunction(); 26 | for (index of fn2) { 27 | console.log(index); // return 1, then 2 28 | } 29 | -------------------------------------------------------------------------------- /snippets/24-usage-of-switch-with-numeric-ranges.js: -------------------------------------------------------------------------------- 1 | // Minutes of Javascript #24 - Usage of switch (true), an example with numeric ranges 2 | // Source: https://github.com/olivierloverde/minutes-of-javascript/blob/main/snippets/24-usage-of-switch-with-numeric-ranges.js 3 | 4 | // switch (true) may seem absurd but you can match against values as well as expressions. 5 | // Expressions will be evaluated before matching, so any expression that evals to true will be matched. 6 | // Ref: https://262.ecma-international.org/10.0/#sec-switch-statement 7 | 8 | // For example, you can use a switch statement with a numeric range in the case with: 9 | function canDrink(age) { 10 | switch (true) { 11 | case (age < 18): 12 | return "No"; 13 | case (age < 21): 14 | return "Not in the USA"; 15 | default: 16 | return "Yes"; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /snippets/25-symbols-property-keys-without-name-collisions.js: -------------------------------------------------------------------------------- 1 | // Minutes of Javascript #25 - Symbols: property keys without name collisions 2 | // Source: https://github.com/olivierloverde/minutes-of-javascript/blob/main/snippets/25-symbols-property-keys-without-name-collisions.js 3 | 4 | // Symbols are values that programs use as property keys without risking name collisions. 5 | // Using Symbol(description) creates a new unique value. 6 | const payload = {}; 7 | payload[Symbol("Description")] = 'uniqueRef #1'; 8 | payload[Symbol('Description 2')] = 'uniqueRef #2'; 9 | /* 10 | { 11 | [Symbol(Description)]: 'uniqueRef #1', 12 | [Symbol(Description2)]: 'uniqueRef #2' 13 | } 14 | */ 15 | 16 | // Symbol.for(key) accesses a set of existing symbols called the symbol registry. 17 | const newSymbol = Symbol.for('symbolKey'); 18 | const existingSymbol = Symbol.for('symbolKey'); 19 | console.info(newSymbol === existingSymbol) // returns true 20 | 21 | // newSymbol and existingSymbol are the same symbol 22 | const payload2 = {}; 23 | payload2[newSymbol] = 'myValue'; // { [Symbol(symbolKey)]: 'myValue' } 24 | payload2[existingSymbol] = 'newValue'; // { [Symbol(symbolKey)]: 'newValue' } 25 | -------------------------------------------------------------------------------- /snippets/26-void-operator.js: -------------------------------------------------------------------------------- 1 | // Minutes of Javascript #26 - The void operator 2 | // Source: https://github.com/olivierloverde/minutes-of-javascript/blob/main/snippets/26-void-operator.js 3 | 4 | // The void operator evaluates the given expression and then returns undefined 5 | console.info(void {}); // Outputs: undefined 6 | 7 | 8 | // It can be used when the return value of a function is not intended to be used 9 | // For example: it ensure that changing API do not cause the parent arrow fonction behavior to change 10 | button.onclick = () => void doSomething(); 11 | 12 | 13 | // void is also useful for immediately-invoked function expression 14 | // Without the void keyword, it will result in an Uncaught SyntaxError 15 | void function fn() { 16 | console.info('Hey!'); 17 | }(); 18 | -------------------------------------------------------------------------------- /snippets/27-set-duplicate-values-array.js: -------------------------------------------------------------------------------- 1 | // Minutes of Javascript #27 - Using new Set() to get rid of duplicate values in array 2 | // Source: https://github.com/olivierloverde/minutes-of-javascript/blob/main/snippets/27-set-duplicate-values-array.js 3 | 4 | const myArray = [1,2,2,2,6,8,99,2,6,99,8,7]; 5 | const uniqueValuesOfMyArray = [...new Set(myArray)]; 6 | 7 | console.info(uniqueValuesOfMyArray); // returns [ 1, 2, 6, 8, 99, 7 ] 8 | -------------------------------------------------------------------------------- /snippets/28-object-destructuring-array.js: -------------------------------------------------------------------------------- 1 | // Minutes of Javascript #28 - Object destructuring on Array 2 | // Source: https://github.com/olivierloverde/minutes-of-javascript/blob/main/snippets/28-object-destructuring-array.js 3 | 4 | const myArray = ['first', 'second', 'third', 'last']; 5 | 6 | // Examples 7 | const { 1: sec } = myArray; 8 | console.info(sec); // returns 'second' 9 | 10 | // You can destructure the length property too 11 | const { length, 0: first, [length-1]: last } = myArray; 12 | console.info(first); // returns 'first' 13 | console.info(last); // returns 'last' 14 | console.info(length); // returns 4 15 | --------------------------------------------------------------------------------