[
  {
    "path": ".editorconfig",
    "content": "root = true\n\n[*]\ncharset = utf-8\nend_of_line = lf\ninsert_final_newline = true\nindent_style = tab\nindent_size = 4\n\n[*.md]\nindent_style = space\nindent_size = 4\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/content-question.md",
    "content": "---\nname: Content Question\nabout: Ask a question about something you read in the books?\nlabels:\n\n---\n\n**We are not currently accepting any more corrections to the book content. The 2nd edition books have all been published and finalized. Thank you for your interest and support.**\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/foreign-translation-request.md",
    "content": "---\nname: Foreign Translation Request\nabout: Want to request a translation into a foreign language?\nlabels:\n\n---\n\nForeign translations are appreciated, but only for the 3 second edition books.\n\n**I will not be accepting any new foreign translations for previous editions.**\n\n----\n\nPlease check these issues first:\n\n* https://github.com/getify/You-Dont-Know-JS/issues?utf8=%E2%9C%93&q=label%3A%22foreign+language+translations%22+\n* https://github.com/getify/You-Dont-Know-JS/issues/9\n* https://github.com/getify/You-Dont-Know-JS/issues/900\n* https://github.com/getify/You-Dont-Know-JS/issues/1378\n\nTo summarize, the steps for a foreign language translation are:\n\n1. Fork this repo\n2. Make your own translation entirely in your fork, preferably of all six books, but at a minimum of one whole book\n3. File an issue asking for a branch to be made on our main repo, named for that [language's ISO code](http://www.lingoes.net/en/translator/langcode.htm)\n4. Once the branch is created, you can PR to merge your translated work in\n5. Once the merge is complete, I will promote you to a repository maintainer so you can manage any further translation maintenance work on your own branch of this repo\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/report-technical-mistake.md",
    "content": "---\nname: Report Technical Mistake\nabout: Help us fix a mistake in the code.\nlabels:\n\n---\n\n**We are not currently accepting any more corrections to the book content. The 2nd edition books have all been published and finalized. Thank you for your interest and support.**\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/textual-grammar-typo.md",
    "content": "---\nname: Textual/Grammar Typo\nabout: Help us correct a spelling or grammar error in the text.\nlabels:\n\n---\n\n**We are not currently accepting any more corrections to the book content. The 2nd edition books have all been published and finalized. Thank you for your interest and support.**\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing\n\nThis book series is now complete, **so we are no longer open to contributions.**\n\n## Translations\n\nIf you're wanting to translate these books, please keep in mind that any such translations **must be posted to this github repository, free and open, and not monetized.**\n\nForeign translations are appreciated, but only for the 3 second edition books.\n\n**We will not be accepting any new foreign translations for previous editions.**\n\n----\n\nPlease check these issues first:\n\n* https://github.com/getify/You-Dont-Know-JS/issues?utf8=%E2%9C%93&q=label%3A%22foreign+language+translations%22+\n* https://github.com/getify/You-Dont-Know-JS/issues/9\n* https://github.com/getify/You-Dont-Know-JS/issues/900\n* https://github.com/getify/You-Dont-Know-JS/issues/1378\n\nTo summarize, the steps for a foreign language translation are:\n\n1. Fork this repo\n2. Make your own translation entirely in your fork, preferably of all six books, but at a minimum of one whole book\n3. File an issue asking for a branch to be made on our main repo, named for that [language's ISO code](http://www.lingoes.net/en/translator/langcode.htm)\n4. Once the branch is created, you can PR to merge your translated work in\n5. Once the merge is complete, I will promote you to a repository maintainer so you can manage any further translation maintenance work on your own branch of this repo\n\n## Reading Experience (Chapter/Section links, etc)\n\nI understand that reading one long .md file, with no relative cross links to other sections/etc, is not the preferred reading experience for most of you. As such, it's totally reasonable to want to file an issue/PR to add those kinds of features.\n\nThis topic has been brought up many times, and I've considered it. But we are not accepting such changes. \n\nThe main purpose of my book repos is to track and manage the content for the purposes of publication (paid-for ebooks and print books). I do this in the open because I also care about providing free and early access to the content, to make sure there is no paywall barrier to learning.\n\nAs such, this repo **is not optimized for your reading experience.**\n\nThe intended **best reading experience** are the published books (either ebook or print), so I encourage you to purchase them for that purpose.\n\n## Editions\n\nThe current (and final) edition of the books is the 2nd edition.\n\nWe **are not accepting any contributions** for these books, no exceptions.\n\n## Typos?\n\nWe're not worried about typo fixes anymore. The books are done and published.\n\n## Search First!\n\nSeriously, no more need for contributions.\n\nIf you have a question, please search first before asking. It's probably already been asked and answered before, as these books have been around for 12 years now. \n"
  },
  {
    "path": "LICENSE.txt",
    "content": "Attribution-NonCommercial-NoDerivatives 4.0 International\n\n=======================================================================\n\nCreative Commons Corporation (\"Creative Commons\") is not a law firm and\ndoes not provide legal services or legal advice. Distribution of\nCreative Commons public licenses does not create a lawyer-client or\nother relationship. Creative Commons makes its licenses and related\ninformation available on an \"as-is\" basis. Creative Commons gives no\nwarranties regarding its licenses, any material licensed under their\nterms and conditions, or any related information. Creative Commons\ndisclaims all liability for damages resulting from their use to the\nfullest extent possible.\n\nUsing Creative Commons Public Licenses\n\nCreative Commons public licenses provide a standard set of terms and\nconditions that creators and other rights holders may use to share\noriginal works of authorship and other material subject to copyright\nand certain other rights specified in the public license below. The\nfollowing considerations are for informational purposes only, are not\nexhaustive, and do not form part of our licenses.\n\n     Considerations for licensors: Our public licenses are\n     intended for use by those authorized to give the public\n     permission to use material in ways otherwise restricted by\n     copyright and certain other rights. Our licenses are\n     irrevocable. Licensors should read and understand the terms\n     and conditions of the license they choose before applying it.\n     Licensors should also secure all rights necessary before\n     applying our licenses so that the public can reuse the\n     material as expected. Licensors should clearly mark any\n     material not subject to the license. This includes other CC-\n     licensed material, or material used under an exception or\n     limitation to copyright. More considerations for licensors:\n    wiki.creativecommons.org/Considerations_for_licensors\n\n     Considerations for the public: By using one of our public\n     licenses, a licensor grants the public permission to use the\n     licensed material under specified terms and conditions. If\n     the licensor's permission is not necessary for any reason--for\n     example, because of any applicable exception or limitation to\n     copyright--then that use is not regulated by the license. Our\n     licenses grant only permissions under copyright and certain\n     other rights that a licensor has authority to grant. Use of\n     the licensed material may still be restricted for other\n     reasons, including because others have copyright or other\n     rights in the material. A licensor may make special requests,\n     such as asking that all changes be marked or described.\n     Although not required by our licenses, you are encouraged to\n     respect those requests where reasonable. More_considerations\n     for the public:\n    wiki.creativecommons.org/Considerations_for_licensees\n\n=======================================================================\n\nCreative Commons Attribution-NonCommercial-NoDerivatives 4.0\nInternational Public License\n\nBy exercising the Licensed Rights (defined below), You accept and agree\nto be bound by the terms and conditions of this Creative Commons\nAttribution-NonCommercial-NoDerivatives 4.0 International Public\nLicense (\"Public License\"). To the extent this Public License may be\ninterpreted as a contract, You are granted the Licensed Rights in\nconsideration of Your acceptance of these terms and conditions, and the\nLicensor grants You such rights in consideration of benefits the\nLicensor receives from making the Licensed Material available under\nthese terms and conditions.\n\n\nSection 1 -- Definitions.\n\n  a. Adapted Material means material subject to Copyright and Similar\n     Rights that is derived from or based upon the Licensed Material\n     and in which the Licensed Material is translated, altered,\n     arranged, transformed, or otherwise modified in a manner requiring\n     permission under the Copyright and Similar Rights held by the\n     Licensor. For purposes of this Public License, where the Licensed\n     Material is a musical work, performance, or sound recording,\n     Adapted Material is always produced where the Licensed Material is\n     synched in timed relation with a moving image.\n\n  b. Copyright and Similar Rights means copyright and/or similar rights\n     closely related to copyright including, without limitation,\n     performance, broadcast, sound recording, and Sui Generis Database\n     Rights, without regard to how the rights are labeled or\n     categorized. For purposes of this Public License, the rights\n     specified in Section 2(b)(1)-(2) are not Copyright and Similar\n     Rights.\n\n  c. Effective Technological Measures means those measures that, in the\n     absence of proper authority, may not be circumvented under laws\n     fulfilling obligations under Article 11 of the WIPO Copyright\n     Treaty adopted on December 20, 1996, and/or similar international\n     agreements.\n\n  d. Exceptions and Limitations means fair use, fair dealing, and/or\n     any other exception or limitation to Copyright and Similar Rights\n     that applies to Your use of the Licensed Material.\n\n  e. Licensed Material means the artistic or literary work, database,\n     or other material to which the Licensor applied this Public\n     License.\n\n  f. Licensed Rights means the rights granted to You subject to the\n     terms and conditions of this Public License, which are limited to\n     all Copyright and Similar Rights that apply to Your use of the\n     Licensed Material and that the Licensor has authority to license.\n\n  g. Licensor means the individual(s) or entity(ies) granting rights\n     under this Public License.\n\n  h. NonCommercial means not primarily intended for or directed towards\n     commercial advantage or monetary compensation. For purposes of\n     this Public License, the exchange of the Licensed Material for\n     other material subject to Copyright and Similar Rights by digital\n     file-sharing or similar means is NonCommercial provided there is\n     no payment of monetary compensation in connection with the\n     exchange.\n\n  i. Share means to provide material to the public by any means or\n     process that requires permission under the Licensed Rights, such\n     as reproduction, public display, public performance, distribution,\n     dissemination, communication, or importation, and to make material\n     available to the public including in ways that members of the\n     public may access the material from a place and at a time\n     individually chosen by them.\n\n  j. Sui Generis Database Rights means rights other than copyright\n     resulting from Directive 96/9/EC of the European Parliament and of\n     the Council of 11 March 1996 on the legal protection of databases,\n     as amended and/or succeeded, as well as other essentially\n     equivalent rights anywhere in the world.\n\n  k. You means the individual or entity exercising the Licensed Rights\n     under this Public License. Your has a corresponding meaning.\n\n\nSection 2 -- Scope.\n\n  a. License grant.\n\n       1. Subject to the terms and conditions of this Public License,\n          the Licensor hereby grants You a worldwide, royalty-free,\n          non-sublicensable, non-exclusive, irrevocable license to\n          exercise the Licensed Rights in the Licensed Material to:\n\n            a. reproduce and Share the Licensed Material, in whole or\n               in part, for NonCommercial purposes only; and\n\n            b. produce and reproduce, but not Share, Adapted Material\n               for NonCommercial purposes only.\n\n       2. Exceptions and Limitations. For the avoidance of doubt, where\n          Exceptions and Limitations apply to Your use, this Public\n          License does not apply, and You do not need to comply with\n          its terms and conditions.\n\n       3. Term. The term of this Public License is specified in Section\n          6(a).\n\n       4. Media and formats; technical modifications allowed. The\n          Licensor authorizes You to exercise the Licensed Rights in\n          all media and formats whether now known or hereafter created,\n          and to make technical modifications necessary to do so. The\n          Licensor waives and/or agrees not to assert any right or\n          authority to forbid You from making technical modifications\n          necessary to exercise the Licensed Rights, including\n          technical modifications necessary to circumvent Effective\n          Technological Measures. For purposes of this Public License,\n          simply making modifications authorized by this Section 2(a)\n          (4) never produces Adapted Material.\n\n       5. Downstream recipients.\n\n            a. Offer from the Licensor -- Licensed Material. Every\n               recipient of the Licensed Material automatically\n               receives an offer from the Licensor to exercise the\n               Licensed Rights under the terms and conditions of this\n               Public License.\n\n            b. No downstream restrictions. You may not offer or impose\n               any additional or different terms or conditions on, or\n               apply any Effective Technological Measures to, the\n               Licensed Material if doing so restricts exercise of the\n               Licensed Rights by any recipient of the Licensed\n               Material.\n\n       6. No endorsement. Nothing in this Public License constitutes or\n          may be construed as permission to assert or imply that You\n          are, or that Your use of the Licensed Material is, connected\n          with, or sponsored, endorsed, or granted official status by,\n          the Licensor or others designated to receive attribution as\n          provided in Section 3(a)(1)(A)(i).\n\n  b. Other rights.\n\n       1. Moral rights, such as the right of integrity, are not\n          licensed under this Public License, nor are publicity,\n          privacy, and/or other similar personality rights; however, to\n          the extent possible, the Licensor waives and/or agrees not to\n          assert any such rights held by the Licensor to the limited\n          extent necessary to allow You to exercise the Licensed\n          Rights, but not otherwise.\n\n       2. Patent and trademark rights are not licensed under this\n          Public License.\n\n       3. To the extent possible, the Licensor waives any right to\n          collect royalties from You for the exercise of the Licensed\n          Rights, whether directly or through a collecting society\n          under any voluntary or waivable statutory or compulsory\n          licensing scheme. In all other cases the Licensor expressly\n          reserves any right to collect such royalties, including when\n          the Licensed Material is used other than for NonCommercial\n          purposes.\n\n\nSection 3 -- License Conditions.\n\nYour exercise of the Licensed Rights is expressly made subject to the\nfollowing conditions.\n\n  a. Attribution.\n\n       1. If You Share the Licensed Material, You must:\n\n            a. retain the following if it is supplied by the Licensor\n               with the Licensed Material:\n\n                 i. identification of the creator(s) of the Licensed\n                    Material and any others designated to receive\n                    attribution, in any reasonable manner requested by\n                    the Licensor (including by pseudonym if\n                    designated);\n\n                ii. a copyright notice;\n\n               iii. a notice that refers to this Public License;\n\n                iv. a notice that refers to the disclaimer of\n                    warranties;\n\n                 v. a URI or hyperlink to the Licensed Material to the\n                    extent reasonably practicable;\n\n            b. indicate if You modified the Licensed Material and\n               retain an indication of any previous modifications; and\n\n            c. indicate the Licensed Material is licensed under this\n               Public License, and include the text of, or the URI or\n               hyperlink to, this Public License.\n\n          For the avoidance of doubt, You do not have permission under\n          this Public License to Share Adapted Material.\n\n       2. You may satisfy the conditions in Section 3(a)(1) in any\n          reasonable manner based on the medium, means, and context in\n          which You Share the Licensed Material. For example, it may be\n          reasonable to satisfy the conditions by providing a URI or\n          hyperlink to a resource that includes the required\n          information.\n\n       3. If requested by the Licensor, You must remove any of the\n          information required by Section 3(a)(1)(A) to the extent\n          reasonably practicable.\n\n\nSection 4 -- Sui Generis Database Rights.\n\nWhere the Licensed Rights include Sui Generis Database Rights that\napply to Your use of the Licensed Material:\n\n  a. for the avoidance of doubt, Section 2(a)(1) grants You the right\n     to extract, reuse, reproduce, and Share all or a substantial\n     portion of the contents of the database for NonCommercial purposes\n     only and provided You do not Share Adapted Material;\n\n  b. if You include all or a substantial portion of the database\n     contents in a database in which You have Sui Generis Database\n     Rights, then the database in which You have Sui Generis Database\n     Rights (but not its individual contents) is Adapted Material; and\n\n  c. You must comply with the conditions in Section 3(a) if You Share\n     all or a substantial portion of the contents of the database.\n\nFor the avoidance of doubt, this Section 4 supplements and does not\nreplace Your obligations under this Public License where the Licensed\nRights include other Copyright and Similar Rights.\n\n\nSection 5 -- Disclaimer of Warranties and Limitation of Liability.\n\n  a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE\n     EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS\n     AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF\n     ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,\n     IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,\n     WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR\n     PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,\n     ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT\n     KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT\n     ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.\n\n  b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE\n     TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,\n     NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,\n     INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,\n     COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR\n     USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN\n     ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR\n     DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR\n     IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.\n\n  c. The disclaimer of warranties and limitation of liability provided\n     above shall be interpreted in a manner that, to the extent\n     possible, most closely approximates an absolute disclaimer and\n     waiver of all liability.\n\n\nSection 6 -- Term and Termination.\n\n  a. This Public License applies for the term of the Copyright and\n     Similar Rights licensed here. However, if You fail to comply with\n     this Public License, then Your rights under this Public License\n     terminate automatically.\n\n  b. Where Your right to use the Licensed Material has terminated under\n     Section 6(a), it reinstates:\n\n       1. automatically as of the date the violation is cured, provided\n          it is cured within 30 days of Your discovery of the\n          violation; or\n\n       2. upon express reinstatement by the Licensor.\n\n     For the avoidance of doubt, this Section 6(b) does not affect any\n     right the Licensor may have to seek remedies for Your violations\n     of this Public License.\n\n  c. For the avoidance of doubt, the Licensor may also offer the\n     Licensed Material under separate terms or conditions or stop\n     distributing the Licensed Material at any time; however, doing so\n     will not terminate this Public License.\n\n  d. Sections 1, 5, 6, 7, and 8 survive termination of this Public\n     License.\n\n\nSection 7 -- Other Terms and Conditions.\n\n  a. The Licensor shall not be bound by any additional or different\n     terms or conditions communicated by You unless expressly agreed.\n\n  b. Any arrangements, understandings, or agreements regarding the\n     Licensed Material not stated herein are separate from and\n     independent of the terms and conditions of this Public License.\n\n\nSection 8 -- Interpretation.\n\n  a. For the avoidance of doubt, this Public License does not, and\n     shall not be interpreted to, reduce, limit, restrict, or impose\n     conditions on any use of the Licensed Material that could lawfully\n     be made without permission under this Public License.\n\n  b. To the extent possible, if any provision of this Public License is\n     deemed unenforceable, it shall be automatically reformed to the\n     minimum extent necessary to make it enforceable. If the provision\n     cannot be reformed, it shall be severed from this Public License\n     without affecting the enforceability of the remaining terms and\n     conditions.\n\n  c. No term or condition of this Public License will be waived and no\n     failure to comply consented to unless expressly agreed to by the\n     Licensor.\n\n  d. Nothing in this Public License constitutes or may be interpreted\n     as a limitation upon, or waiver of, any privileges and immunities\n     that apply to the Licensor or You, including from the legal\n     processes of any jurisdiction or authority.\n\n=======================================================================\n\nCreative Commons is not a party to its public\nlicenses. Notwithstanding, Creative Commons may elect to apply one of\nits public licenses to material it publishes and in those instances\nwill be considered the “Licensor.” The text of the Creative Commons\npublic licenses is dedicated to the public domain under the CC0 Public\nDomain Dedication. Except for the limited purpose of indicating that\nmaterial is shared under a Creative Commons public license or as\notherwise permitted by the Creative Commons policies published at\ncreativecommons.org/policies, Creative Commons does not authorize the\nuse of the trademark \"Creative Commons\" or any other trademark or logo\nof Creative Commons without its prior written consent including,\nwithout limitation, in connection with any unauthorized modifications\nto any of its public licenses or any other arrangements,\nunderstandings, or agreements concerning use of licensed material. For\nthe avoidance of doubt, this paragraph does not form part of the\npublic licenses.\n\nCreative Commons may be contacted at creativecommons.org.\n"
  },
  {
    "path": "PULL_REQUEST_TEMPLATE.md",
    "content": "**Yes, I promise I've read the [Contributions Guidelines](https://github.com/getify/You-Dont-Know-JS/blob/master/CONTRIBUTING.md)** (please feel free to remove this line).\n\nSpecifically quoting these guidelines regarding typos:\n\n> Typos?\n>\n> Please don't worry about minor text typos. These will almost certainly be caught during the editing process.\n>\n> If you're going to submit a PR for typo fixes, please be measured in doing so by collecting several small changes into a single PR (in separate commits). Or, **just don't even worry about them for now,** because we'll get to them later. I promise.\n\n----\n\n**Please type \"I already searched for this issue\":**\n\n**Edition:** (pull requests not accepted for previous editions)\n\n**Book Title:**\n\n**Chapter:**\n\n**Section Title:**\n\n**Topic:**\n"
  },
  {
    "path": "README.md",
    "content": "# You Don't Know JS Yet (book series) - 2nd Edition\n\nThis is a series of books diving deep into the core mechanisms of the JavaScript language. This is the **second edition** of the book series:\n\n<a href=\"https://leanpub.com/ydkjsy-get-started\"><img src=\"get-started/images/cover.png\" width=\"75\"></a>&nbsp;&nbsp;\n<a href=\"https://leanpub.com/ydkjsy-scope-closures\"><img src=\"scope-closures/images/cover.png\" width=\"75\"></a>&nbsp;&nbsp;\n<a href=\"https://leanpub.com/ydkjsy-unbooks\"><img src=\"unbooks-cover.png\" width=\"75\"></a>\n\n**To read more about the motivations and perspective behind this book series, check out the [Preface](preface.md).**\n\nIf you're looking for the previous **first edition** books, [they can be found here](https://github.com/getify/You-Dont-Know-JS/blob/1st-ed/README.md).\n\n## Titles\n\nI recommend reading the **second edition** books in this order:\n\n* [Get Started](get-started/README.md) | [Buy on Leanpub](https://leanpub.com/ydkjsy-get-started) | [Buy on Amazon](https://www.amazon.com/dp/B084BNMN7T)\n* [Scope & Closures](scope-closures/README.md) | [Buy on Leanpub](https://leanpub.com/ydkjsy-scope-closures) | [Buy on Amazon](https://www.amazon.com/dp/B08634PZ3N)\n* \"The Unbooks\" (ebook) | [Buy on Leanpub](https://leanpub.com/ydkjsy-unbooks) | [Buy on Amazon](https://www.amazon.com/dp/B0F7H1DN5S)\n    - [Objects & Classes](objects-classes/README.md) (draft stable)\n    - [Types & Grammar](types-grammar/README.md) (rough draft)\n    - ~~Sync & Async (canceled)~~\n    - ~~ES.Next & Beyond (canceled)~~\n\nIf you're looking for the previous **first edition** books, [they can be found here](https://github.com/getify/You-Dont-Know-JS/blob/1st-ed/README.md).\n\n## Publishing\n\nAs always, you'll be able to read these books online here entirely for free.\n\nThis edition of the books is being self-published through [GetiPub](https://geti.pub) publishing. The published books will be made available for sale through normal book retail sources.\n\nIf you'd like to contribute financially towards the effort (or any of my other OSS efforts) aside from purchasing the published books, please consider these options:\n\n* [Github Sponsorship](https://github.com/users/getify/sponsorship)\n* [Patreon](https://www.patreon.com/getify)\n* [Paypal](https://www.paypal.me/getify)\n\n## Contributions\n\nThis book series is now complete, and is **not open to further contributions**.\n\nThank you to those who've been part of the 11 years journey of this book series.\n\n## Thank You To These Wonderful Sponsors\n\n[![Frontend Masters Logo (dark)](https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/external-logos/fem_logo-light.svg)](https://frontendmasters.com#gh-light-mode-only)\n\n[![Frontend Masters Logo (light)](https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/external-logos/fem_logo.svg)](https://frontendmasters.com#gh-dark-mode-only)\n\n**The first two books of the second edition** are exclusively sponsored by **[Frontend Masters](https://frontendmasters.com/?code=simpson)**.\n\nFrontend Masters is the gold standard for top-of-the-line expert training material in frontend-oriented software development. With over 150 courses on all things frontend, this should be your first and only stop for quality video training on HTML, CSS, JS, and related technologies.\n\n**Note:** I teach [all my workshops](https://frontendmasters.com/teachers/kyle-simpson?code=simpson) exclusively through Frontend Masters. If you like this book content, please check out my video training courses.\n\nI want to extend a warm and deep thanks to Marc Grabanski and the entire Frontend Masters team, not only for their excellent work with the video training platform, but for their unwavering support of me and of the \"You Don't Know JS\" books!\n\n----\n\n## License & Copyright\n\nThe materials herein are all &copy; 2019-2025 Kyle Simpson.\n\n<a rel=\"license\" href=\"https://creativecommons.org/licenses/by-nc-nd/4.0/\"><img alt=\"Creative Commons License\" style=\"border-width:0\" src=\"https://i.creativecommons.org/l/by-nc-nd/4.0/88x31.png\" /></a><br />This work is licensed under a <a rel=\"license\" href=\"http://creativecommons.org/licenses/by-nc-nd/4.0/\">Creative Commons Attribution-NonCommercial-NoDerivs 4.0 Unported License</a>.\n"
  },
  {
    "path": "es-next-beyond/README.md",
    "content": "# You Don't Know JS Yet: ES.Next & Beyond - 2nd Edition\n\n| NOTE: |\n| :--- |\n| Work in progress |\n\n[Table of Contents](toc.md)\n\n* [Foreword](foreword.md) (by TBA)\n* [Preface](../preface.md)\n* [Chapter 1: TODO](ch1.md)\n"
  },
  {
    "path": "es-next-beyond/ch1.md",
    "content": "# You Don't Know JS Yet: ES.Next & Beyond - 2nd Edition\n# Chapter 1: TODO\n\n| NOTE: |\n| :--- |\n| Work in progress |\n\n"
  },
  {
    "path": "es-next-beyond/foreword.md",
    "content": "# You Don't Know JS Yet: ES.Next & Beyond - 2nd Edition\n# Foreword\n\n| NOTE: |\n| :--- |\n| Work in progress |\n"
  },
  {
    "path": "es-next-beyond/toc.md",
    "content": "# You Don't Know JS Yet: ES.Next & Beyond - 2nd Edition\n\n| NOTE: |\n| :--- |\n| Work in progress |\n\n## Table of Contents\n\n* Foreword\n* Preface\n* Chapter 1: TODO\n    * TODO\n"
  },
  {
    "path": "get-started/README.md",
    "content": "# You Don't Know JS Yet: Get Started - 2nd Edition\n\n<img src=\"images/cover.png\" width=\"300\">\n\n-----\n\n**[Purchase ebook/PDF from Leanpub](https://leanpub.com/ydkjsy-get-started)**\n\n-----\n\n[Table of Contents](toc.md)\n\n* [Foreword](foreword.md) (by [Brian Holt](https://twitter.com/holtbt))\n* [Preface](../preface.md)\n* [Chapter 1: What Is JavaScript?](ch1.md)\n* [Chapter 2: Surveying JS](ch2.md)\n* [Chapter 3: Digging to the Roots of JS](ch3.md)\n* [Chapter 4: The Bigger Picture](ch4.md)\n* [Appendix A: Exploring Further](apA.md)\n* [Appendix B: Practice, Practice, Practice!](apB.md)\n"
  },
  {
    "path": "get-started/apA.md",
    "content": "# You Don't Know JS Yet: Get Started - 2nd Edition\n# Appendix A: Exploring Further\n\nIn this appendix, we're going to explore some topics from the main chapter text in a bit more detail. Think of this content as an optional preview of some of the more nuanced details covered throughout the rest of the book series.\n\n## Values vs. References\n\nIn Chapter 2, we introduced the two main types of values: primitives and objects. But we didn't discuss yet one key difference between the two: how these values are assigned and passed around.\n\nIn many languages, the developer can choose between assigning/passing a value as the value itself, or as a reference to the value. In JS, however, this decision is entirely determined by the kind of value. That surprises a lot of developers from other languages when they start using JS.\n\nIf you assign/pass a value itself, the value is copied. For example:\n\n```js\nvar myName = \"Kyle\";\n\nvar yourName = myName;\n```\n\nHere, the `yourName` variable has a separate copy of the `\"Kyle\"` string from the value that's stored in `myName`. That's because the value is a primitive, and primitive values are always assigned/passed as **value copies**.\n\nHere's how you can prove there's two separate values involved:\n\n```js\nvar myName = \"Kyle\";\n\nvar yourName = myName;\n\nmyName = \"Frank\";\n\nconsole.log(myName);\n// Frank\n\nconsole.log(yourName);\n// Kyle\n```\n\nSee how `yourName` wasn't affected by the re-assignment of `myName` to `\"Frank\"`? That's because each variable holds its own copy of the value.\n\nBy contrast, references are the idea that two or more variables are pointing at the same value, such that modifying this shared value would be reflected by access via any of those references. In JS, only object values (arrays, objects, functions, etc.) are treated as references.\n\nConsider:\n\n```js\nvar myAddress = {\n    street: \"123 JS Blvd\",\n    city: \"Austin\",\n    state: \"TX\"\n};\n\nvar yourAddress = myAddress;\n\n// I've got to move to a new house!\nmyAddress.street = \"456 TS Ave\";\n\nconsole.log(yourAddress.street);\n// 456 TS Ave\n```\n\nBecause the value assigned to `myAddress` is an object, it's held/assigned by reference, and thus the assignment to the `yourAddress` variable is a copy of the reference, not the object value itself. That's why the updated value assigned to the `myAddress.street` is reflected when we access `yourAddress.street`. `myAddress` and `yourAddress` have copies of the reference to the single shared object, so an update to one is an update to both.\n\nAgain, JS chooses the value-copy vs. reference-copy behavior based on the value type. Primitives are held by value, objects are held by reference. There's no way to override this in JS, in either direction.\n\n## So Many Function Forms\n\nRecall this snippet from the \"Functions\" section in Chapter 2:\n\n```js\nvar awesomeFunction = function(coolThings) {\n    // ..\n    return amazingStuff;\n};\n```\n\nThe function expression here is referred to as an *anonymous function expression*, since it has no name identifier between the `function` keyword and the `(..)` parameter list. This point confuses many JS developers because as of ES6, JS performs a \"name inference\" on an anonymous function:\n\n```js\nawesomeFunction.name;\n// \"awesomeFunction\"\n```\n\nThe `name` property of a function will reveal either its directly given name (in the case of a declaration) or its inferred name in the case of an anonymous function expression. That value is generally used by developer tools when inspecting a function value or when reporting an error stack trace.\n\nSo even an anonymous function expression *might* get a name. However, name inference only happens in limited cases such as when the function expression is assigned (with `=`). If you pass a function expression as an argument to a function call, for example, no name inference occurs; the `name` property will be an empty string, and the developer console will usually report \"(anonymous function)\".\n\nEven if a name is inferred, **it's still an anonymous function.** Why? Because the inferred name is a metadata string value, not an available identifier to refer to the function. An anonymous function doesn't have an identifier to use to refer to itself from inside itself—for recursion, event unbinding, etc.\n\nCompare the anonymous function expression form to:\n\n```js\n// let awesomeFunction = ..\n// const awesomeFunction = ..\nvar awesomeFunction = function someName(coolThings) {\n    // ..\n    return amazingStuff;\n};\n\nawesomeFunction.name;\n// \"someName\"\n```\n\nThis function expression is a *named function expression*, since the identifier `someName` is directly associated with the function expression at compile time; the association with the identifier `awesomeFunction` still doesn't happen until runtime at the time of that statement. Those two identifiers don't have to match; sometimes it makes sense to have them be different, other times it's better to have them be the same.\n\nNotice also that the explicit function name, the identifier `someName`, takes precedence when assigning a *name* for the `name` property.\n\nShould function expressions be named or anonymous? Opinions vary widely on this. Most developers tend to be unconcerned with using anonymous functions. They're shorter, and unquestionably more common in the broad sphere of JS code out there.\n\nIn my opinion, if a function exists in your program, it has a purpose; otherwise, take it out! And if it has a purpose, it has a natural name that describes that purpose.\n\nIf a function has a name, you the code author should include that name in the code, so that the reader does not have to infer that name from reading and mentally executing that function's source code. Even a trivial function body like `x * 2` has to be read to infer a name like \"double\" or \"multBy2\"; that brief extra mental work is unnecessary when you could just take a second to name the function \"double\" or \"multBy2\" *once*, saving the reader that repeated mental work every time it's read in the future.\n\nThere are, regrettably in some respects, many other function definition forms in JS as of early 2020 (maybe more in the future!).\n\nHere are some more declaration forms:\n\n```js\n// generator function declaration\nfunction *two() { .. }\n\n// async function declaration\nasync function three() { .. }\n\n// async generator function declaration\nasync function *four() { .. }\n\n// named function export declaration (ES6 modules)\nexport function five() { .. }\n```\n\nAnd here are some more of the (many!) function expression forms:\n\n```js\n// IIFE\n(function(){ .. })();\n(function namedIIFE(){ .. })();\n\n// asynchronous IIFE\n(async function(){ .. })();\n(async function namedAIIFE(){ .. })();\n\n// arrow function expressions\nvar f;\nf = () => 42;\nf = x => x * 2;\nf = (x) => x * 2;\nf = (x,y) => x * y;\nf = x => ({ x: x * 2 });\nf = x => { return x * 2; };\nf = async x => {\n    var y = await doSomethingAsync(x);\n    return y * 2;\n};\nsomeOperation( x => x * 2 );\n// ..\n```\n\nKeep in mind that arrow function expressions are **syntactically anonymous**, meaning the syntax doesn't provide a way to provide a direct name identifier for the function. The function expression may get an inferred name, but only if it's one of the assignment forms, not in the (more common!) form of being passed as a function call argument (as in the last line of the snippet).\n\nSince I don't think anonymous functions are a good idea to use frequently in your programs, I'm not a fan of using the `=>` arrow function form. This kind of function actually has a specific purpose (i.e., handling the `this` keyword lexically), but that doesn't mean we should use it for every function we write. Use the most appropriate tool for each job.\n\nFunctions can also be specified in class definitions and object literal definitions. They're typically referred to as \"methods\" when in these forms, though in JS this term doesn't have much observable difference over \"function\":\n\n```js\nclass SomethingKindaGreat {\n    // class methods\n    coolMethod() { .. }   // no commas!\n    boringMethod() { .. }\n}\n\nvar EntirelyDifferent = {\n    // object methods\n    coolMethod() { .. },   // commas!\n    boringMethod() { .. },\n\n    // (anonymous) function expression property\n    oldSchool: function() { .. }\n};\n```\n\nPhew! That's a lot of different ways to define functions.\n\nThere's no simple shortcut path here; you just have to build familiarity with all the function forms so you can recognize them in existing code and use them appropriately in the code you write. Study them closely and practice!\n\n## Coercive Conditional Comparison\n\nYes, that section name is quite a mouthful. But what are we talking about? We're talking about conditional expressions needing to perform coercion-oriented comparisons to make their decisions.\n\n`if` and `? :`-ternary statements, as well as the test clauses in `while` and `for` loops, all perform an implicit value comparison. But what sort? Is it \"strict\" or \"coercive\"? Both, actually.\n\nConsider:\n\n```js\nvar x = 1;\n\nif (x) {\n    // will run!\n}\n\nwhile (x) {\n    // will run, once!\n    x = false;\n}\n```\n\nYou might think of these `(x)` conditional expressions like this:\n\n```js\nvar x = 1;\n\nif (x == true) {\n    // will run!\n}\n\nwhile (x == true) {\n    // will run, once!\n    x = false;\n}\n```\n\nIn this specific case -- the value of `x` being `1` -- that mental model works, but it's not accurate more broadly. Consider:\n\n```js\nvar x = \"hello\";\n\nif (x) {\n    // will run!\n}\n\nif (x == true) {\n    // won't run :(\n}\n```\n\nOops. So what is the `if` statement actually doing? This is the more accurate mental model:\n\n```js\nvar x = \"hello\";\n\nif (Boolean(x) == true) {\n    // will run\n}\n\n// which is the same as:\n\nif (Boolean(x) === true) {\n    // will run\n}\n```\n\nSince the `Boolean(..)` function always returns a value of type boolean, the `==` vs `===` in this snippet is irrelevant; they'll both do the same thing. But the important part is to see that before the comparison, a coercion occurs, from whatever type `x` currently is, to boolean.\n\nYou just can't get away from coercions in JS comparisons. Buckle down and learn them.\n\n## Prototypal \"Classes\"\n\nIn Chapter 3, we introduced prototypes and showed how we can link objects through a prototype chain.\n\nAnother way of wiring up such prototype linkages served as the (honestly, ugly) predecessor to the elegance of the ES6 `class` system (see Chapter 2, \"Classes\"), and is referred to as prototypal classes.\n\n| TIP: |\n| :--- |\n| While this style of code is quite uncommon in JS these days, it's still perplexingly rather common to be asked about it in job interviews! |\n\nLet's first recall the `Object.create(..)` style of coding:\n\n```js\nvar Classroom = {\n    welcome() {\n        console.log(\"Welcome, students!\");\n    }\n};\n\nvar mathClass = Object.create(Classroom);\n\nmathClass.welcome();\n// Welcome, students!\n```\n\nHere, a `mathClass` object is linked via its prototype to a `Classroom` object. Through this linkage, the function call `mathClass.welcome()` is delegated to the method defined on `Classroom`.\n\nThe prototypal class pattern would have labeled this delegation behavior \"inheritance,\" and alternatively have defined it (with the same behavior) as:\n\n```js\nfunction Classroom() {\n    // ..\n}\n\nClassroom.prototype.welcome = function hello() {\n    console.log(\"Welcome, students!\");\n};\n\nvar mathClass = new Classroom();\n\nmathClass.welcome();\n// Welcome, students!\n```\n\nAll functions by default reference an empty object at a property named `prototype`. Despite the confusing naming, this is **not** the function's *prototype* (where the function is prototype linked to), but rather the prototype object to *link to* when other objects are created by calling the function with `new`.\n\nWe add a `welcome` property on that empty object (called `Classroom.prototype`), pointing at the `hello()` function.\n\nThen `new Classroom()` creates a new object (assigned to `mathClass`), and prototype links it to the existing `Classroom.prototype` object.\n\nThough `mathClass` does not have a `welcome()` property/function, it successfully delegates to the function `Classroom.prototype.welcome()`.\n\nThis \"prototypal class\" pattern is now strongly discouraged, in favor of using ES6's `class` mechanism:\n\n```js\nclass Classroom {\n    constructor() {\n        // ..\n    }\n\n    welcome() {\n        console.log(\"Welcome, students!\");\n    }\n}\n\nvar mathClass = new Classroom();\n\nmathClass.welcome();\n// Welcome, students!\n```\n\nUnder the covers, the same prototype linkage is wired up, but this `class` syntax fits the class-oriented design pattern much more cleanly than \"prototypal classes\".\n"
  },
  {
    "path": "get-started/apB.md",
    "content": "# You Don't Know JS Yet: Get Started - 2nd Edition\n# Appendix B: Practice, Practice, Practice!\n\nIn this appendix, we'll explore some exercises and their suggested solutions. These are just to *get you started* with practice over the concepts from the book.\n\n## Practicing Comparisons\n\nLet's practice working with value types and comparisons (Chapter 4, Pillar 3) where coercion will need to be involved.\n\n`scheduleMeeting(..)` should take a start time (in 24-hour format as a string \"hh:mm\") and a meeting duration (number of minutes). It should return `true` if the meeting falls entirely within the work day (according to the times specified in `dayStart` and `dayEnd`); return `false` if the meeting violates the work day bounds.\n\n```js\nconst dayStart = \"07:30\";\nconst dayEnd = \"17:45\";\n\nfunction scheduleMeeting(startTime,durationMinutes) {\n    // ..TODO..\n}\n\nscheduleMeeting(\"7:00\",15);     // false\nscheduleMeeting(\"07:15\",30);    // false\nscheduleMeeting(\"7:30\",30);     // true\nscheduleMeeting(\"11:30\",60);    // true\nscheduleMeeting(\"17:00\",45);    // true\nscheduleMeeting(\"17:30\",30);    // false\nscheduleMeeting(\"18:00\",15);    // false\n```\n\nTry to solve this yourself first. Consider the usage of equality and relational comparison operators, and how coercion impacts this code. Once you have code that works, *compare* your solution(s) to the code in \"Suggested Solutions\" at the end of this appendix.\n\n## Practicing Closure\n\nNow let's practice with closure (Chapter 4, Pillar 1).\n\nThe `range(..)` function takes a number as its first argument, representing the first number in a desired range of numbers. The second argument is also a number representing the end of the desired range (inclusive). If the second argument is omitted, then another function should be returned that expects that argument.\n\n```js\nfunction range(start,end) {\n    // ..TODO..\n}\n\nrange(3,3);    // [3]\nrange(3,8);    // [3,4,5,6,7,8]\nrange(3,0);    // []\n\nvar start3 = range(3);\nvar start4 = range(4);\n\nstart3(3);     // [3]\nstart3(8);     // [3,4,5,6,7,8]\nstart3(0);     // []\n\nstart4(6);     // [4,5,6]\n```\n\nTry to solve this yourself first.\n\nOnce you have code that works, *compare* your solution(s) to the code in \"Suggested Solutions\" at the end of this appendix.\n\n## Practicing Prototypes\n\nFinally, let's work on `this` and objects linked via prototype (Chapter 4, Pillar 2).\n\nDefine a slot machine with three reels that can individually `spin()`, and then `display()` the current contents of all the reels.\n\nThe basic behavior of a single reel is defined in the `reel` object below. But the slot machine needs individual reels—objects that delegate to `reel`, and which each have a `position` property.\n\nA reel only *knows how* to `display()` its current slot symbol, but a slot machine typically shows three symbols per reel: the current slot (`position`), one slot above (`position - 1`), and one slot below (`position + 1`). So displaying the slot machine should end up displaying a 3 x 3 grid of slot symbols.\n\n```js\nfunction randMax(max) {\n    return Math.trunc(1E9 * Math.random()) % max;\n}\n\nvar reel = {\n    symbols: [\n        \"♠\", \"♥\", \"♦\", \"♣\", \"☺\", \"★\", \"☾\", \"☀\"\n    ],\n    spin() {\n        if (this.position == null) {\n            this.position = randMax(\n                this.symbols.length - 1\n            );\n        }\n        this.position = (\n            this.position + 100 + randMax(100)\n        ) % this.symbols.length;\n    },\n    display() {\n        if (this.position == null) {\n            this.position = randMax(\n                this.symbols.length - 1\n            );\n        }\n        return this.symbols[this.position];\n    }\n};\n\nvar slotMachine = {\n    reels: [\n        // this slot machine needs 3 separate reels\n        // hint: Object.create(..)\n    ],\n    spin() {\n        this.reels.forEach(function spinReel(reel){\n            reel.spin();\n        });\n    },\n    display() {\n        // TODO\n    }\n};\n\nslotMachine.spin();\nslotMachine.display();\n// ☾ | ☀ | ★\n// ☀ | ♠ | ☾\n// ♠ | ♥ | ☀\n\nslotMachine.spin();\nslotMachine.display();\n// ♦ | ♠ | ♣\n// ♣ | ♥ | ☺\n// ☺ | ♦ | ★\n```\n\nTry to solve this yourself first.\n\nHints:\n\n* Use the `%` modulo operator for wrapping `position` as you access symbols circularly around a reel.\n\n* Use `Object.create(..)` to create an object and prototype-link it to another object. Once linked, delegation allows the objects to share `this` context during method invocation.\n\n* Instead of modifying the reel object directly to show each of the three positions, you can use another temporary object (`Object.create(..)` again) with its own `position`, to delegate from.\n\nOnce you have code that works, *compare* your solution(s) to the code in \"Suggested Solutions\" at the end of this appendix.\n\n## Suggested Solutions\n\nKeep in mind that these suggested solutions are just that: suggestions. There are many different ways to solve these practice exercises. Compare your approach to what you see here, and consider the pros and cons of each.\n\nSuggested solution for \"Comparisons\" (Pillar 3) practice:\n\n```js\nconst dayStart = \"07:30\";\nconst dayEnd = \"17:45\";\n\nfunction scheduleMeeting(startTime,durationMinutes) {\n    var [ , meetingStartHour, meetingStartMinutes ] =\n        startTime.match(/^(\\d{1,2}):(\\d{2})$/) || [];\n\n    durationMinutes = Number(durationMinutes);\n\n    if (\n        typeof meetingStartHour == \"string\" &&\n        typeof meetingStartMinutes == \"string\"\n    ) {\n        let durationHours =\n            Math.floor(durationMinutes / 60);\n        durationMinutes =\n            durationMinutes - (durationHours * 60);\n        let meetingEndHour =\n            Number(meetingStartHour) + durationHours;\n        let meetingEndMinutes =\n            Number(meetingStartMinutes) +\n            durationMinutes;\n\n        if (meetingEndMinutes >= 60) {\n            meetingEndHour = meetingEndHour + 1;\n            meetingEndMinutes =\n                meetingEndMinutes - 60;\n        }\n\n        // re-compose fully-qualified time strings\n        // (to make comparison easier)\n        let meetingStart = `${\n            meetingStartHour.padStart(2,\"0\")\n        }:${\n            meetingStartMinutes.padStart(2,\"0\")\n        }`;\n        let meetingEnd = `${\n            String(meetingEndHour).padStart(2,\"0\")\n        }:${\n            String(meetingEndMinutes).padStart(2,\"0\")\n        }`;\n\n        // NOTE: since expressions are all strings,\n        // comparisons here are alphabetic, but it's\n        // safe here since they're fully qualified\n        // time strings (ie, \"07:15\" < \"07:30\")\n        return (\n            meetingStart >= dayStart &&\n            meetingEnd <= dayEnd\n        );\n    }\n\n    return false;\n}\n\nscheduleMeeting(\"7:00\",15);     // false\nscheduleMeeting(\"07:15\",30);    // false\nscheduleMeeting(\"7:30\",30);     // true\nscheduleMeeting(\"11:30\",60);    // true\nscheduleMeeting(\"17:00\",45);    // true\nscheduleMeeting(\"17:30\",30);    // false\nscheduleMeeting(\"18:00\",15);    // false\n```\n\n----\n\nSuggested solution for \"Closure\" (Pillar 1) practice:\n\n```js\nfunction range(start,end) {\n    start = Number(start) || 0;\n\n    if (end === undefined) {\n        return function getEnd(end) {\n            return getRange(start,end);\n        };\n    }\n    else {\n        end = Number(end) || 0;\n        return getRange(start,end);\n    }\n\n\n    // **********************\n\n    function getRange(start,end) {\n        var ret = [];\n        for (let i = start; i <= end; i++) {\n            ret.push(i);\n        }\n        return ret;\n    }\n}\n\nrange(3,3);    // [3]\nrange(3,8);    // [3,4,5,6,7,8]\nrange(3,0);    // []\n\nvar start3 = range(3);\nvar start4 = range(4);\n\nstart3(3);     // [3]\nstart3(8);     // [3,4,5,6,7,8]\nstart3(0);     // []\n\nstart4(6);     // [4,5,6]\n```\n\n----\n\nSuggested solution for \"Prototypes\" (Pillar 2) practice:\n\n```js\nfunction randMax(max) {\n    return Math.trunc(1E9 * Math.random()) % max;\n}\n\nvar reel = {\n    symbols: [\n        \"♠\", \"♥\", \"♦\", \"♣\", \"☺\", \"★\", \"☾\", \"☀\"\n    ],\n    spin() {\n        if (this.position == null) {\n            this.position = randMax(\n                this.symbols.length - 1\n            );\n        }\n        this.position = (\n            this.position + 100 + randMax(100)\n        ) % this.symbols.length;\n    },\n    display() {\n        if (this.position == null) {\n            this.position = randMax(\n                this.symbols.length - 1\n            );\n        }\n        return this.symbols[this.position];\n    }\n};\n\nvar slotMachine = {\n    reels: [\n        Object.create(reel),\n        Object.create(reel),\n        Object.create(reel)\n    ],\n    spin() {\n        this.reels.forEach(function spinReel(reel){\n            reel.spin();\n        });\n    },\n    display() {\n        var lines = [];\n\n        // display all 3 lines on the slot machine\n        for (\n            let linePos = -1; linePos <= 1; linePos++\n        ) {\n            let line = this.reels.map(\n                function getSlot(reel){\n                    var slot = Object.create(reel);\n                    slot.position = (\n                        reel.symbols.length +\n                        reel.position +\n                        linePos\n                    ) % reel.symbols.length;\n                    return slot.display();\n                }\n            );\n            lines.push(line.join(\" | \"));\n        }\n\n        return lines.join(\"\\n\");\n    }\n};\n\nslotMachine.spin();\nslotMachine.display();\n// ☾ | ☀ | ★\n// ☀ | ♠ | ☾\n// ♠ | ♥ | ☀\n\nslotMachine.spin();\nslotMachine.display();\n// ♦ | ♠ | ♣\n// ♣ | ♥ | ☺\n// ☺ | ♦ | ★\n```\n\nThat's it for this book. But now it's time to look for real projects to practice these ideas on. Just keep coding, because that's the best way to learn!\n"
  },
  {
    "path": "get-started/ch1.md",
    "content": "# You Don't Know JS Yet: Get Started - 2nd Edition\n# Chapter 1: What *Is* JavaScript?\n\nYou don't know JS, yet. Neither do I, not fully anyway. None of us do. But we can all start getting to know JS better.\n\nIn this first chapter of the first book of the *You Don't Know JS Yet* (YDKJSY) series, we will take some time to build a foundation to move forward on. We need to start by covering a variety of important background housekeeping details, clearing up some myths and misconceptions about what the language really is (and isn't!).\n\nThis is valuable insight into the identity and process of how JS is organized and maintained; all JS developers should understand it. If you want to get to know JS, this is how to *get started* taking the first steps in that journey.\n\n## About This Book\n\nI emphasize the word journey because *knowing JS* is not a destination, it's a direction. No matter how much time you spend with the language, you will always be able to find something else to learn and understand a little better. So don't look at this book as something to rush through for a quick achievement. Instead, patience and persistence are best as you take these first few steps.\n\nFollowing this background chapter, the rest of the book lays out a high-level map of what you will find as you dig into and study JS with the YDKJSY books.\n\nIn particular, Chapter 4 identifies three main pillars around which the JS language is organized: scope/closures, prototypes/objects, and types/coercion. JS is a broad and sophisticated language, with many features and capabilities. But all of JS is founded on these three foundational pillars.\n\nKeep in mind that even though this book is titled \"Get Started,\" it's **not intended as a beginner/intro book**. This book's main job is to get you ready for studying JS deeply throughout the rest of the series; it's written assuming you already have familiarity with JS over at least several months experience before moving on in YDKJSY. So to get the most out of *Get Started*, make sure you spend plenty of time writing JS code to build up your experience.\n\nEven if you've already written a lot of JS before, this book should not be skimmed over or skipped; take your time to fully process the material here. **A good start always depends on a solid first step.**\n\n## What's With That Name?\n\nThe name JavaScript is probably the most mistaken and misunderstood programming language name.\n\nIs this language related to Java? Is it only the script form for Java? Is it only for writing scripts and not real programs?\n\nThe truth is, the name JavaScript is an artifact of marketing shenanigans. When Brendan Eich first conceived of the language, he code-named it Mocha. Internally at Netscape, the brand LiveScript was used. But when it came time to publicly name the language, \"JavaScript\" won the vote.\n\nWhy? Because this language was originally designed to appeal to an audience of mostly Java programmers, and because the word \"script\" was popular at the time to refer to lightweight programs. These lightweight \"scripts\" would be the first ones to embed inside of pages on this new thing called the web!\n\nIn other words, JavaScript was a marketing ploy to try to position this language as a palatable alternative to writing the heavier and more well-known Java of the day. It could just as easily have been called \"WebJava,\" for that matter.\n\nThere are some superficial resemblances between JavaScript's code and Java code. Those similarities don't particularly come from shared development, but from both languages targeting developers with assumed syntax expectations from C (and to an extent, C++).\n\nFor example, we use the `{` to begin a block of code and the `}` to end that block of code, just like C/C++ and Java. We also use the `;` to punctuate the end of a statement.\n\nIn some ways, legal relationships run even deeper than the syntax. Oracle (via Sun), the company that still owns and runs Java, also owns the official trademark for the name \"JavaScript\" (via Netscape). This trademark is almost never enforced, and likely couldn't be at this point.\n\nFor these reasons, some have suggested we use JS instead of JavaScript. That is a very common shorthand, if not a good candidate for an official language branding itself. Indeed, these books use JS almost exclusively to refer to the language.\n\nFurther distancing the language from the Oracle-owned trademark, the official name of the language specified by TC39 and formalized by the ECMA standards body is **ECMAScript**. And indeed, since 2016, the official language name has also been suffixed by the revision year; as of this writing, that's ECMAScript 2019, or otherwise abbreviated ES2019.\n\nIn other words, the JavaScript/JS that runs in your browser or in Node.js, is *an* implementation of the ES2019 standard.\n\n| NOTE: |\n| :--- |\n| Don't use terms like \"JS6\" or \"ES8\" to refer to the language. Some do, but those terms only serve to perpetuate confusion. \"ES20xx\" or just \"JS\" are what you should stick to. |\n\nWhether you call it JavaScript, JS, ECMAScript, or ES2019, it's most definitely not a variant of the Java language!\n\n> \"Java is to JavaScript as ham is to hamster.\" --Jeremy Keith, 2009\n\n## Language Specification\n\nI mentioned TC39, the technical steering committee that manages JS. Their primary task is managing the official specification for the language. They meet regularly to vote on any agreed changes, which they then submit to ECMA, the standards organization.\n\nJS's syntax and behavior are defined in the ES specification.\n\nES2019 happens to be the 10th major numbered specification/revision since JS's inception in 1995, so in the specification's official URL as hosted by ECMA, you'll find \"10.0\":\n\nhttps://www.ecma-international.org/ecma-262/10.0/\n\nThe TC39 committee is comprised of between 50 and about 100 different people from a broad section of web-invested companies, such as browser makers (Mozilla, Google, Apple) and device makers (Samsung, etc). All members of the committee are volunteers, though many of them are employees of these companies and so may receive compensation in part for their duties on the committee.\n\nTC39 meets generally about every other month, usually for about three days, to review work done by members since the last meeting, discuss issues, and vote on proposals. Meeting locations rotate among member companies willing to host.\n\nAll TC39 proposals progress through a five-stage process—of course, since we're programmers, it's 0-based!—Stage 0 through Stage 4. You can read more about the Stage process here: https://tc39.es/process-document/\n\nStage 0 means roughly, someone on TC39 thinks it's a worthy idea and plans to champion and work on it. That means lots of ideas that non-TC39 members \"propose,\" through informal means such as social media or blog posts, are really \"pre-stage 0.\" You have to get a TC39 member to champion a proposal for it to be considered \"Stage 0\" officially.\n\nOnce a proposal reaches \"Stage 4\" status, it is eligible to be included in the next yearly revision of the language. It can take anywhere from several months to a few years for a proposal to work its way through these stages.\n\nAll proposals are managed in the open, on TC39's Github repository: https://github.com/tc39/proposals\n\nAnyone, whether on TC39 or not, is welcome to participate in these public discussions and the processes for working on the proposals. However, only TC39 members can attend meetings and vote on the proposals and changes. So in effect, the voice of a TC39 member carries a lot of weight in where JS will go.\n\nContrary to some established and frustratingly perpetuated myth, there are *not* multiple versions of JavaScript in the wild. There's just **one JS**, the official standard as maintained by TC39 and ECMA.\n\nBack in the early 2000s, when Microsoft maintained a forked and reverse-engineered (and not entirely compatible) version of JS called \"JScript,\" there were legitimately \"multiple versions\" of JS. But those days are long gone. It's outdated and inaccurate to make such claims about JS today.\n\nAll major browsers and device makers have committed to keeping their JS implementations compliant with this one central specification. Of course, engines implement features at different times. But it should never be the case that the v8 engine (Chrome's JS engine) implements a specified feature differently or incompatibly as compared to the SpiderMonkey engine (Mozilla's JS engine).\n\nThat means you can learn **one JS**, and rely on that same JS everywhere.\n\n### The Web Rules Everything About (JS)\n\nWhile the array of environments that run JS is constantly expanding (from browsers, to servers (Node.js), to robots, to lightbulbs, to...), the one environment that rules JS is the web. In other words, how JS is implemented for web browsers is, in all practicality, the only reality that matters.\n\nFor the most part, the JS defined in the specification and the JS that runs in browser-based JS engines is the same. But there are some differences that must be considered.\n\nSometimes the JS specification will dictate some new or refined behavior, and yet that won't exactly match with how it works in browser-based JS engines. Such a mismatch is historical: JS engines have had 20+ years of observable behaviors around corner cases of features that have come to be relied on by web content. As such, sometimes the JS engines will refuse to conform to a specification-dictated change because it would break that web content.\n\nIn these cases, often TC39 will backtrack and simply choose to conform the specification to the reality of the web. For example, TC39 planned to add a `contains(..)` method for Arrays, but it was found that this name conflicted with old JS frameworks still in use on some sites, so they changed the name to a non-conflicting `includes(..)`. The same happened with a comedic/tragic JS *community crisis* dubbed \"smooshgate,\" where the planned `flatten(..)` method was eventually renamed `flat(..)`.\n\nBut occasionally, TC39 will decide the specification should stick firm on some point even though it is unlikely that browser-based JS engines will ever conform.\n\nThe solution? Appendix B, \"Additional ECMAScript Features for Web Browsers\".[^specApB] The JS specification includes this appendix to detail out any known mismatches between the official JS specification and the reality of JS on the web. In other words, these are exceptions that are allowed *only* for web JS; other JS environments must stick to the letter of the law.\n\nSection B.1 and B.2 cover *additions* to JS (syntax and APIs) that web JS includes, again for historical reasons, but which TC39 does not plan to formally specify in the core of JS. Examples include `0`-prefixed octal literals, the global `escape(..)` / `unescape(..)` utilities, String \"helpers\" like `anchor(..)` and `blink()`, and the RegExp `compile(..)` method.\n\nSection B.3 includes some conflicts where code may run in both web and non-web JS engines, but where the behavior *could* be observably different, resulting in different outcomes. Most of the listed changes involve situations that are labeled as early errors when code is running in strict mode.\n\nAppendix B *gotchas* aren't encountered very often, but it's still a good idea to avoid these constructs to be future safe. Wherever possible, adhere to the JS specification and don't rely on behavior that's only applicable in certain JS engine environments.\n\n### Not All (Web) JS...\n\nIs this code a JS program?\n\n```js\nalert(\"Hello, JS!\");\n```\n\nDepends on how you look at things. The `alert(..)` function shown here is not included in the JS specification, but it *is* in all web JS environments. Yet, you won't find it in Appendix B, so what gives?\n\nVarious JS environments (like browser JS engines, Node.js, etc.) add APIs into the global scope of your JS programs that give you environment-specific capabilities, like being able to pop an alert-style box in the user's browser.\n\nIn fact, a wide range of JS-looking APIs, like `fetch(..)`, `getCurrentLocation(..)`, and `getUserMedia(..)`, are all web APIs that look like JS. In Node.js, we can access hundreds of API methods from various built-in modules, like `fs.write(..)`.\n\nAnother common example is `console.log(..)` (and all the other `console.*` methods!). These are not specified in JS, but because of their universal utility are defined by pretty much every JS environment, according to a roughly agreed consensus.\n\nSo `alert(..)` and `console.log(..)` are not defined by JS. But they *look* like JS. They are functions and object methods and they obey JS syntax rules. The behaviors behind them are controlled by the environment running the JS engine, but on the surface they definitely have to abide by JS to be able to play in the JS playground.\n\nMost of the cross-browser differences people complain about with \"JS is so inconsistent!\" claims are actually due to differences in how those environment behaviors work, not in how the JS itself works.\n\nSo an `alert(..)` call *is* JS, but `alert` itself is really just a guest, not part of the official JS specification.\n\n### It's Not Always JS\n\nUsing the console/REPL (Read-Evaluate-Print-Loop) in your browser's Developer Tools (or Node) feels like a pretty straightforward JS environment at first glance. But it's not, really.\n\nDeveloper Tools are... tools for developers. Their primary purpose is to make life easier for developers. They prioritize DX (Developer Experience). It is *not* a goal of such tools to accurately and purely reflect all nuances of strict-spec JS behavior. As such, there's many quirks that may act as \"gotchas\" if you're treating the console as a *pure* JS environment.\n\nThis convenience is a good thing, by the way! I'm glad Developer Tools make developers' lives easier! I'm glad we have nice UX charms like auto-complete of variables/properties, etc. I'm just pointing out that we can't and shouldn't expect such tools to *always* adhere strictly to the way JS programs are handled, because that's not the purpose of these tools.\n\nSince such tools vary in behavior from browser to browser, and since they change (sometimes rather frequently), I'm not going to \"hardcode\" any of the specific details into this text, thereby ensuring this book text is outdated quickly.\n\nBut I'll just hint at some examples of quirks that have been true at various points in different JS console environments, to reinforce my point about not assuming native JS behavior while using them:\n\n* Whether a `var` or `function` declaration in the top-level \"global scope\" of the console actually creates a real global variable (and mirrored `window` property, and vice versa!).\n\n* What happens with multiple `let` and `const` declarations in the top-level \"global scope.\"\n\n* Whether `\"use strict\";` on one line-entry (pressing `<enter>` after) enables strict mode for the rest of that console session, the way it would on the first line of a .js file, as well as whether you can use `\"use strict\";` beyond the \"first line\" and still get strict mode turned on for that session.\n\n* How non-strict mode `this` default-binding works for function calls, and whether the \"global object\" used will contain expected global variables.\n\n* How hoisting (see Book 2, *Scope & Closures*) works across multiple line entries.\n\n* ...several others\n\nThe developer console is not trying to pretend to be a JS compiler that handles your entered code exactly the same way the JS engine handles a .js file. It's trying to make it easy for you to quickly enter a few lines of code and see the results immediately. These are entirely different use cases, and as such, it's unreasonable to expect one tool to handle both equally.\n\nDon't trust what behavior you see in a developer console as representing *exact* to-the-letter JS semantics; for that, read the specification. Instead, think of the console as a \"JS-friendly\" environment. That's useful in its own right.\n\n## Many Faces\n\nThe term \"paradigm\" in programming language context refers to a broad (almost universal) mindset and approach to structuring code. Within a paradigm, there are myriad variations of style and form that distinguish programs, including countless different libraries and frameworks that leave their unique signature on any given code.\n\nBut no matter what a program's individual style may be, the big picture divisions around paradigms are almost always evident at first glance of any program.\n\nTypical paradigm-level code categories include procedural, object-oriented (OO/classes), and functional (FP):\n\n* Procedural style organizes code in a top-down, linear progression through a pre-determined set of operations, usually collected together in related units called procedures.\n\n* OO style organizes code by collecting logic and data together into units called classes.\n\n* FP style organizes code into functions (pure computations as opposed to procedures), and the adaptations of those functions as values.\n\nParadigms are neither right nor wrong. They're orientations that guide and mold how programmers approach problems and solutions, how they structure and maintain their code.\n\nSome languages are heavily slanted toward one paradigm—C is procedural, Java/C++ are almost entirely class oriented, and Haskell is FP through and through.\n\nBut many languages also support code patterns that can come from, and even mix and match from, different paradigms. So called \"multi-paradigm languages\" offer ultimate flexibility. In some cases, a single program can even have two or more expressions of these paradigms sitting side by side.\n\nJavaScript is most definitely a multi-paradigm language. You can write procedural, class-oriented, or FP-style code, and you can make those decisions on a line-by-line basis instead of being forced into an all-or-nothing choice.\n\n## Backwards & Forwards\n\nOne of the most foundational principles that guides JavaScript is preservation of *backwards compatibility*. Many are confused by the implications of this term, and often confuse it with a related but different term: *forwards compatibility*.\n\nLet's set the record straight.\n\nBackwards compatibility means that once something is accepted as valid JS, there will not be a future change to the language that causes that code to become invalid JS. Code written in 1995—however primitive or limited it may have been!—should still work today. As TC39 members often proclaim, \"we don't break the web!\"\n\nThe idea is that JS developers can write code with confidence that their code won't stop working unpredictably because a browser update is released. This makes the decision to choose JS for a program a more wise and safe investment, for years into the future.\n\nThat \"guarantee\" is no small thing. Maintaining backwards compatibility, stretched out across almost 25 years of the language's history, creates an enormous burden and a whole slew of unique challenges. You'd be hard pressed to find many other examples in computing of such a commitment to backwards compatibility.\n\nThe costs of sticking to this principle should not be casually dismissed. It necessarily creates a very high bar to including changing or extending the language; any decision becomes effectively permanent, mistakes and all. Once it's in JS, it can't be taken out because it might break programs, even if we'd really, really like to remove it!\n\nThere are some small exceptions to this rule. JS has had some backwards-incompatible changes, but TC39 is extremely cautious in doing so. They study existing code on the web (via browser data gathering) to estimate the impact of such breakage, and browsers ultimately decide and vote on whether they're willing to take the heat from users for a very small-scale breakage weighed against the benefits of fixing or improving some aspect of the language for many more sites (and users).\n\nThese kinds of changes are rare, and are almost always in corner cases of usage that are unlikely to be observably breaking in many sites.\n\nCompare *backwards compatibility* to its counterpart, *forwards compatibility*. Being forwards-compatible means that including a new addition to the language in a program would not cause that program to break if it were run in an older JS engine. **JS is not forwards-compatible**, despite many wishing such, and even incorrectly believing the myth that it is.\n\nHTML and CSS, by contrast, are forwards-compatible but not backwards-compatible. If you dug up some HTML or CSS written back in 1995, it's entirely possible it would not work (or work the same) today. But, if you use a new feature from 2019 in a browser from 2010, the page isn't \"broken\" -- the unrecognized CSS/HTML is skipped over, while the rest of the CSS/HTML would be processed accordingly.\n\nIt may seem desirable for forwards-compatibility to be included in programming language design, but it's generally impractical to do so. Markup (HTML) or styling (CSS) are declarative in nature, so it's much easier to \"skip over\" unrecognized declarations with minimal impact to other recognized declarations.\n\nBut chaos and non-determinism would ensue if a programming language engine selectively skipped statements (or even expressions!) that it didn't understand, as it's impossible to ensure that a subsequent part of the program wasn't expecting the skipped-over part to have been processed.\n\nThough JS isn't, and can't be, forwards-compatible, it's critical to recognize JS's backwards compatibility, including the enduring benefits to the web and the constraints and difficulties it places on JS as a result.\n\n### Jumping the Gaps\n\nSince JS is not forwards-compatible, it means that there is always the potential for a gap between code that you can write that's valid JS, and the oldest engine that your site or application needs to support. If you run a program that uses an ES2019 feature in an engine from 2016, you're very likely to see the program break and crash.\n\nIf the feature is a new syntax, the program will in general completely fail to compile and run, usually throwing a syntax error. If the feature is an API (such as ES6's `Object.is(..)`), the program may run up to a point but then throw a runtime exception and stop once it encounters the reference to the unknown API.\n\nDoes this mean JS developers should always lag behind the pace of progress, using only code that is on the trailing edge of the oldest JS engine environments they need to support? No!\n\nBut it does mean that JS developers need to take special care to address this gap.\n\nFor new and incompatible syntax, the solution is transpiling. Transpiling is a contrived and community-invented term to describe using a tool to convert the source code of a program from one form to another (but still as textual source code). Typically, forwards-compatibility problems related to syntax are solved by using a transpiler (the most common one being Babel (https://babeljs.io)) to convert from that newer JS syntax version to an equivalent older syntax.\n\nFor example, a developer may write a snippet of code like:\n\n```js\nif (something) {\n    let x = 3;\n    console.log(x);\n}\nelse {\n    let x = 4;\n    console.log(x);\n}\n```\n\nThis is how the code would look in the source code tree for that application. But when producing the file(s) to deploy to the public website, the Babel transpiler might convert that code to look like this:\n\n```js\nvar x$0, x$1;\nif (something) {\n    x$0 = 3;\n    console.log(x$0);\n}\nelse {\n    x$1 = 4;\n    console.log(x$1);\n}\n```\n\nThe original snippet relied on `let` to create block-scoped `x` variables in both the `if` and `else` clauses which did not interfere with each other. An equivalent program (with minimal re-working) that Babel can produce just chooses to name two different variables with unique names, producing the same non-interference outcome.\n\n| NOTE: |\n| :--- |\n| The `let` keyword was added in ES6 (in 2015). The preceding example of transpiling would only need to apply if an application needed to run in a pre-ES6 supporting JS environment. The example here is just for simplicity of illustration. When ES6 was new, the need for such a transpilation was quite prevalent, but in 2020 it's much less common to need to support pre-ES6 environments. The \"target\" used for transpilation is thus a sliding window that shifts upward only as decisions are made for a site/application to stop supporting some old browser/engine. |\n\nYou may wonder: why go to the trouble of using a tool to convert from a newer syntax version to an older one? Couldn't we just write the two variables and skip using the `let` keyword? The reason is, it's strongly recommended that developers use the latest version of JS so that their code is clean and communicates its ideas most effectively.\n\nDevelopers should focus on writing the clean, new syntax forms, and let the tools take care of producing a forwards-compatible version of that code that is suitable to deploy and run on the oldest-supported JS engine environments.\n\n### Filling the Gaps\n\nIf the forwards-compatibility issue is not related to new syntax, but rather to a missing API method that was only recently added, the most common solution is to provide a definition for that missing API method that stands in and acts as if the older environment had already had it natively defined. This pattern is called a polyfill (aka \"shim\").\n\nConsider this code:\n\n```js\n// getSomeRecords() returns us a promise for some\n// data it will fetch\nvar pr = getSomeRecords();\n\n// show the UI spinner while we get the data\nstartSpinner();\n\npr\n.then(renderRecords)   // render if successful\n.catch(showError)      // show an error if not\n.finally(hideSpinner)  // always hide the spinner\n```\n\nThis code uses an ES2019 feature, the `finally(..)` method on the promise prototype. If this code were used in a pre-ES2019 environment, the `finally(..)` method would not exist, and an error would occur.\n\nA polyfill for `finally(..)` in pre-ES2019 environments could look like this:\n\n```js\nif (!Promise.prototype.finally) {\n    Promise.prototype.finally = function f(fn){\n        return this.then(\n            function t(v){\n                return Promise.resolve( fn() )\n                    .then(function t(){\n                        return v;\n                    });\n            },\n            function c(e){\n                return Promise.resolve( fn() )\n                    .then(function t(){\n                        throw e;\n                    });\n            }\n        );\n    };\n}\n```\n\n| WARNING: |\n| :--- |\n| This is only a simple illustration of a basic (not entirely spec-compliant) polyfill for `finally(..)`. Don't use this polyfill in your code; always use a robust, official polyfill wherever possible, such as the collection of polyfills/shims in ES-Shim. |\n\nThe `if` statement protects the polyfill definition by preventing it from running in any environment where the JS engine has already defined that method. In older environments, the polyfill is defined, but in newer environments the `if` statement is quietly skipped.\n\nTranspilers like Babel typically detect which polyfills your code needs and provide them automatically for you. But occasionally you may need to include/define them explicitly, which works similar to the snippet we just looked at.\n\nAlways write code using the most appropriate features to communicate its ideas and intent effectively. In general, this means using the most recent stable JS version. Avoid negatively impacting the code's readability by trying to manually adjust for the syntax/API gaps. That's what tools are for!\n\nTranspilation and polyfilling are two highly effective techniques for addressing that gap between code that uses the latest stable features in the language and the old environments a site or application needs to still support. Since JS isn't going to stop improving, the gap will never go away. Both techniques should be embraced as a standard part of every JS project's production chain going forward.\n\n## What's in an Interpretation?\n\nA long-debated question for code written in JS: is it an interpreted script or a compiled program? The majority opinion seems to be that JS is an interpreted (scripting) language. But the truth is more complicated than that.\n\nFor much of the history of programming languages, \"interpreted\" languages and \"scripting\" languages have been looked down on as inferior compared to their compiled counterparts. The reasons for this acrimony are numerous, including the perception that there is a lack of performance optimization, as well as dislike of certain language characteristics, such as scripting languages generally using dynamic typing instead of the \"more mature\" statically typed languages.\n\nLanguages regarded as \"compiled\" usually produce a portable (binary) representation of the program that is distributed for execution later. Since we don't really observe that kind of model with JS (we distribute the source code, not the binary form), many claim that disqualifies JS from the category. In reality, the distribution model for a program's \"executable\" form has become drastically more varied and also less relevant over the last few decades; to the question at hand, it doesn't really matter so much anymore what form of a program gets passed around.\n\nThese misinformed claims and criticisms should be set aside. The real reason it matters to have a clear picture on whether JS is interpreted or compiled relates to the nature of how errors are handled.\n\nHistorically, scripted or interpreted languages were executed in generally a top-down and line-by-line fashion; there's typically not an initial pass through the program to process it before execution begins (see Figure 1).\n\n<figure>\n    <img src=\"images/fig1.png\" width=\"650\" alt=\"Interpreting a script to execute it\" align=\"center\">\n    <figcaption><em>Fig. 1: Interpreted/Scripted Execution</em></figcaption>\n    <br><br>\n</figure>\n\nIn scripted or interpreted languages, an error on line 5 of a program won't be discovered until lines 1 through 4 have already executed. Notably, the error on line 5 might be due to a runtime condition, such as some variable or value having an unsuitable value for an operation, or it may be due to a malformed statement/command on that line. Depending on context, deferring error handling to the line the error occurs on may be a desirable or undesirable effect.\n\nCompare that to languages which do go through a processing step (typically, called parsing) before any execution occurs, as illustrated in Figure 2:\n\n<figure>\n    <img src=\"images/fig2.png\" width=\"650\" alt=\"Parsing, compiling, and executing a program\" align=\"center\">\n    <figcaption><em>Fig. 2: Parsing + Compilation + Execution</em></figcaption>\n    <br><br>\n</figure>\n\nIn this processing model, an invalid command (such as broken syntax) on line 5 would be caught during the parsing phase, before any execution has begun, and none of the program would run. For catching syntax (or otherwise \"static\") errors, generally it's preferred to know about them ahead of any doomed partial execution.\n\nSo what do \"parsed\" languages have in common with \"compiled\" languages? First, all compiled languages are parsed. So a parsed language is quite a ways down the road toward being compiled already. In classic compilation theory, the last remaining step after parsing is code generation: producing an executable form.\n\nOnce any source program has been fully parsed, it's very common that its subsequent execution will, in some form or fashion, include a translation from the parsed form of the program—usually called an Abstract Syntax Tree (AST)—to that executable form.\n\nIn other words, parsed languages usually also perform code generation before execution, so it's not that much of a stretch to say that, in spirit, they're compiled languages.\n\nJS source code is parsed before it is executed. The specification requires as much, because it calls for \"early errors\"—statically determined errors in code, such as a duplicate parameter name—to be reported before the code starts executing. Those errors cannot be recognized without the code having been parsed.\n\nSo **JS is a parsed language**, but is it *compiled*?\n\nThe answer is closer to yes than no. The parsed JS is converted to an optimized (binary) form, and that \"code\" is subsequently executed (Figure 2); the engine does not commonly switch back into line-by-line execution (like Figure 1) mode after it has finished all the hard work of parsing—most languages/engines wouldn't, because that would be highly inefficient.\n\nTo be specific, this \"compilation\" produces a binary byte code (of sorts), which is then handed to the \"JS virtual machine\" to execute. Some like to say this VM is \"interpreting\" the byte code. But then that means Java, and a dozen other JVM-driven languages, for that matter, are interpreted rather than compiled. Of course, that contradicts the typical assertion that Java/etc are compiled languages.\n\nInterestingly, while Java and JavaScript are very different languages, the question of interpreted/compiled is pretty closely related between them!\n\nAnother wrinkle is that JS engines can employ multiple passes of JIT (Just-In-Time) processing/optimization on the generated code (post parsing), which again could reasonably be labeled either \"compilation\" or \"interpretation\" depending on perspective. It's actually a fantastically complex situation under the hood of a JS engine.\n\nSo what do these nitty-gritty details boil down to? Step back and consider the entire flow of a JS source program:\n\n1. After a program leaves a developer's editor, it gets transpiled by Babel, then packed by Webpack (and perhaps half a dozen other build processes), then it gets delivered in that very different form to a JS engine.\n\n2. The JS engine parses the code to an AST.\n\n3. Then the engine converts that AST to a kind-of byte code, a binary intermediate representation (IR), which is then refined/converted even further by the optimizing JIT compiler.\n\n4. Finally, the JS VM executes the program.\n\nTo visualize those steps, again:\n\n<figure>\n    <img src=\"images/fig3.png\" width=\"650\" alt=\"Steps of JS compilation and execution\" align=\"center\">\n    <figcaption><em>Fig. 3: Parsing, Compiling, and Executing JS</em></figcaption>\n    <br><br>\n</figure>\n\nIs JS handled more like an interpreted, line-by-line script, as in Figure 1, or is it handled more like a compiled language that's processed in one-to-several passes first, before execution (as in Figures 2 and 3)?\n\nI think it's clear that in spirit, if not in practice, **JS is a compiled language**.\n\nAnd again, the reason that matters is, since JS is compiled, we are informed of static errors (such as malformed syntax) before our code is executed. That is a substantively different interaction model than we get with traditional \"scripting\" programs, and arguably more helpful!\n\n### Web Assembly (WASM)\n\nOne dominating concern that has driven a significant amount of JS's evolution is performance, both how quickly JS can be parsed/compiled and how quickly that compiled code can be executed.\n\nIn 2013, engineers from Mozilla Firefox demonstrated a port of the Unreal 3 game engine from C to JS. The ability for this code to run in a browser JS engine at full 60fps performance was predicated on a set of optimizations that the JS engine could perform specifically because the JS version of the Unreal engine's code used a style of code that favored a subset of the JS language, named \"ASM.js\".\n\nThis subset is valid JS written in ways that are somewhat uncommon in normal coding, but which signal certain important typing information to the engine that allow it to make key optimizations. ASM.js was introduced as one way of addressing the pressures on the runtime performance of JS.\n\nBut it's important to note that ASM.js was never intended to be code that was authored by developers, but rather a representation of a program having been transpiled from another language (such as C), where these typing \"annotations\" were inserted automatically by the tooling.\n\nSeveral years after ASM.js demonstrated the validity of tooling-created versions of programs that can be processed more efficiently by the JS engine, another group of engineers (also, initially, from Mozilla) released Web Assembly (WASM).\n\nWASM is similar to ASM.js in that its original intent was to provide a path for non-JS programs (C, etc.) to be converted to a form that could run in the JS engine. Unlike ASM.js, WASM chose to additionally get around some of the inherent delays in JS parsing/compilation before a program can execute, by representing the program in a form that is entirely unlike JS.\n\nWASM is a representation format more akin to Assembly (hence, its name) that can be processed by a JS engine by skipping the parsing/compilation that the JS engine normally does. The parsing/compilation of a WASM-targeted program happen ahead of time (AOT); what's distributed is a binary-packed program ready for the JS engine to execute with very minimal processing.\n\nAn initial motivation for WASM was clearly the potential performance improvements. While that continues to be a focus, WASM is additionally motivated by the desire to bring more parity for non-JS languages to the web platform. For example, if a language like Go supports threaded programming, but JS (the language) does not, WASM offers the potential for such a Go program to be converted to a form the JS engine can understand, without needing a threads feature in the JS language itself.\n\nIn other words, WASM relieves the pressure to add features to JS that are mostly/exclusively intended to be used by transpiled programs from other languages. That means JS feature development can be judged (by TC39) without being skewed by interests/demands in other language ecosystems, while still letting those languages have a viable path onto the web.\n\nAnother perspective on WASM that's emerging is, interestingly, not even directly related to the web (W). WASM is evolving to become a cross-platform virtual machine (VM) of sorts, where programs can be compiled once and run in a variety of different system environments.\n\nSo, WASM isn't only for the web, and WASM also isn't JS. Ironically, even though WASM runs in the JS engine, the JS language is one of the least suitable languages to source WASM programs with, because WASM relies heavily on static typing information. Even TypeScript (TS)—ostensibly, JS + static types—is not quite suitable (as it stands) to transpile to WASM, though language variants like AssemblyScript are attempting to bridge the gap between JS/TS and WASM.\n\nThis book isn't about WASM, so I won't spend much more time discussing it, except to make one final point. *Some* folks have suggested WASM points to a future where JS is excised from, or minimized in, the web. These folks often harbor ill feelings about JS, and want some other language—any other language!—to replace it. Since WASM lets other languages run in the JS engine, on its face this isn't an entirely fanciful fairytale.\n\nBut let me just state simply: WASM will not replace JS. WASM significantly augments what the web (including JS) can accomplish. That's a great thing, entirely orthogonal to whether some people will use it as an escape hatch from having to write JS.\n\n## *Strict*ly Speaking\n\nBack in 2009 with the release of ES5, JS added *strict mode* as an opt-in mechanism for encouraging better JS programs.\n\nThe benefits of strict mode far outweigh the costs, but old habits die hard and the inertia of existing (aka \"legacy\") code bases is really hard to shift. So sadly, more than 10 years later, strict mode's *optionality* means that it's still not necessarily the default for JS programmers.\n\nWhy strict mode? Strict mode shouldn't be thought of as a restriction on what you can't do, but rather as a guide to the best way to do things so that the JS engine has the best chance of optimizing and efficiently running the code. Most JS code is worked on by teams of developers, so the *strict*-ness of strict mode (along with tooling like linters!) often helps collaboration on code by avoiding some of the more problematic mistakes that slip by in non-strict mode.\n\nMost strict mode controls are in the form of *early errors*, meaning errors that aren't strictly syntax errors but are still thrown at compile time (before the code is run). For example, strict mode disallows naming two function parameters the same, and results in an early error. Some other strict mode controls are only observable at runtime, such as how `this` defaults to `undefined` instead of the global object.\n\nRather than fighting and arguing with strict mode, like a kid who just wants to defy whatever their parents tell them not to do, the best mindset is that strict mode is like a linter reminding you how JS *should* be written to have the highest quality and best chance at performance. If you find yourself feeling handcuffed, trying to work around strict mode, that should be a blaring red warning flag that you need to back up and rethink the whole approach.\n\nStrict mode is switched on per file with a special pragma (nothing allowed before it except comments/whitespace):\n\n```js\n// only whitespace and comments are allowed\n// before the use-strict pragma\n\"use strict\";\n// the rest of the file runs in strict mode\n```\n\n| WARNING: |\n| :--- |\n| Something to be aware of is that even a stray `;` all by itself appearing before the strict mode pragma will render the pragma useless; no errors are thrown because it's valid JS to have a string literal expression in a statement position, but it also will silently *not* turn on strict mode! |\n\nStrict mode can alternatively be turned on per-function scope, with exactly the same rules about its surroundings:\n\n```js\nfunction someOperations() {\n    // whitespace and comments are fine here\n    \"use strict\";\n\n    // all this code will run in strict mode\n}\n```\n\nInterestingly, if a file has strict mode turned on, the function-level strict mode pragmas are disallowed. So you have to pick one or the other.\n\nThe **only** valid reason to use a per-function approach to strict mode is when you are converting an existing non-strict mode program file and need to make the changes little by little over time. Otherwise, it's vastly better to simply turn strict mode on for the entire file/program.\n\nMany have wondered if there would ever be a time when JS made strict mode the default? The answer is, almost certainly not. As we discussed earlier around backwards compatibility, if a JS engine update started assuming code was strict mode even if it's not marked as such, it's possible that this code would break as a result of strict mode's controls.\n\nHowever, there are a few factors that reduce the future impact of this non-default \"obscurity\" of strict mode.\n\nFor one, virtually all transpiled code ends up in strict mode even if the original source code isn't written as such. Most JS code in production has been transpiled, so that means most JS is already adhering to strict mode. It's possible to undo that assumption, but you really have to go out of your way to do so, so it's highly unlikely.\n\nMoreover, a wide shift is happening toward more/most new JS code being written using the ES6 module format. ES6 modules assume strict mode, so all code in such files is automatically defaulted to strict mode.\n\nTaken together, strict mode is largely the de facto default even though technically it's not actually the default.\n\n## Defined\n\nJS is an implementation of the ECMAScript standard (version ES2019 as of this writing), which is guided by the TC39 committee and hosted by ECMA. It runs in browsers and other JS environments such as Node.js.\n\nJS is a multi-paradigm language, meaning the syntax and capabilities allow a developer to mix and match (and bend and reshape!) concepts from various major paradigms, such as procedural, object-oriented (OO/classes), and functional (FP).\n\nJS is a compiled language, meaning the tools (including the JS engine) process and verify a program (reporting any errors!) before it executes.\n\nWith our language now *defined*, let's start getting to know its ins and outs.\n\n[^specApB]: ECMAScript 2019 Language Specification, Appendix B: Additional ECMAScript Features for Web Browsers, https://www.ecma-international.org/ecma-262/10.0/#sec-additional-ecmascript-features-for-web-browsers (latest as of time of this writing in January 2020)\n"
  },
  {
    "path": "get-started/ch2.md",
    "content": "# You Don't Know JS Yet: Get Started - 2nd Edition\n# Chapter 2: Surveying JS\n\nThe best way to learn JS is to start writing JS.\n\nTo do that, you need to know how the language works, and that's what we'll focus on here. Even if you've programmed in other languages before, take your time getting comfortable with JS, and make sure to practice each piece.\n\nThis chapter is not an exhaustive reference on every bit of syntax of the JS language. It's also not intended to be a complete \"intro to JS\" primer.\n\nInstead, we're just going to survey some of the major topic areas of the language. Our goal is to get a better *feel* for it, so that we can move forward writing our own programs with more confidence. We'll revisit many of these topics in successively more detail as you go through the rest of this book, and the rest of the series.\n\nPlease don't expect this chapter to be a quick read. It's long and there's plenty of detail to chew on. Take your time.\n\n| TIP: |\n| :--- |\n| If you're still getting familiar with JS, I suggest you reserve plenty of extra time to work through this chapter. Take each section and ponder and explore the topic for awhile. Look through existing JS programs and compare what you see in them to the code and explanations (and opinions!) presented here. You will get a lot more out of the rest of the book and series with a solid foundation of JS's *nature*. |\n\n## Each File is a Program\n\nAlmost every website (web application) you use is comprised of many different JS files (typically with the .js file extension). It's tempting to think of the whole thing (the application) as one program. But JS sees it differently.\n\nIn JS, each standalone file is its own separate program.\n\nThe reason this matters is primarily around error handling. Since JS treats files as programs, one file may fail (during parse/compile or execution) and that will not necessarily prevent the next file from being processed. Obviously, if your application depends on five .js files, and one of them fails, the overall application will probably only partially operate, at best. It's important to ensure that each file works properly, and that to whatever extent possible, they handle failure in other files as gracefully as possible.\n\nIt may surprise you to consider separate .js files as separate JS programs. From the perspective of your usage of an application, it sure seems like one big program. That's because the execution of the application allows these individual *programs* to cooperate and act as one program.\n\n| NOTE: |\n| :--- |\n| Many projects use build process tools that end up combining separate files from the project into a single file to be delivered to a web page. When this happens, JS treats this single combined file as the entire program. |\n\nThe only way multiple standalone .js files act as a single program is by sharing their state (and access to their public functionality) via the \"global scope.\" They mix together in this global scope namespace, so at runtime they act as a whole.\n\nSince ES6, JS has also supported a module format in addition to the typical standalone JS program format. Modules are also file-based. If a file is loaded via module-loading mechanism such as an `import` statement or a `<script type=module>` tag, all its code is treated as a single module.\n\nThough you wouldn't typically think about a module—a collection of state and publicly exposed methods to operate on that state—as a standalone program, JS does in fact still treat each module separately. Similar to how \"global scope\" allows standalone files to mix together at runtime, importing a module into another allows runtime interoperation between them.\n\nRegardless of which code organization pattern (and loading mechanism) is used for a file (standalone or module), you should still think of each file as its own (mini) program, which may then cooperate with other (mini) programs to perform the functions of your overall application.\n\n## Values\n\nThe most fundamental unit of information in a program is a value. Values are data. They're how the program maintains state. Values come in two forms in JS: **primitive** and **object**.\n\nValues are embedded in programs using *literals*:\n\n```js\ngreeting(\"My name is Kyle.\");\n```\n\nIn this program, the value `\"My name is Kyle.\"` is a primitive string literal; strings are ordered collections of characters, usually used to represent words and sentences.\n\nI used the double-quote `\"` character to *delimit* (surround, separate, define) the string value. But I could have used the single-quote `'` character as well. The choice of which quote character is entirely stylistic. The important thing, for the sake of code readability and maintainability, is to pick one and to use it consistently throughout the program.\n\nAnother option to delimit a string literal is to use the back-tick `` ` `` character. However, this choice is not merely stylistic; there's a behavioral difference as well. Consider:\n\n```js\nconsole.log(\"My name is ${ firstName }.\");\n// My name is ${ firstName }.\n\nconsole.log('My name is ${ firstName }.');\n// My name is ${ firstName }.\n\nconsole.log(`My name is ${ firstName }.`);\n// My name is Kyle.\n```\n\nAssuming this program has already defined a variable `firstName` with the string value `\"Kyle\"`, the `` ` ``-delimited string then resolves the variable expression (indicated with `${ .. }`) to its current value. This is called **interpolation**.\n\nThe back-tick `` ` ``-delimited string can be used without including interpolated expressions, but that defeats the whole purpose of that alternate string literal syntax:\n\n```js\nconsole.log(\n    `Am I confusing you by omitting interpolation?`\n);\n// Am I confusing you by omitting interpolation?\n```\n\nThe better approach is to use `\"` or `'` (again, pick one and stick to it!) for strings *unless you need* interpolation; reserve `` ` `` only for strings that will include interpolated expressions.\n\nOther than strings, JS programs often contain other primitive literal values such as booleans and numbers:\n\n```js\nwhile (false) {\n    console.log(3.141592);\n}\n```\n\n`while` represents a loop type, a way to repeat operations *while* its condition is true.\n\nIn this case, the loop will never run (and nothing will be printed), because we used the `false` boolean value as the loop conditional. `true` would have resulted in a loop that keeps going forever, so be careful!\n\nThe number `3.141592` is, as you may know, an approximation of mathematical PI to the first six digits. Rather than embed such a value, however, you would typically use the predefined `Math.PI` value for that purpose. Another variation on numbers is the `bigint` (big-integer) primitive type, which is used for storing arbitrarily large numbers.\n\nNumbers are most often used in programs for counting steps, such as loop iterations, and accessing information in numeric positions (i.e., an array index). We'll cover arrays/objects in a little bit, but as an example, if there was an array called `names`, we could access the element in its second position like this:\n\n```js\nconsole.log(`My name is ${ names[1] }.`);\n// My name is Kyle.\n```\n\nWe used `1` for the element in the second position, instead of `2`, because like in most programming languages, JS array indices are 0-based (`0` is the first position).\n\nIn addition to strings, numbers, and booleans, two other *primitive* values in JS programs are `null` and `undefined`. While there are differences between them (some historic and some contemporary), for the most part both values serve the purpose of indicating *emptiness* (or absence) of a value.\n\nMany developers prefer to treat them both consistently in this fashion, which is to say that the values are assumed to be indistinguishable. If care is taken, this is often possible. However, it's safest and best to use only `undefined` as the single empty value, even though `null` seems attractive in that it's shorter to type!\n\n```js\nwhile (value != undefined) {\n    console.log(\"Still got something!\");\n}\n```\n\nThe final primitive value to be aware of is a symbol, which is a special-purpose value that behaves as a hidden unguessable value. Symbols are almost exclusively used as special keys on objects:\n\n```js\nhitchhikersGuide[ Symbol(\"meaning of life\") ];\n// 42\n```\n\nYou won't encounter direct usage of symbols very often in typical JS programs. They're mostly used in low-level code such as in libraries and frameworks.\n\n### Arrays And Objects\n\nBesides primitives, the other value type in JS is an object value.\n\nAs mentioned earlier, arrays are a special type of object that's comprised of an ordered and numerically indexed list of data:\n\n```js\nvar names = [ \"Frank\", \"Kyle\", \"Peter\", \"Susan\" ];\n\nnames.length;\n// 4\n\nnames[0];\n// Frank\n\nnames[1];\n// Kyle\n```\n\nJS arrays can hold any value type, either primitive or object (including other arrays). As we'll see toward the end of Chapter 3, even functions are values that can be held in arrays or objects.\n\n| NOTE: |\n| :--- |\n| Functions, like arrays, are a special kind (aka, sub-type) of object. We'll cover functions in more detail in a bit. |\n\nObjects are more general: an unordered, keyed collection of any various values. In other words, you access the element by a string location name (aka \"key\" or \"property\") rather than by its numeric position (as with arrays). For example:\n\n```js\nvar me = {\n    first: \"Kyle\",\n    last: \"Simpson\",\n    age: 39,\n    specialties: [ \"JS\", \"Table Tennis\" ]\n};\n\nconsole.log(`My name is ${ me.first }.`);\n```\n\nHere, `me` represents an object, and `first` represents the name of a location of information in that object (value collection). Another syntax option that accesses information in an object by its property/key uses the square-brackets `[ ]`, such as  `me[\"first\"]`.\n\n### Value Type Determination\n\nFor distinguishing values, the `typeof` operator tells you its built-in type, if primitive, or `\"object\"` otherwise:\n\n```js\ntypeof 42;                  // \"number\"\ntypeof \"abc\";               // \"string\"\ntypeof true;                // \"boolean\"\ntypeof undefined;           // \"undefined\"\ntypeof null;                // \"object\" -- oops, bug!\ntypeof { \"a\": 1 };          // \"object\"\ntypeof [1,2,3];             // \"object\"\ntypeof function hello(){};  // \"function\"\n```\n\n| WARNING: |\n| :--- |\n| `typeof null` unfortunately returns `\"object\"` instead of the expected `\"null\"`. Also, `typeof` returns the specific `\"function\"` for functions, but not the expected `\"array\"` for arrays. |\n\nConverting from one value type to another, such as from string to number, is referred to in JS as \"coercion.\" We'll cover this in more detail later in this chapter.\n\nPrimitive values and object values behave differently when they're assigned or passed around. We'll cover these details in Appendix A, \"Values vs References.\"\n\n## Declaring and Using Variables\n\nTo be explicit about something that may not have been obvious in the previous section: in JS programs, values can either appear as literal values (as many of the preceding examples illustrate), or they can be held in variables; think of variables as just containers for values.\n\nVariables have to be declared (created) to be used. There are various syntax forms that declare variables (aka, \"identifiers\"), and each form has different implied behaviors.\n\nFor example, consider the `var` statement:\n\n```js\nvar myName = \"Kyle\";\nvar age;\n```\n\nThe `var` keyword declares a variable to be used in that part of the program, and optionally allows an initial assignment of a value.\n\nAnother similar keyword is `let`:\n\n```js\nlet myName = \"Kyle\";\nlet age;\n```\n\nThe `let` keyword has some differences to `var`, with the most obvious being that `let` allows a more limited access to the variable than `var`. This is called \"block scoping\" as opposed to regular or function scoping.\n\nConsider:\n\n```js\nvar adult = true;\n\nif (adult) {\n    var myName = \"Kyle\";\n    let age = 39;\n    console.log(\"Shhh, this is a secret!\");\n}\n\nconsole.log(myName);\n// Kyle\n\nconsole.log(age);\n// Error!\n```\n\nThe attempt to access `age` outside of the `if` statement results in an error, because `age` was block-scoped to the `if`, whereas `myName` was not.\n\nBlock-scoping is very useful for limiting how widespread variable declarations are in our programs, which helps prevent accidental overlap of their names.\n\nBut `var` is still useful in that it communicates \"this variable will be seen by a wider scope (of the whole function)\". Both declaration forms can be appropriate in any given part of a program, depending on the circumstances.\n\n| NOTE: |\n| :--- |\n| It's very common to suggest that `var` should be avoided in favor of `let` (or `const`!), generally because of perceived confusion over how the scoping behavior of `var` has worked since the beginning of JS. I believe this to be overly restrictive advice and ultimately unhelpful. It's assuming you are unable to learn and use a feature properly in combination with other features. I believe you *can* and *should* learn any features available, and use them where appropriate! |\n\nA third declaration form is `const`. It's like `let` but has an additional limitation that it must be given a value at the moment it's declared, and cannot be re-assigned a different value later.\n\nConsider:\n\n```js\nconst myBirthday = true;\nlet age = 39;\n\nif (myBirthday) {\n    age = age + 1;    // OK!\n    myBirthday = false;  // Error!\n}\n```\n\nThe `myBirthday` constant is not allowed to be re-assigned.\n\n`const` declared variables are not \"unchangeable\", they just cannot be re-assigned. It's ill-advised to use `const` with object values, because those values can still be changed even though the variable can't be re-assigned. This leads to potential confusion down the line, so I think it's wise to avoid situations like:\n\n```js\nconst actors = [\n    \"Morgan Freeman\", \"Jennifer Aniston\"\n];\n\nactors[2] = \"Tom Cruise\";   // OK :(\nactors = [];                // Error!\n```\n\nThe best semantic use of a `const` is when you have a simple primitive value that you want to give a useful name to, such as using `myBirthday` instead of `true`. This makes programs easier to read.\n\n| TIP: |\n| :--- |\n| If you stick to using `const` only with primitive values, you avoid any confusion of re-assignment (not allowed) vs. mutation (allowed)! That's the safest and best way to use `const`. |\n\nBesides `var` / `let` / `const`, there are other syntactic forms that declare identifiers (variables) in various scopes. For example:\n\n```js\nfunction hello(myName) {\n    console.log(`Hello, ${ myName }.`);\n}\n\nhello(\"Kyle\");\n// Hello, Kyle.\n```\n\nThe identifier `hello` is created in the outer scope, and it's also automatically associated so that it references the function. But the named parameter `myName` is created only inside the function, and thus is only accessible inside that function's scope. `hello` and `myName` generally behave as `var`-declared.\n\nAnother syntax that declares a variable is a `catch` clause:\n\n```js\ntry {\n    someError();\n}\ncatch (err) {\n    console.log(err);\n}\n```\n\nThe `err` is a block-scoped variable that exists only inside the `catch` clause, as if it had been declared with `let`.\n\n## Functions\n\nThe word \"function\" has a variety of meanings in programming. For example, in the world of Functional Programming, \"function\" has a precise mathematical definition and implies a strict set of rules to abide by.\n\nIn JS, we should consider \"function\" to take the broader meaning of another related term: \"procedure.\" A procedure is a collection of statements that can be invoked one or more times, may be provided some inputs, and may give back one or more outputs.\n\nFrom the early days of JS, function definition looked like:\n\n```js\nfunction awesomeFunction(coolThings) {\n    // ..\n    return amazingStuff;\n}\n```\n\nThis is called a function declaration because it appears as a statement by itself, not as an expression in another statement. The association between the identifier `awesomeFunction` and the function value happens during the compile phase of the code, before that code is executed.\n\nIn contrast to a function declaration statement, a function expression can be defined and assigned like this:\n\n```js\n// let awesomeFunction = ..\n// const awesomeFunction = ..\nvar awesomeFunction = function(coolThings) {\n    // ..\n    return amazingStuff;\n};\n```\n\nThis function is an expression that is assigned to the variable `awesomeFunction`. Different from the function declaration form, a function expression is not associated with its identifier until that statement during runtime.\n\nIt's extremely important to note that in JS, functions are values that can be assigned (as shown in this snippet) and passed around. In fact, JS functions are a special type of the object value type. Not all languages treat functions as values, but it's essential for a language to support the functional programming pattern, as JS does.\n\nJS functions can receive parameter input:\n\n```js\nfunction greeting(myName) {\n    console.log(`Hello, ${ myName }!`);\n}\n\ngreeting(\"Kyle\");   // Hello, Kyle!\n```\n\nIn this snippet, `myName` is called a parameter, which acts as a local variable inside the function. Functions can be defined to receive any number of parameters, from none upward, as you see fit. Each parameter is assigned the argument value that you pass in that position (`\"Kyle\"`, here) of the call.\n\nFunctions also can return values using the `return` keyword:\n\n```js\nfunction greeting(myName) {\n    return `Hello, ${ myName }!`;\n}\n\nvar msg = greeting(\"Kyle\");\n\nconsole.log(msg);   // Hello, Kyle!\n```\n\nYou can only `return` a single value, but if you have more values to return, you can wrap them up into a single object/array.\n\nSince functions are values, they can be assigned as properties on objects:\n\n```js\nvar whatToSay = {\n    greeting() {\n        console.log(\"Hello!\");\n    },\n    question() {\n        console.log(\"What's your name?\");\n    },\n    answer() {\n        console.log(\"My name is Kyle.\");\n    }\n};\n\nwhatToSay.greeting();\n// Hello!\n```\n\nIn this snippet, references to three functions (`greeting()`, `question()`, and `answer()`) are included in the object held by `whatToSay`. Each function can be called by accessing the property to retrieve the function reference value. Compare this straightforward style of defining functions on an object to the more sophisticated `class` syntax discussed later in this chapter.\n\nThere are many varied forms that `function`s take in JS. We dig into these variations in Appendix A, \"So Many Function Forms.\"\n\n## Comparisons\n\nMaking decisions in programs requires comparing values to determine their identity and relationship to each other. JS has several mechanisms to enable value comparison, so let's take a closer look at them.\n\n### Equal...ish\n\nThe most common comparison in JS programs asks the question, \"Is this X value *the same as* that Y value?\" What exactly does \"the same as\" really mean to JS, though?\n\nFor ergonomic and historical reasons, the meaning is more complicated than the obvious *exact identity* sort of matching. Sometimes an equality comparison intends *exact* matching, but other times the desired comparison is a bit broader, allowing *closely similar* or *interchangeable* matching. In other words, we must be aware of the nuanced differences between an **equality** comparison and an **equivalence** comparison.\n\nIf you've spent any time working with and reading about JS, you've certainly seen the so-called \"triple-equals\" `===` operator, also described as the \"strict equality\" operator. That seems rather straightforward, right? Surely, \"strict\" means strict, as in narrow and *exact*.\n\nNot *exact*ly.\n\nYes, most values participating in an `===` equality comparison will fit with that *exact same* intuition. Consider some examples:\n\n```js\n3 === 3.0;              // true\n\"yes\" === \"yes\";        // true\nnull === null;          // true\nfalse === false;        // true\n\n42 === \"42\";            // false\n\"hello\" === \"Hello\";    // false\ntrue === 1;             // false\n0 === null;             // false\n\"\" === null;            // false\nnull === undefined;     // false\n```\n\n| NOTE: |\n| :--- |\n| Another way `===`'s equality comparison is often described is, \"checking both the value and the type\". In several of the examples we've looked at so far, like `42 === \"42\"`, the *type* of both values (number, string, etc.) does seem to be the distinguishing factor. There's more to it than that, though. **All** value comparisons in JS consider the type of the values being compared, not *just* the `===` operator. Specifically, `===` disallows any sort of type conversion (aka, \"coercion\") in its comparison, where other JS comparisons *do* allow coercion. |\n\nBut the `===` operator does have some nuance to it, a fact many JS developers gloss over, to their detriment. The `===` operator is designed to *lie* in two cases of special values: `NaN` and `-0`. Consider:\n\n```js\nNaN === NaN;            // false\n0 === -0;               // true\n```\n\nIn the case of `NaN`, the `===` operator *lies* and says that an occurrence of `NaN` is not equal to another `NaN`. In the case of `-0` (yes, this is a real, distinct value you can use intentionally in your programs!), the `===` operator *lies* and says it's equal to the regular `0` value.\n\nSince the *lying* about such comparisons can be bothersome, it's best to avoid using `===` for them. For `NaN` comparisons, use the `Number.isNaN(..)` utility, which does not *lie*. For `-0` comparison, use the `Object.is(..)` utility, which also does not *lie*. `Object.is(..)` can also be used for non-*lying* `NaN` checks, if you prefer. Humorously, you could think of `Object.is(..)` as the \"quadruple-equals\" `====`, the really-really-strict comparison!\n\nThere are deeper historical and technical reasons for these *lies*, but that doesn't change the fact that `===` is not actually *strictly exactly equal* comparison, in the *strictest* sense.\n\nThe story gets even more complicated when we consider comparisons of object values (non-primitives). Consider:\n\n```js\n[ 1, 2, 3 ] === [ 1, 2, 3 ];    // false\n{ a: 42 } === { a: 42 }         // false\n(x => x * 2) === (x => x * 2)   // false\n```\n\nWhat's going on here?\n\nIt may seem reasonable to assume that an equality check considers the *nature* or *contents* of the value; after all, `42 === 42` considers the actual `42` value and compares it. But when it comes to objects, a content-aware comparison is generally referred to as \"structural equality.\"\n\nJS does not define `===` as *structural equality* for object values. Instead, `===` uses *identity equality* for object values.\n\nIn JS, all object values are held by reference (see \"Values vs References\" in Appendix A), are assigned and passed by reference-copy, **and** to our current discussion, are compared by reference (identity) equality. Consider:\n\n```js\nvar x = [ 1, 2, 3 ];\n\n// assignment is by reference-copy, so\n// y references the *same* array as x,\n// not another copy of it.\nvar y = x;\n\ny === x;              // true\ny === [ 1, 2, 3 ];    // false\nx === [ 1, 2, 3 ];    // false\n```\n\nIn this snippet, `y === x` is true because both variables hold a reference to the same initial array. But the `=== [1,2,3]` comparisons both fail because `y` and `x`, respectively, are being compared to new *different* arrays `[1,2,3]`. The array structure and contents don't matter in this comparison, only the **reference identity**.\n\nJS does not provide a mechanism for structural equality comparison of object values, only reference identity comparison. To do structural equality comparison, you'll need to implement the checks yourself.\n\nBut beware, it's more complicated than you'll assume. For example, how might you determine if two function references are \"structurally equivalent\"? Even stringifying to compare their source code text wouldn't take into account things like closure. JS doesn't provide structural equality comparison because it's almost intractable to handle all the corner cases!\n\n### Coercive Comparisons\n\nCoercion means a value of one type being converted to its respective representation in another type (to whatever extent possible). As we'll discuss in Chapter 4, coercion is a core pillar of the JS language, not some optional feature that can reasonably be avoided.\n\nBut where coercion meets comparison operators (like equality), confusion and frustration unfortunately crop up more often than not.\n\nFew JS features draw more ire in the broader JS community than the `==` operator, generally referred to as the \"loose equality\" operator. The majority of all writing and public discourse on JS condemns this operator as poorly designed and dangerous/bug-ridden when used in JS programs. Even the creator of the language himself, Brendan Eich, has lamented how it was designed as a big mistake.\n\nFrom what I can tell, most of this frustration comes from a pretty short list of confusing corner cases, but a deeper problem is the extremely widespread misconception that it performs its comparisons without considering the types of its compared values.\n\nThe `==` operator performs an equality comparison similarly to how the `===` performs it. In fact, both operators consider the type of the values being compared. And if the comparison is between the same value type, both `==` and `===` **do exactly the same thing, no difference whatsoever.**\n\nIf the value types being compared are different, the `==` differs from `===` in that it allows coercion before the comparison. In other words, they both want to compare values of like types, but `==` allows type conversions *first*, and once the types have been converted to be the same on both sides, then `==` does the same thing as `===`. Instead of \"loose equality,\" the `==` operator should be described as \"coercive equality.\"\n\nConsider:\n\n```js\n42 == \"42\";             // true\n1 == true;              // true\n```\n\nIn both comparisons, the value types are different, so the `==` causes the non-number values (`\"42\"` and `true`) to be converted to numbers (`42` and `1`, respectively) before the comparisons are made.\n\nJust being aware of this nature of `==`—that it prefers primitive numeric comparisons—helps you avoid most of the troublesome corner cases, such as staying away from a gotchas like `\"\" == 0` or `0 == false`.\n\nYou may be thinking, \"Oh, well, I will just always avoid any coercive equality comparison (using `===` instead) to avoid those corner cases\"! Eh, sorry, that's not quite as likely as you would hope.\n\nThere's a pretty good chance that you'll use relational comparison operators like `<`, `>` (and even `<=` and `>=`).\n\nJust like `==`, these operators will perform as if they're \"strict\" if the types being relationally compared already match, but they'll allow coercion first (generally, to numbers) if the types differ.\n\nConsider:\n\n```js\nvar arr = [ \"1\", \"10\", \"100\", \"1000\" ];\nfor (let i = 0; i < arr.length && arr[i] < 500; i++) {\n    // will run 3 times\n}\n```\n\nThe `i < arr.length` comparison is \"safe\" from coercion because `i` and `arr.length` are always numbers. The `arr[i] < 500` invokes coercion, though, because the `arr[i]` values are all strings. Those comparisons thus become `1 < 500`, `10 < 500`, `100 < 500`, and `1000 < 500`. Since that fourth one is false, the loop stops after its third iteration.\n\nThese relational operators typically use numeric comparisons, except in the case where **both** values being compared are already strings; in this case, they use alphabetical (dictionary-like) comparison of the strings:\n\n```js\nvar x = \"10\";\nvar y = \"9\";\n\nx < y;      // true, watch out!\n```\n\nThere's no way to get these relational operators to avoid coercion, other than to just never use mismatched types in the comparisons. That's perhaps admirable as a goal, but it's still pretty likely you're going to run into a case where the types *may* differ.\n\nThe wiser approach is not to avoid coercive comparisons, but to embrace and learn their ins and outs.\n\nCoercive comparisons crop up in other places in JS, such as conditionals (`if`, etc.), which we'll revisit in Appendix A, \"Coercive Conditional Comparison.\"\n\n## How We Organize in JS\n\nTwo major patterns for organizing code (data and behavior) are used broadly across the JS ecosystem: classes and modules. These patterns are not mutually exclusive; many programs can and do use both. Other programs will stick with just one pattern, or even neither!\n\nIn some respects, these patterns are very different. But interestingly, in other ways, they're just different sides of the same coin. Being proficient in JS requires understanding both patterns and where they are appropriate (and not!).\n\n### Classes\n\nThe terms \"object-oriented,\" \"class-oriented,\" and \"classes\" are all very loaded full of detail and nuance; they're not universal in definition.\n\nWe will use a common and somewhat traditional definition here, the one most likely familiar to those with backgrounds in \"object-oriented\" languages like C++ and Java.\n\nA class in a program is a definition of a \"type\" of custom data structure that includes both data and behaviors that operate on that data. Classes define how such a data structure works, but classes are not themselves concrete values. To get a concrete value that you can use in the program, a class must be *instantiated* (with the `new` keyword) one or more times.\n\nConsider:\n\n```js\nclass Page {\n    constructor(text) {\n        this.text = text;\n    }\n\n    print() {\n        console.log(this.text);\n    }\n}\n\nclass Notebook {\n    constructor() {\n        this.pages = [];\n    }\n\n    addPage(text) {\n        var page = new Page(text);\n        this.pages.push(page);\n    }\n\n    print() {\n        for (let page of this.pages) {\n            page.print();\n        }\n    }\n}\n\nvar mathNotes = new Notebook();\nmathNotes.addPage(\"Arithmetic: + - * / ...\");\nmathNotes.addPage(\"Trigonometry: sin cos tan ...\");\n\nmathNotes.print();\n// ..\n```\n\nIn the `Page` class, the data is a string of text stored in a `this.text` member property. The behavior is `print()`, a method that dumps the text to the console.\n\nFor the `Notebook` class, the data is an array of `Page` instances. The behavior is `addPage(..)`, a method that instantiates new `Page` pages and adds them to the list, as well as `print()` (which prints out all the pages in the notebook).\n\nThe statement `mathNotes = new Notebook()` creates an instance of the `Notebook` class, and `page = new Page(text)` is where instances of the `Page` class are created.\n\nBehavior (methods) can only be called on instances (not the classes themselves), such as `mathNotes.addPage(..)` and `page.print()`.\n\nThe `class` mechanism allows packaging data (`text` and `pages`) to be organized together with their behaviors (e.g., `addPage(..)` and `print()`). The same program could have been built without any `class` definitions, but it would likely have been much less organized, harder to read and reason about, and more susceptible to bugs and subpar maintenance.\n\n#### Class Inheritance\n\nAnother aspect inherent to traditional \"class-oriented\" design, though a bit less commonly used in JS, is \"inheritance\" (and \"polymorphism\"). Consider:\n\n```js\nclass Publication {\n    constructor(title,author,pubDate) {\n        this.title = title;\n        this.author = author;\n        this.pubDate = pubDate;\n    }\n\n    print() {\n        console.log(`\n            Title: ${ this.title }\n            By: ${ this.author }\n            ${ this.pubDate }\n        `);\n    }\n}\n```\n\nThis `Publication` class defines a set of common behavior that any publication might need.\n\nNow let's consider more specific types of publication, like `Book` and `BlogPost`:\n\n```js\nclass Book extends Publication {\n    constructor(bookDetails) {\n        super(\n            bookDetails.title,\n            bookDetails.author,\n            bookDetails.pubDate\n        );\n        this.publisher = bookDetails.publisher;\n        this.ISBN = bookDetails.ISBN;\n    }\n\n    print() {\n        super.print();\n        console.log(`\n            Publisher: ${ this.publisher }\n            ISBN: ${ this.ISBN }\n        `);\n    }\n}\n\nclass BlogPost extends Publication {\n    constructor(title,author,pubDate,URL) {\n        super(title,author,pubDate);\n        this.URL = URL;\n    }\n\n    print() {\n        super.print();\n        console.log(this.URL);\n    }\n}\n```\n\nBoth `Book` and `BlogPost` use the `extends` clause to *extend* the general definition of `Publication` to include additional behavior. The `super(..)` call in each constructor delegates to the parent `Publication` class's constructor for its initialization work, and then they do more specific things according to their respective publication type (aka, \"sub-class\" or \"child class\").\n\nNow consider using these child classes:\n\n```js\nvar YDKJS = new Book({\n    title: \"You Don't Know JS\",\n    author: \"Kyle Simpson\",\n    pubDate: \"June 2014\",\n    publisher: \"O'Reilly\",\n    ISBN: \"123456-789\"\n});\n\nYDKJS.print();\n// Title: You Don't Know JS\n// By: Kyle Simpson\n// June 2014\n// Publisher: O'Reilly\n// ISBN: 123456-789\n\nvar forAgainstLet = new BlogPost(\n    \"For and against let\",\n    \"Kyle Simpson\",\n    \"October 27, 2014\",\n    \"https://davidwalsh.name/for-and-against-let\"\n);\n\nforAgainstLet.print();\n// Title: For and against let\n// By: Kyle Simpson\n// October 27, 2014\n// https://davidwalsh.name/for-and-against-let\n```\n\nNotice that both child class instances have a `print()` method, which was an override of the *inherited* `print()` method from the parent `Publication` class. Each of those overridden child class `print()` methods call `super.print()` to invoke the inherited version of the `print()` method.\n\nThe fact that both the inherited and overridden methods can have the same name and co-exist is called *polymorphism*.\n\nInheritance is a powerful tool for organizing data/behavior in separate logical units (classes), but allowing the child class to cooperate with the parent by accessing/using its behavior and data.\n\n### Modules\n\nThe module pattern has essentially the same goal as the class pattern, which is to group data and behavior together into logical units. Also like classes, modules can \"include\" or \"access\" the data and behaviors of other modules, for cooperation's sake.\n\nBut modules have some important differences from classes. Most notably, the syntax is entirely different.\n\n#### Classic Modules\n\nES6 added a module syntax form to native JS syntax, which we'll look at in a moment. But from the early days of JS, modules was an important and common pattern that was leveraged in countless JS programs, even without a dedicated syntax.\n\nThe key hallmarks of a *classic module* are an outer function (that runs at least once), which returns an \"instance\" of the module with one or more functions exposed that can operate on the module instance's internal (hidden) data.\n\nBecause a module of this form is *just a function*, and calling it produces an \"instance\" of the module, another description for these functions is \"module factories\".\n\nConsider the classic module form of the earlier `Publication`, `Book`, and `BlogPost` classes:\n\n```js\nfunction Publication(title,author,pubDate) {\n    var publicAPI = {\n        print() {\n            console.log(`\n                Title: ${ title }\n                By: ${ author }\n                ${ pubDate }\n            `);\n        }\n    };\n\n    return publicAPI;\n}\n\nfunction Book(bookDetails) {\n    var pub = Publication(\n        bookDetails.title,\n        bookDetails.author,\n        bookDetails.publishedOn\n    );\n\n    var publicAPI = {\n        print() {\n            pub.print();\n            console.log(`\n                Publisher: ${ bookDetails.publisher }\n                ISBN: ${ bookDetails.ISBN }\n            `);\n        }\n    };\n\n    return publicAPI;\n}\n\nfunction BlogPost(title,author,pubDate,URL) {\n    var pub = Publication(title,author,pubDate);\n\n    var publicAPI = {\n        print() {\n            pub.print();\n            console.log(URL);\n        }\n    };\n\n    return publicAPI;\n}\n```\n\nComparing these forms to the `class` forms, there are more similarities than differences.\n\nThe `class` form stores methods and data on an object instance, which must be accessed with the `this.` prefix. With modules, the methods and data are accessed as identifier variables in scope, without any `this.` prefix.\n\nWith `class`, the \"API\" of an instance is implicit in the class definition—also, all data and methods are public. With the module factory function, you explicitly create and return an object with any publicly exposed methods, and any data or other unreferenced methods remain private inside the factory function.\n\nThere are other variations to this factory function form that are quite common across JS, even in 2020; you may run across these forms in different JS programs: AMD (Asynchronous Module Definition), UMD (Universal Module Definition), and CommonJS (classic Node.js-style modules). The variations are minor (not quite compatible). However, all of these forms rely on the same basic principles.\n\nConsider also the usage (aka, \"instantiation\") of these module factory functions:\n\n```js\nvar YDKJS = Book({\n    title: \"You Don't Know JS\",\n    author: \"Kyle Simpson\",\n    publishedOn: \"June 2014\",\n    publisher: \"O'Reilly\",\n    ISBN: \"123456-789\"\n});\n\nYDKJS.print();\n// Title: You Don't Know JS\n// By: Kyle Simpson\n// June 2014\n// Publisher: O'Reilly\n// ISBN: 123456-789\n\nvar forAgainstLet = BlogPost(\n    \"For and against let\",\n    \"Kyle Simpson\",\n    \"October 27, 2014\",\n    \"https://davidwalsh.name/for-and-against-let\"\n);\n\nforAgainstLet.print();\n// Title: For and against let\n// By: Kyle Simpson\n// October 27, 2014\n// https://davidwalsh.name/for-and-against-let\n```\n\nThe only observable difference here is the lack of using `new`, calling the module factories as normal functions.\n\n#### ES Modules\n\nES modules (ESM), introduced to the JS language in ES6, are meant to serve much the same spirit and purpose as the existing *classic modules* just described, especially taking into account important variations and use cases from AMD, UMD, and CommonJS.\n\nThe implementation approach does, however, differ significantly.\n\nFirst, there's no wrapping function to *define* a module. The wrapping context is a file. ESMs are always file-based; one file, one module.\n\nSecond, you don't interact with a module's \"API\" explicitly, but rather use the `export` keyword to add a variable or method to its public API definition. If something is defined in a module but not `export`ed, then it stays hidden (just as with *classic modules*).\n\nThird, and maybe most noticeably different from previously discussed patterns, you don't \"instantiate\" an ES module, you just `import` it to use its single instance. ESMs are, in effect, \"singletons,\" in that there's only one instance ever created, at first `import` in your program, and all other `import`s just receive a reference to that same single instance. If your module needs to support multiple instantiations, you have to provide a *classic module-style* factory function on your ESM definition for that purpose.\n\nIn our running example, we do assume multiple-instantiation, so these following snippets will mix both ESM and *classic modules*.\n\nConsider the file `publication.js`:\n\n```js\nfunction printDetails(title,author,pubDate) {\n    console.log(`\n        Title: ${ title }\n        By: ${ author }\n        ${ pubDate }\n    `);\n}\n\nexport function create(title,author,pubDate) {\n    var publicAPI = {\n        print() {\n            printDetails(title,author,pubDate);\n        }\n    };\n\n    return publicAPI;\n}\n```\n\nTo import and use this module, from another ES module like `blogpost.js`:\n\n```js\nimport { create as createPub } from \"publication.js\";\n\nfunction printDetails(pub,URL) {\n    pub.print();\n    console.log(URL);\n}\n\nexport function create(title,author,pubDate,URL) {\n    var pub = createPub(title,author,pubDate);\n\n    var publicAPI = {\n        print() {\n            printDetails(pub,URL);\n        }\n    };\n\n    return publicAPI;\n}\n```\n\nAnd finally, to use this module, we import into another ES module like `main.js`:\n\n```js\nimport { create as newBlogPost } from \"blogpost.js\";\n\nvar forAgainstLet = newBlogPost(\n    \"For and against let\",\n    \"Kyle Simpson\",\n    \"October 27, 2014\",\n    \"https://davidwalsh.name/for-and-against-let\"\n);\n\nforAgainstLet.print();\n// Title: For and against let\n// By: Kyle Simpson\n// October 27, 2014\n// https://davidwalsh.name/for-and-against-let\n```\n\n| NOTE: |\n| :--- |\n| The `as newBlogPost` clause in the `import` statement is optional; if omitted, a top-level function just named `create(..)` would be imported. In this case, I'm renaming it for readability's sake; its more generic factory name of `create(..)` becomes more semantically descriptive of its purpose as `newBlogPost(..)`. |\n\nAs shown, ES modules can use *classic modules* internally if they need to support multiple-instantiation. Alternatively, we could have exposed a `class` from our module instead of a `create(..)` factory function, with generally the same outcome. However, since you're already using ESM at that point, I'd recommend sticking with *classic modules* instead of `class`.\n\nIf your module only needs a single instance, you can skip the extra layers of complexity: `export` its public methods directly.\n\n## The Rabbit Hole Deepens\n\nAs promised at the top of this chapter, we just glanced over a wide surface area of the main parts of the JS language. Your head may still be spinning, but that's entirely natural after such a firehose of information!\n\nEven with just this \"brief\" survey of JS, we covered or hinted at a ton of details you should carefully consider and ensure you are comfortable with. I'm serious when I suggest: re-read this chapter, maybe several times.\n\nIn the next chapter, we're going to dig much deeper into some important aspects of how JS works at its core. But before you follow that rabbit hole deeper, make sure you've taken adequate time to fully digest what we've just covered here.\n"
  },
  {
    "path": "get-started/ch3.md",
    "content": "# You Don't Know JS Yet: Get Started - 2nd Edition\n# Chapter 3: Digging to the Roots of JS\n\nIf you've read Chapters 1 and 2, and taken the time to digest and percolate, you're hopefully starting to *get* JS a little more. If you skipped/skimmed them (especially Chapter 2), I recommend going back to spend some more time with that material.\n\nIn Chapter 2, we surveyed syntax, patterns, and behaviors at a high level. In this chapter, our attention shifts to some of the lower-level root characteristics of JS that underpin virtually every line of code we write.\n\nBe aware: this chapter digs much deeper than you're likely used to thinking about a programming language. My goal is to help you appreciate the core of how JS works, what makes it tick. This chapter should begin to answer some of the \"Why?\" questions that may be cropping up as you explore JS. However, this material is still not an exhaustive exposition of the language; that's what the rest of the book series is for! Our goal here is still just to *get started*, and become more comfortable with, the *feel* of JS, how it ebbs and flows.\n\nDon't run so quickly through this material that you get lost in the weeds. As I've said a dozen times already, **take your time**. Even still, you'll probably finish this chapter with remaining questions. That's OK, because there's a whole book series ahead of you to keep exploring!\n\n## Iteration\n\nSince programs are essentially built to process data (and make decisions on that data), the patterns used to step through the data have a big impact on the program's readability.\n\nThe iterator pattern has been around for decades, and suggests a \"standardized\" approach to consuming data from a source one *chunk* at a time. The idea is that it's more common and helpful to iterate the data source—to progressively handle the collection of data by processing the first part, then the next, and so on, rather than handling the entire set all at once.\n\nImagine a data structure that represents a relational database `SELECT` query, which typically organizes the results as rows. If this query had only one or a couple of rows, you could handle the entire result set at once, and assign each row to a local variable, and perform whatever operations on that data that were appropriate.\n\nBut if the query has 100 or 1,000 (or more!) rows, you'll need iterative processing to deal with this data (typically, a loop).\n\nThe iterator pattern defines a data structure called an \"iterator\" that has a reference to an underlying data source (like the query result rows), which exposes a method like `next()`. Calling `next()` returns the next piece of data (i.e., a \"record\" or \"row\" from a database query).\n\nYou don't always know how many pieces of data that you will need to iterate through, so the pattern typically indicates completion by some special value or exception once you iterate through the entire set and *go past the end*.\n\nThe importance of the iterator pattern is in adhering to a *standard* way of processing data iteratively, which creates cleaner and easier to understand code, as opposed to having every data structure/source define its own custom way of handling its data.\n\nAfter many years of various JS community efforts around mutually agreed-upon iteration techniques, ES6 standardized a specific protocol for the iterator pattern directly in the language. The protocol defines a `next()` method whose return is an object called an *iterator result*; the object has `value` and `done` properties, where `done` is a boolean that is `false` until the iteration over the underlying data source is complete.\n\n### Consuming Iterators\n\nWith the ES6 iteration protocol in place, it's workable to consume a data source one value at a time, checking after each `next()` call for `done` to be `true` to stop the iteration. But this approach is rather manual, so ES6 also included several mechanisms (syntax and APIs) for standardized consumption of these iterators.\n\nOne such mechanism is the `for..of` loop:\n\n```js\n// given an iterator of some data source:\nvar it = /* .. */;\n\n// loop over its results one at a time\nfor (let val of it) {\n    console.log(`Iterator value: ${ val }`);\n}\n// Iterator value: ..\n// Iterator value: ..\n// ..\n```\n\n| NOTE: |\n| :--- |\n| We'll omit the manual loop equivalent here, but it's definitely less readable than the `for..of` loop! |\n\nAnother mechanism that's often used for consuming iterators is the `...` operator. This operator actually has two symmetrical forms: *spread* and *rest* (or *gather*, as I prefer). The *spread* form is an iterator-consumer.\n\nTo *spread* an iterator, you have to have *something* to spread it into. There are two possibilities in JS: an array or an argument list for a function call.\n\nAn array spread:\n\n```js\n// spread an iterator into an array,\n// with each iterated value occupying\n// an array element position.\nvar vals = [ ...it ];\n```\n\nA function call spread:\n\n```js\n// spread an iterator into a function,\n// call with each iterated value\n// occupying an argument position.\ndoSomethingUseful( ...it );\n```\n\nIn both cases, the iterator-spread form of `...` follows the iterator-consumption protocol (the same as the `for..of` loop) to retrieve all available values from an iterator and place (aka, spread) them into the receiving context (array, argument list).\n\n### Iterables\n\nThe iterator-consumption protocol is technically defined for consuming *iterables*; an iterable is a value that can be iterated over.\n\nThe protocol automatically creates an iterator instance from an iterable, and consumes *just that iterator instance* to its completion. This means a single iterable could be consumed more than once; each time, a new iterator instance would be created and used.\n\nSo where do we find iterables?\n\nES6 defined the basic data structure/collection types in JS as iterables. This includes strings, arrays, maps, sets, and others.\n\nConsider:\n\n```js\n// an array is an iterable\nvar arr = [ 10, 20, 30 ];\n\nfor (let val of arr) {\n    console.log(`Array value: ${ val }`);\n}\n// Array value: 10\n// Array value: 20\n// Array value: 30\n```\n\nSince arrays are iterables, we can shallow-copy an array using iterator consumption via the `...` spread operator:\n\n```js\nvar arrCopy = [ ...arr ];\n```\n\nWe can also iterate the characters in a string one at a time:\n\n```js\nvar greeting = \"Hello world!\";\nvar chars = [ ...greeting ];\n\nchars;\n// [ \"H\", \"e\", \"l\", \"l\", \"o\", \" \",\n//   \"w\", \"o\", \"r\", \"l\", \"d\", \"!\" ]\n```\n\nA `Map` data structure uses objects as keys, associating a value (of any type) with that object. Maps have a different default iteration than seen here, in that the iteration is not just over the map's values but instead its *entries*. An *entry* is a tuple (2-element array) including both a key and a value.\n\nConsider:\n\n```js\n// given two DOM elements, `btn1` and `btn2`\n\nvar buttonNames = new Map();\nbuttonNames.set(btn1,\"Button 1\");\nbuttonNames.set(btn2,\"Button 2\");\n\nfor (let [btn,btnName] of buttonNames) {\n    btn.addEventListener(\"click\",function onClick(){\n        console.log(`Clicked ${ btnName }`);\n    });\n}\n```\n\nIn the `for..of` loop over the default map iteration, we use the `[btn,btnName]` syntax (called \"array destructuring\") to break down each consumed tuple into the respective key/value pairs (`btn1` / `\"Button 1\"` and `btn2` / `\"Button 2\"`).\n\nEach of the built-in iterables in JS expose a default iteration, one which likely matches your intuition. But you can also choose a more specific iteration if necessary. For example, if we want to consume only the values of the above `buttonNames` map, we can call `values()` to get a values-only iterator:\n\n```js\nfor (let btnName of buttonNames.values()) {\n    console.log(btnName);\n}\n// Button 1\n// Button 2\n```\n\nOr if we want the index *and* value in an array iteration, we can make an entries iterator with the `entries()` method:\n\n```js\nvar arr = [ 10, 20, 30 ];\n\nfor (let [idx,val] of arr.entries()) {\n    console.log(`[${ idx }]: ${ val }`);\n}\n// [0]: 10\n// [1]: 20\n// [2]: 30\n```\n\nFor the most part, all built-in iterables in JS have three iterator forms available: keys-only (`keys()`), values-only (`values()`), and entries (`entries()`).\n\nBeyond just using built-in iterables, you can also ensure your own data structures adhere to the iteration protocol; doing so means you opt into the ability to consume your data with `for..of` loops and the `...` operator. \"Standardizing\" on this protocol means code that is overall more readily recognizable and readable.\n\n| NOTE: |\n| :--- |\n| You may have noticed a nuanced shift that occurred in this discussion. We started by talking about consuming **iterators**, but then switched to talking about iterating over **iterables**. The iteration-consumption protocol expects an *iterable*, but the reason we can provide a direct *iterator* is that an iterator is just an iterable of itself! When creating an iterator instance from an existing iterator, the iterator itself is returned. |\n\n## Closure\n\nPerhaps without realizing it, almost every JS developer has made use of closure. In fact, closure is one of the most pervasive programming functionalities across a majority of languages. It might even be as important to understand as variables or loops; that's how fundamental it is.\n\nYet it feels kind of hidden, almost magical. And it's often talked about in either very abstract or very informal terms, which does little to help us nail down exactly what it is.\n\nWe need to be able to recognize where closure is used in programs, as the presence or lack of closure is sometimes the cause of bugs (or even the cause of performance issues).\n\nSo let's define closure in a pragmatic and concrete way:\n\n> Closure is when a function remembers and continues to access variables from outside its scope, even when the function is executed in a different scope.\n\nWe see two definitional characteristics here. First, closure is part of the nature of a function. Objects don't get closures, functions do. Second, to observe a closure, you must execute a function in a different scope than where that function was originally defined.\n\nConsider:\n\n```js\nfunction greeting(msg) {\n    return function who(name) {\n        console.log(`${ msg }, ${ name }!`);\n    };\n}\n\nvar hello = greeting(\"Hello\");\nvar howdy = greeting(\"Howdy\");\n\nhello(\"Kyle\");\n// Hello, Kyle!\n\nhello(\"Sarah\");\n// Hello, Sarah!\n\nhowdy(\"Grant\");\n// Howdy, Grant!\n```\n\nFirst, the `greeting(..)` outer function is executed, creating an instance of the inner function `who(..)`; that function closes over the variable `msg`, which is the parameter from the outer scope of `greeting(..)`. When that inner function is returned, its reference is assigned to the `hello` variable in the outer scope. Then we call `greeting(..)` a second time, creating a new inner function instance, with a new closure over a new `msg`, and return that reference to be assigned to `howdy`.\n\nWhen the `greeting(..)` function finishes running, normally we would expect all of its variables to be garbage collected (removed from memory). We'd expect each `msg` to go away, but they don't. The reason is closure. Since the inner function instances are still alive (assigned to `hello` and `howdy`, respectively), their closures are still preserving the `msg` variables.\n\nThese closures are not a snapshot of the `msg` variable's value; they are a direct link and preservation of the variable itself. That means closure can actually observe (or make!) updates to these variables over time.\n\n```js\nfunction counter(step = 1) {\n    var count = 0;\n    return function increaseCount(){\n        count = count + step;\n        return count;\n    };\n}\n\nvar incBy1 = counter(1);\nvar incBy3 = counter(3);\n\nincBy1();       // 1\nincBy1();       // 2\n\nincBy3();       // 3\nincBy3();       // 6\nincBy3();       // 9\n```\n\nEach instance of the inner `increaseCount()` function is closed over both the `count` and `step` variables from its outer `counter(..)` function's scope. `step` remains the same over time, but `count` is updated on each invocation of that inner function. Since closure is over the variables and not just snapshots of the values, these updates are preserved.\n\nClosure is most common when working with asynchronous code, such as with callbacks. Consider:\n\n```js\nfunction getSomeData(url) {\n    ajax(url,function onResponse(resp){\n        console.log(\n            `Response (from ${ url }): ${ resp }`\n        );\n    });\n}\n\ngetSomeData(\"https://some.url/wherever\");\n// Response (from https://some.url/wherever): ...\n```\n\nThe inner function `onResponse(..)` is closed over `url`, and thus preserves and remembers it until the Ajax call returns and executes `onResponse(..)`. Even though `getSomeData(..)` finishes right away, the `url` parameter variable is kept alive in the closure for as long as needed.\n\nIt's not necessary that the outer scope be a function—it usually is, but not always—just that there be at least one variable in an outer scope accessed from an inner function:\n\n```js\nfor (let [idx,btn] of buttons.entries()) {\n    btn.addEventListener(\"click\",function onClick(){\n       console.log(`Clicked on button (${ idx })!`);\n    });\n}\n```\n\nBecause this loop is using `let` declarations, each iteration gets new block-scoped (aka, local) `idx` and `btn` variables;  the loop also creates a new inner `onClick(..)` function each time. That inner function closes over `idx`, preserving it for as long as the click handler is set on the `btn`. So when each button is clicked, its handler can print its associated index value, because the handler remembers its respective `idx` variable.\n\nRemember: this closure is not over the value (like `1` or `3`), but over the variable `idx` itself.\n\nClosure is one of the most prevalent and important programming patterns in any language. But that's especially true of JS; it's hard to imagine doing anything useful without leveraging closure in one way or another.\n\nIf you're still feeling unclear or shaky about closure, the majority of Book 2, *Scope & Closures* is focused on the topic.\n\n## `this` Keyword\n\nOne of JS's most powerful mechanisms is also one of its most misunderstood: the `this` keyword. One common misconception is that a function's `this` refers to the function itself. Because of how `this` works in other languages, another misconception is that `this` points the instance that a method belongs to. Both are incorrect.\n\nAs discussed previously, when a function is defined, it is *attached* to its enclosing scope via closure. Scope is the set of rules that controls how references to variables are resolved.\n\nBut functions also have another characteristic besides their scope that influences what they can access. This characteristic is best described as an *execution context*, and it's exposed to the function via its `this` keyword.\n\nScope is static and contains a fixed set of variables available at the moment and location you define a function, but a function's execution *context* is dynamic, entirely dependent on **how it is called** (regardless of where it is defined or even called from).\n\n`this` is not a fixed characteristic of a function based on the function's definition, but rather a dynamic characteristic that's determined each time the function is called.\n\nOne way to think about the *execution context* is that it's a tangible object whose properties are made available to a function while it executes. Compare that to scope, which can also be thought of as an *object*; except, the *scope object* is hidden inside the JS engine, it's always the same for that function, and its *properties* take the form of identifier variables available inside the function.\n\n```js\nfunction classroom(teacher) {\n    return function study() {\n        console.log(\n            `${ teacher } says to study ${ this.topic }`\n        );\n    };\n}\nvar assignment = classroom(\"Kyle\");\n```\n\nThe outer `classroom(..)` function makes no reference to a `this` keyword, so it's just like any other function we've seen so far. But the inner `study()` function does reference `this`, which makes it a `this`-aware function. In other words, it's a function that is dependent on its *execution context*.\n\n| NOTE: |\n| :--- |\n| `study()` is also closed over the `teacher` variable from its outer scope. |\n\nThe inner `study()` function returned by `classroom(\"Kyle\")` is assigned to a variable called `assignment`. So how can `assignment()` (aka `study()`) be called?\n\n```js\nassignment();\n// Kyle says to study undefined  -- Oops :(\n```\n\nIn this snippet, we call `assignment()` as a plain, normal function, without providing it any *execution context*.\n\nSince this program is not in strict mode (see Chapter 1, \"Strictly Speaking\"), context-aware functions that are called **without any context specified** default the context to the global object (`window` in the browser). As there is no global variable named `topic` (and thus no such property on the global object), `this.topic` resolves to `undefined`.\n\nNow consider:\n\n```js\nvar homework = {\n    topic: \"JS\",\n    assignment: assignment\n};\n\nhomework.assignment();\n// Kyle says to study JS\n```\n\nA copy of the `assignment` function reference is set as a property on the `homework` object, and then it's called as `homework.assignment()`. That means the `this` for that function call will be the `homework` object. Hence, `this.topic` resolves to `\"JS\"`.\n\nLastly:\n\n```js\nvar otherHomework = {\n    topic: \"Math\"\n};\n\nassignment.call(otherHomework);\n// Kyle says to study Math\n```\n\nA third way to invoke a function is with the `call(..)` method, which takes an object (`otherHomework` here) to use for setting the `this` reference for the function call. The property reference `this.topic` resolves to `\"Math\"`.\n\nThe same context-aware function invoked three different ways, gives different answers each time for what object `this` will reference.\n\nThe benefit of `this`-aware functions—and their dynamic context—is the ability to more flexibly re-use a single function with data from different objects. A function that closes over a scope can never reference a different scope or set of variables. But a function that has dynamic `this` context awareness can be quite helpful for certain tasks.\n\n## Prototypes\n\nWhere `this` is a characteristic of function execution, a prototype is a characteristic of an object, and specifically resolution of a property access.\n\nThink about a prototype as a linkage between two objects; the linkage is hidden behind the scenes, though there are ways to expose and observe it. This prototype linkage occurs when an object is created; it's linked to another object that already exists.\n\nA series of objects linked together via prototypes is called the \"prototype chain.\"\n\nThe purpose of this prototype linkage (i.e., from an object B to another object A) is so that accesses against B for properties/methods that B does not have, are *delegated* to A to handle. Delegation of property/method access allows two (or more!) objects to cooperate with each other to perform a task.\n\nConsider defining an object as a normal literal:\n\n```js\nvar homework = {\n    topic: \"JS\"\n};\n```\n\nThe `homework` object only has a single property on it: `topic`. However, its default prototype linkage connects to the `Object.prototype` object, which has common built-in methods on it like `toString()` and `valueOf()`, among others.\n\nWe can observe this prototype linkage *delegation* from `homework` to `Object.prototype`:\n\n```js\nhomework.toString();    // [object Object]\n```\n\n`homework.toString()` works even though `homework` doesn't have a `toString()` method defined; the delegation invokes `Object.prototype.toString()` instead.\n\n### Object Linkage\n\nTo define an object prototype linkage, you can create the object using the `Object.create(..)` utility:\n\n```js\nvar homework = {\n    topic: \"JS\"\n};\n\nvar otherHomework = Object.create(homework);\n\notherHomework.topic;   // \"JS\"\n```\n\nThe first argument to `Object.create(..)` specifies an object to link the newly created object to, and then returns the newly created (and linked!) object.\n\nFigure 4 shows how the three objects (`otherHomework`, `homework`, and `Object.prototype`) are linked in a prototype chain:\n\n<figure>\n    <img src=\"images/fig4.png\" width=\"200\" alt=\"Prototype chain with 3 objects\" align=\"center\">\n    <figcaption><em>Fig. 4: Objects in a prototype chain</em></figcaption>\n    <br><br>\n</figure>\n\nDelegation through the prototype chain only applies for accesses to lookup the value in a property. If you assign to a property of an object, that will apply directly to the object regardless of where that object is prototype linked to.\n\n| TIP: |\n| :--- |\n| `Object.create(null)` creates an object that is not prototype linked anywhere, so it's purely just a standalone object; in some circumstances, that may be preferable. |\n\nConsider:\n\n```js\nhomework.topic;\n// \"JS\"\n\notherHomework.topic;\n// \"JS\"\n\notherHomework.topic = \"Math\";\notherHomework.topic;\n// \"Math\"\n\nhomework.topic;\n// \"JS\" -- not \"Math\"\n```\n\nThe assignment to `topic` creates a property of that name directly on `otherHomework`; there's no effect on the `topic` property on `homework`. The next statement then accesses `otherHomework.topic`, and we see the non-delegated answer from that new property: `\"Math\"`.\n\nFigure 5 shows the objects/properties after the assignment that creates the `otherHomework.topic` property:\n\n<figure>\n    <img src=\"images/fig5.png\" width=\"200\" alt=\"3 objects linked, with shadowed property\" align=\"center\">\n    <figcaption><em>Fig. 5: Shadowed property 'topic'</em></figcaption>\n    <br><br>\n</figure>\n\nThe `topic` on `otherHomework` is \"shadowing\" the property of the same name on the `homework` object in the chain.\n\n| NOTE: |\n| :--- |\n| Another frankly more convoluted but perhaps still more common way of creating an object with a prototype linkage is using the \"prototypal class\" pattern, from before `class` (see Chapter 2, \"Classes\") was added in ES6. We'll cover this topic in more detail in Appendix A, \"Prototypal 'Classes'\". |\n\n### `this` Revisited\n\nWe covered the `this` keyword earlier, but its true importance shines when considering how it powers prototype-delegated function calls. Indeed, one of the main reasons `this` supports dynamic context based on how the function is called is so that method calls on objects which delegate through the prototype chain still maintain the expected `this`.\n\nConsider:\n\n```js\nvar homework = {\n    study() {\n        console.log(`Please study ${ this.topic }`);\n    }\n};\n\nvar jsHomework = Object.create(homework);\njsHomework.topic = \"JS\";\njsHomework.study();\n// Please study JS\n\nvar mathHomework = Object.create(homework);\nmathHomework.topic = \"Math\";\nmathHomework.study();\n// Please study Math\n```\n\nThe two objects `jsHomework` and `mathHomework` each prototype link to the single `homework` object, which has the `study()` function. `jsHomework` and `mathHomework` are each given their own `topic` property (see Figure 6).\n\n<figure>\n    <img src=\"images/fig6.png\" width=\"495\" alt=\"4 objects prototype linked\" align=\"center\">\n    <figcaption><em>Fig. 6: Two objects linked to a common parent</em></figcaption>\n    <br><br>\n</figure>\n\n`jsHomework.study()` delegates to `homework.study()`, but its `this` (`this.topic`) for that execution resolves to `jsHomework` because of how the function is called, so `this.topic` is `\"JS\"`. Similarly for `mathHomework.study()` delegating to `homework.study()` but still resolving `this` to `mathHomework`, and thus `this.topic` as `\"Math\"`.\n\nThe preceding code snippet would be far less useful if `this` was resolved to `homework`. Yet, in many other languages, it would seem `this` would be `homework` because the `study()` method is indeed defined on `homework`.\n\nUnlike many other languages, JS's `this` being dynamic is a critical component of allowing prototype delegation, and indeed `class`, to work as expected!\n\n## Asking \"Why?\"\n\nThe intended take-away from this chapter is that there's a lot more to JS under the hood than is obvious from glancing at the surface.\n\nAs you are *getting started* learning and knowing JS more closely, one of the most important skills you can practice and bolster is curiosity, and the art of asking \"Why?\" when you encounter something in the language.\n\nEven though this chapter has gone quite deep on some of the topics, many details have still been entirely skimmed over. There's much more to learn here, and the path to that starts with you asking the *right* questions of your code. Asking the right questions is a critical skill of becoming a better developer.\n\nIn the final chapter of this book, we're going to briefly look at how JS is divided, as covered across the rest of the *You Don't Know JS Yet* book series. Also, don't skip Appendix B of this book, which has some practice code to review some of the main topics covered in this book.\n"
  },
  {
    "path": "get-started/ch4.md",
    "content": "# You Don't Know JS Yet: Get Started - 2nd Edition\n# Chapter 4: The Bigger Picture\n\nThis book surveys what you need to be aware of as you *get started* with JS. The goal is to fill in gaps that readers newer to JS might have tripped over in their early encounters with the language. I also hope that we've hinted at enough deeper detail throughout to pique your curiosity to want to dig more into the language.\n\nThe rest of the books in this series are where we will unpack all of the rest of the language, in far greater detail than we could have done in a few brief chapters here.\n\nRemember to take your time, though. Rather than rushing onto the next book in an attempt to churn through all the books expediently, spend some time going back over the material in this book. Spend some more time looking through code in your current projects, and comparing what you see to what's been discussed so far.\n\nWhen you're ready, this final chapter divides the organization of the JS language into three main pillars, then offers a brief roadmap of what to expect from the rest of the book series, and how I suggest you proceed. Also, don't skip the appendices, especially Appendix B, \"Practice, Practice, Practice!\".\n\n## Pillar 1: Scope and Closure\n\nThe organization of variables into units of scope (functions, blocks) is one of the most foundational characteristics of any language; perhaps no other characteristic has a greater impact on how programs behave.\n\nScopes are like buckets, and variables are like marbles you put into those buckets. The scope model of a language is like the rules that help you determine which color marbles go in which matching-color buckets.\n\nScopes nest inside each other, and for any given expression or statement, only variables at that level of scope nesting, or in higher/outer scopes, are accessible; variables from lower/inner scopes are hidden and inaccessible.\n\nThis is how scopes behave in most languages, which is called lexical scope. The scope unit boundaries, and how variables are organized in them, is determined at the time the program is parsed (compiled). In other words, it's an author-time decision: where you locate a function/scope in the program determines what the scope structure of that part of the program will be.\n\nJS is lexically scoped, though many claim it isn't, because of two particular characteristics of its model that are not present in other lexically scoped languages.\n\nThe first is commonly called *hoisting*: when all variables declared anywhere in a scope are treated as if they're declared at the beginning of the scope. The other is that `var`-declared variables are function scoped, even if they appear inside a block.\n\nNeither hoisting nor function-scoped `var` are sufficient to back the claim that JS is not lexically scoped. `let`/`const` declarations have a peculiar error behavior called the \"Temporal Dead Zone\" (TDZ) which results in observable but unusable variables. Though TDZ can be strange to encounter, it's *also* not an invalidation of lexical scoping. All of these are just unique parts of the language that should be learned and understood by all JS developers.\n\nClosure is a natural result of lexical scope when the language has functions as first-class values, as JS does. When a function makes reference to variables from an outer scope, and that function is passed around as a value and executed in other scopes, it maintains access to its original scope variables; this is closure.\n\nAcross all of programming, but especially in JS, closure drives many of the most important programming patterns, including modules. As I see it, modules are as *with the grain* as you can get, when it comes to code organization in JS.\n\nTo dig further into scope, closures, and how modules work, read Book 2, *Scope & Closures*.\n\n## Pillar 2: Prototypes\n\nThe second pillar of the language is the prototypes system. We covered this topic in-depth in Chapter 3 (\"Prototypes\"), but I just want to make a few more comments about its importance.\n\nJS is one of very few languages where you have the option to create objects directly and explicitly, without first defining their structure in a class.\n\nFor many years, people implemented the class design pattern on top of prototypes—so-called \"prototypal inheritance\" (see Appendix A, \"Prototypal 'Classes'\")—and then with the advent of ES6's `class` keyword, the language doubled-down on its inclination toward OO/class-style programming.\n\nBut I think that focus has obscured the beauty and power of the prototype system: the ability for two objects to simply connect with each other and cooperate dynamically (during function/method execution) through sharing a `this` context.\n\nClasses are just one pattern you can build on top of such power. But another approach, in a very different direction, is to simply embrace objects as objects, forget classes altogether, and let objects cooperate through the prototype chain. This is called *behavior delegation*. I think delegation is more powerful than class inheritance, as a means for organizing behavior and data in our programs.\n\nBut class inheritance gets almost all the attention. And the rest goes to functional programming (FP), as the sort of \"anti-class\" way of designing programs. This saddens me, because it snuffs out any chance for exploration of delegation as a viable alternative.\n\nI encourage you to spend plenty of time deep in Book 3, *Objects & Classes*, to see how object delegation holds far more potential than we've perhaps realized. This isn't an anti-`class` message, but it is intentionally a \"classes aren't the only way to use objects\" message that I want more JS developers to consider.\n\nObject delegation is, I would argue, far more *with the grain* of JS, than classes (more on *grains* in a bit).\n\n## Pillar 3: Types and Coercion\n\nThe third pillar of JS is by far the most overlooked part of JS's nature.\n\nThe vast majority of developers have strong misconceptions about how *types* work in programming languages, and especially how they work in JS. A tidal wave of interest in the broader JS community has begun to shift to \"static typing\" approaches, using type-aware tooling like TypeScript or Flow.\n\nI agree that JS developers should learn more about types, and should learn more about how JS manages type conversions. I also agree that type-aware tooling can help developers, assuming they have gained and used this knowledge in the first place!\n\nBut I don't agree at all that the inevitable conclusion of this is to decide JS's type mechanism is bad and that we need to cover up JS's types with solutions outside the language. We don't have to follow the \"static typing\" way to be smart and solid with types in our programs. There are other options, if you're just willing to go *against the grain* of the crowd, and *with the grain* of JS (again, more on that to come).\n\nArguably, this pillar is more important than the other two, in the sense that no JS program will do anything useful if it doesn't properly leverage JS's value types, as well as the conversion (coercion) of values between types.\n\nEven if you love TypeScript/Flow, you are not going to get the most out of those tools or coding approaches if you aren't deeply familiar with how the language itself manages value types.\n\nTo learn more about JS types and coercion, check out Book 4, *Types & Grammar*. But please don't skip over this topic just because you've always heard that we should use `===` and forget about the rest.\n\nWithout learning this pillar, your foundation in JS is shaky and incomplete at best.\n\n## With the Grain\n\nI have some advice to share on continuing your learning journey with JS, and your path through the rest of this book series: be aware of the *grain* (recall various references to *grain* earlier in this chapter).\n\nFirst, consider the *grain* (as in, wood) of how most people approach and use JS. You've probably already noticed that these books cut against that *grain* in many respects. In YDKJSY, I respect you the reader enough to explain all the parts of JS, not only some select popular parts. I believe you're both capable and deserving of that knowledge.\n\nBut that is not what you'll find from a lot of other material out there. It also means that the more you follow and adhere to the guidance from these books—that you think carefully and analyze for yourself what's best in your code—the more you will stand out. That can be a good and bad thing. If you ever want to break out from the crowd, you're going to have to break from how the crowd does it!\n\nBut I've also had many people tell me that they quoted some topic/explanation from these books during a job interview, and the interviewer told the candidate they were wrong; indeed, people have reportedly lost out on job offers as a result.\n\nAs much as possible, I endeavor in these books to provide completely accurate information about JS, informed generally from the specification itself. But I also dose out quite a bit of my opinions on how you can interpret and use JS to the best benefit in your programs. I don't present opinion as fact, or vice versa. You'll always know which is which in these books.\n\nFacts about JS are not really up for debate. Either the specification says something, or it doesn't. If you don't like what the specification says, or my relaying of it, take that up with TC39! If you're in an interview and they claim you're wrong on the facts, ask them right then and there if you can look it up in the specification. If the interviewer won't re-consider, then you shouldn't want to work there anyway.\n\nBut if you choose to align with my opinions, you have to be prepared to back up those choices with *why* you feel that way. Don't just parrot what I say. Own your opinions. Defend them. And if someone you were hoping to work with disagrees, walk away with your head still held high. It's a big JS, and there's plenty of room for lots of different ways.\n\nIn other words, don't be afraid to go against the *grain*, as I have done with these books and all my teachings. Nobody can tell you how you will best make use of JS; that's for you to decide. I'm merely trying to empower you in coming to your own conclusions, no matter what they are.\n\nOn the other hand, there's a *grain* you really should pay attention to and follow: the *grain* of how JS works, at the language level. There are things that work well and naturally in JS, given the right practice and approach, and there are things you really shouldn't try to do in the language.\n\nCan you make your JS program look like a Java, C#, or Perl program? What about Python or Ruby, or even PHP? To varying degrees, sure you can. But should you?\n\nNo, I don't think you should. I think you should learn and embrace the JS way, and make your JS programs as JS'y as is practical. Some will think that means sloppy and informal programming, but I don't mean that at all. I just mean that JS has a lot of patterns and idioms that are recognizably \"JS,\" and going with that *grain* is the general path to the best success.\n\nFinally, maybe the most important *grain* to recognize is how the existing program(s) you're working on, and developers you're working with, do stuff. Don't read these books and then try to change *all that grain* in your existing projects over night. That approach will always fail.\n\nYou'll have to shift these things little by little, over time. Work on building consensus with your fellow developers on why it's important to re-visit and re-consider an approach. But do so with just one small topic at a time, and let before-and-after code comparisons do most of the talking. Bring everyone on the team together to discuss, and push for decisions that are based on analysis and evidence from the code rather than the inertia of \"our senior devs have always done it this way.\"\n\nThat's the most important advice I can impart to help you learn JS. Always keep looking for better ways to use what JS gives us to author more readable code. Everyone who works on your code, including your future self, will thank you!\n\n## In Order\n\nSo now you've got a broader perspective on what's left to explore in JS, and the right attitude to approach the rest of your journey.\n\nBut one of the most common practical questions I get at this point is, \"What order should I read the books?\" There is a straightforward answer... but it also depends.\n\nMy suggestion for most readers is to proceed through this series in this order:\n\n1. Get started with a solid foundation of JS from *Get Started* (Book 1) -- good news, you've already almost finished this book!\n\n2. In *Scope & Closures* (Book 2), dig into the first pillar of JS: lexical scope, how that supports closure, and how the module pattern organizes code.\n\n3. In *Objects & Classes* (Book 3), focus on the second pillar of JS: how JS's `this` works, how object prototypes support delegation, and how prototypes enable the `class` mechanism for OO-style code organization.\n\n4. In *Types & Grammar* (Book 4), tackle the third and final pillar of JS: types and type coercion, as well as how JS's syntax and grammar define how we write our code.\n\n5. With the **three pillars** solidly in place, *Sync & Async* (Book 5) then explores how we use flow control to model state change in our programs, both synchronously (right away) and asynchronously (over time).\n\n6. The series concludes with *ES.Next & Beyond* (Book 6), a forward look at the near- and mid-term future of JS, including a variety of features likely coming to your JS programs before too long.\n\nThat's the intended order to read this book series.\n\nHowever, Books 2, 3, and 4 can generally be read in any order, depending on which topic you feel most curious about and comfortable exploring first. But I don't recommend you skip any of these three books—not even *Types & Grammar*, as some of you will be tempted to do!—even if you think you already have that topic down.\n\nBook 5 (*Sync & Async*) is crucial for deeply understanding JS, but if you start digging in and find it's too intimidating, this book can be deferred until you're more experienced with the language. The more JS you've written (and struggled with!), the more you'll come to appreciate this book. So don't be afraid to come back to it at a later time.\n\nThe final book in the series, *ES.Next & Beyond*, in some respects stands alone. It can be read at the end, as I suggest, or right after *Getting Started* if you're looking for a shortcut to broaden your radar of what JS is all about. This book will also be more likely to receive updates in the future, so you'll probably want to re-visit it occasionally.\n\nHowever you choose to proceed with YDKJSY, check out the appendices of this book first, especially practicing the snippets in Appendix B, \"Practice, Practice, Practice!\" Did I mention you should go practice!? There's no better way to learn code than to write it.\n"
  },
  {
    "path": "get-started/foreword.md",
    "content": "# You Don't Know JS Yet: Get Started - 2nd Edition\n# Foreword\n\nThe first time I saw a tweet advertising the crowdfunding campaign for the original book series *You Don't Know JS*, I thought to myself that whoever the hell this Kyle Simpson is can get bent. Of course I know JavaScript! At the time I had been working in JavaScript for many years with some of tech's biggest names, so I felt justified in looking down my nose at this sweeping claim.\n\nOnce the funding for the book completed, I observed that a lot of people were really excited to read this book series and I decided to go ahead and give it a shot—you know, just to show everyone that I *do know* JavaScript. Once I dug in and poured over the texts, I experienced a profound mix of learning, surprise, and even a little anger. Kyle has a knack for saying something that challenges my world view and making me think about it until I realize what he said was actually true (I'll never admit this to him though!).\n\nSo it turned out I didn't know JavaScript. I didn't know why I had adopted certain patterns; I didn't know why JavaScript behaves the way it does in certain situations, and I didn't know much of the nuance of the languages that I assumed I did. Many were things I didn't know I didn't know, and I was worse off as a developer for it.\n\nThis is what this book series is great for. It's not just for someone picking up the language for the first time (though it's for them, too); it's for all software craftspeople who want to master their tools, who want to understand the ins and outs of their trade, and who want to select the proper methods for solving problems.\n\nThe thing I appreciate about Kyle and his work is that he is delightfully uninfluenced by the zeitgeist of the programming world around him. That isn't to say he isn't aware of what's happening in the community but rather that it doesn't sway his pursuit of the best answers to the correct questions. This often has put him at odds with the latest \"best practices,\" but in reality this is exactly what you need: a perspective removed from temporal influence and simply speaking to the underlying truth. That's why this series is so good. The first edition of *You Don't Know JS* is still accurate, years later! Not many things stand this test of time given the shifting sands of the JavaScript landscape.\n\nLet's talk a moment about this first book itself, *Get Started*. You may be tempted to skip it as you may think that you already have \"gotten started,\" but it's worth reading this one! You'd be surprised how much depth, nuance, and oddity there is in the underlying building blocks of JavaScript, and it's quite essential for you to grapple with these underpinnings before venturing forward into the constructs of the language. It's exactly the sort of foundation you need, to really know JavaScript.\n\nSo, do your future self a favor and dig into this book and unlock the knowledge within. These solid foundations will serve you better than any framework ever will; those come and go but we'll still be writing JavaScript itself for decades to come. Keep an open mind and challenge your preconceived notions.\n\nBecause, as I found out myself, you probably don't know JavaScript (yet).\n\nBrian Holt<br>\nSenior Program Manager<br>\nVisual Studio Code and Node.js on Azure<br>\nMicrosoft\n"
  },
  {
    "path": "get-started/toc.md",
    "content": "# You Don't Know JS Yet: Get Started - 2nd Edition\n\n## Table of Contents\n\n* Foreword\n* Preface\n* Chapter 1: What Is JavaScript?\n    * About This Book\n    * What's With That Name?\n    * Language Specification\n    * Many Faces\n    * Backwards & Forwards\n    * What's in an Interpretation?\n    * Strictly Speaking\n    * Defined\n* Chapter 2: Surveying JS\n    * Each File is a Program\n    * Values\n    * Declaring and Using Variables\n    * Functions\n    * Comparisons\n    * How We Organize in JS\n    * The Rabbit Hole Deepens\n* Chapter 3: Digging To The Roots Of JS\n    * Iteration\n    * Closure\n    * `this` Keyword\n    * Prototypes\n    * Asking \"Why?\"\n* Chapter 4: The Bigger Picture\n    * Pillar 1: Scope and Closure\n    * Pillar 2: Prototypes\n    * Pillar 3: Types and Coercion\n    * With the Grain\n    * In Order\n* Appendix A: Exploring Further\n    * Values vs. References\n    * So Many Function Forms\n    * Coercive Conditional Comparison\n    * Prototypal \"Classes\"\n* Appendix B: Practice, Practice, Practice!\n    * Practicing Comparisons\n    * Practicing Closure\n    * Practicing Prototypes\n    * Suggested Solutions\n"
  },
  {
    "path": "objects-classes/README.md",
    "content": "# You Don't Know JS Yet: Objects & Classes - 2nd Edition\n\n| NOTE: |\n| :--- |\n| Work in progress |\n\n[Table of Contents](toc.md)\n\n* [Foreword](foreword.md) (by [Rick Waldron](https://twitter.com/rwaldron))\n* [Preface](../preface.md)\n* [Chapter 1: Object Foundations](ch1.md)\n* [Chapter 2: How Objects Work](ch2.md)\n* [Chapter 3: Classy Objects](ch3.md)\n* [Chapter 4: This Works](ch4.md)\n* [Chapter 5: Delegation](ch5.md)\n* [Thank You!](thanks.md)\n"
  },
  {
    "path": "objects-classes/ch1.md",
    "content": "# You Don't Know JS Yet: Objects & Classes - 2nd Edition\n# Chapter 1: Object Foundations\n\n| NOTE: |\n| :--- |\n| Work in progress |\n\n> Everything in JS is an object.\n\nThis is one of the most pervasive, but most incorrect, \"facts\" that perpetually circulates about JS. Let the myth busting commence.\n\nJS definitely has objects, but that doesn't mean that all values are objects. Nevertheless, objects are arguably the most important (and varied!) value type in the language, so mastering them is critical to your JS journey.\n\nThe object mechanism is certainly the most flexible and powerful container type -- something you put other values into; every JS program you write will use them in one way or another. But that's not why objects deserve top billing for this book. Objects are the foundation for the second of JS's three pillars: the prototype.\n\nWhy are prototypes (along with the `this` keyword, covered later in the book) so core to JS as to be one of its three pillars? Among other things, prototypes are how JS's object system can express the class design pattern, one of the most widely relied on design patterns in all of programming.\n\nSo our journey here will start with objects, build up a compelete understanding of prototypes, de-mystify the `this` keyword, and explore the `class` system.\n\n## About This Book\n\nWelcome to book 3 in the *You Don't Know JS Yet* series! If you already finished *Get Started* (the first book) and *Scope & Closures* (the second book), you're in the right spot! If not, before you proceed I encourage you to read those two as foundations before diving into this book.\n\nThe first edition of this book is titled, \"this & Object Prototypes\". In that book, our focus started with the `this` keyword, as it's arguably one of the most confused topics in all of JS. The book then spent the majority of its time focused on expositing the prototype system and advocating for embrace of the lesser-known \"delegation\" pattern instead of class designs. At the time of that book's writing (2014), ES6 would still be almost 2 years to its completion, so I felt the early sketches of the `class` keyword only merited a brief addendum of coverage.\n\nIt's quite an understatement to say a lot has changed in the JS landscape in the almost 8 years since that book. ES6 is old news now; at the time of *this* book's writing, JS has seen 7 yearly updates **after ES6** (ES2016 through ES2022).\n\nNow, we still need to talk about how `this` works, and how that relates to methods invoked against various objects. And `class` actually operates (mostly!) via the prototype chain deep under the covers. But JS developers in 2022 are almost never writing code to explicitly wire up prototypal inheritance anymore. And as much as I personally wish differently, class design patterns -- not \"behavior delegation\" -- are how the majority of data and behavior organization (data structures) in JS are expressed.\n\nThis book reflects JS's current reality: thus the new sub-title, new organization and focus of topics, and complete re-write of the previous edition's text.\n\n## Objects As Containers\n\nOne common way of gathering up multiple values in a single container is with an object. Objects are collections of key/value pairs. There are also sub-types of object in JS with specialized behaviors, such as arrays (numerically indexed) and even functions (callable); more on these sub-types later.\n\n| NOTE: |\n| :--- |\n| Keys are often referred to as \"property names\", with the pairing of a property name and a value often called a \"property\". This book will use those terms distinctly in that manner. |\n\nRegular JS objects are typically declared with literal syntax, like this:\n\n```js\nmyObj = {\n    // ..\n};\n```\n\n**Note:** There's an alternate way to create an object (using `myObj = new Object()`), but this is not common or preferred, and is almost never the appropriate way to go about it. Stick with object literal syntax.\n\nIt's easy to get confused what pairs of `{ .. }` mean, since JS overloads the curly brackets to mean any of the following, depending on the context used:\n\n* delimit values, like object literals\n* define object destructuring patterns (more on this later)\n* delimit interpolated string expressions, like `` `some ${ getNumber() } thing` ``\n* define blocks, like on `if` and `for` loops\n* define function bodies\n\nThough it can sometimes be challenging as you read code, look for whether a `{ .. }` curly brace pair is used in the program where a value/expression is valid to appear; if so, it's an object literal, otherwise it's one of the other overloaded uses.\n\n## Defining Properties\n\nInside the object literal curly braces, you define properties (name and value) with `propertyName: propertyValue` pairs, like this:\n\n```js\nmyObj = {\n    favoriteNumber: 42,\n    isDeveloper: true,\n    firstName: \"Kyle\"\n};\n```\n\nThe values you assign to the properties can be literals, as shown, or can be computed by expression:\n\n```js\nfunction twenty() { return 20; }\n\nmyObj = {\n    favoriteNumber: (twenty() + 1) * 2,\n};\n```\n\nThe expression `(twenty() + 1) * 2` is evaluated immediately, with the result (`42`) assigned as the property value.\n\nDevelopers sometimes wonder if there's a way to define an expression for a property value where the expression is \"lazy\", meaning it's not computed at the time of assignment, but defined later. JS does not have lazy expressions, so the only way to do so is for the expression to be wrapped in a function:\n\n```js\nfunction twenty() { return 20; }\nfunction myNumber() { return (twenty() + 1) * 2; }\n\nmyObj = {\n    favoriteNumber: myNumber   // notice, NOT `myNumber()` as a function call\n};\n```\n\nIn this case, `favoriteNumber` is not holding a numeric value, but rather a function reference. To compute the result, that function reference must be explicitly executed.\n\n### Looks Like JSON?\n\nYou may notice that this object-literal syntax we've seen thus far resembles a related syntax, \"JSON\" (JavaScript Object Notation):\n\n```json\n{\n    \"favoriteNumber\": 42,\n    \"isDeveloper\": true,\n    \"firstName\": \"Kyle\"\n}\n```\n\nThe biggest differences between JS's object literals and JSON are, for objects defined as JSON:\n\n1. property names must be quoted with `\"` double-quote characters\n\n2. property values must be literals (either primitives, objects, or arrays), not arbitrary JS expressions\n\nIn JS programs, an object literal does not require quoted property names -- you *can* quote them (`'` or `\"` allowed), but it's usually optional. There are however characters that are valid in a property name, but which cannot be included without surrounding quotes; for example, leading numbers or whitespace:\n\n```js\nmyObj = {\n    favoriteNumber: 42,\n    isDeveloper: true,\n    firstName: \"Kyle\",\n    \"2 nicknames\": [ \"getify\", \"ydkjs\" ]\n};\n```\n\nOne other minor difference is, JSON syntax -- that is, text that will be *parsed* as JSON, such as from a `.json` file -- is stricter than general JS. For example, JS allows comments (`// ..` and `/* .. */`), and trailing `,` commas in object and array expressions; JSON does not allow any of these. Thankfully, JSON does still allow arbitrary whitespace.\n\n### Property Names\n\nProperty names in object literals are almost always treated/coeced as string values. One exception to this is for integer (or \"integer looking\") property \"names\":\n\n```js\nanotherObj = {\n    42:       \"<-- this property name will be treated as an integer\",\n    \"41\":     \"<-- ...and so will this one\",\n\n    true:     \"<-- this property name will be treated as a string\",\n    [myObj]:  \"<-- ...and so will this one\"\n};\n```\n\nThe `42` property name will be treated as an integer property name (aka, index); the `\"41\"` string value will also be treated as such since it *looks like* an integer. By contrast, the `true` value will become the string property name `\"true\"`, and the `myObj` identifier reference, *computed* via the surrounding `[ .. ]`, will coerce the object's value to a string (generally the default `\"[object Object]\"`).\n\n| WARNING: |\n| :--- |\n| If you need to actually use an object as a key/property name, never rely on this computed string coercion; its behavior is surprising and almost certainly not what's expected, so program bugs are likely to occur. Instead, use a more specialized data structure, called a `Map` (added in ES6), where objects used as property \"names\" are left as-is instead of being coerced to a string value. |\n\nAs with `[myObj]` above, you can *compute* any **property name** (distinct from computing the property value) at the time of object literal definition:\n\n```js\nanotherObj = {\n    [\"x\" + (21 * 2)]: true\n};\n```\n\nThe expression `\"x\" + (21 * 2)`, which must appear inside of `[ .. ]` brackets, is computed immediately, and the result (`\"x42\"`) is used as the property name.\n\n### Symbols As Property Names\n\nES6 added a new primitive value type of `Symbol`, which is often used as a special property name for storing and retrieving property values. They're created via the `Symbol(..)` function call (**without** the `new` keyword), which accepts an optional description string used only for friendlier debugging purposes; if specified, the description is inaccessible to the JS program and thus not used for any other purpose than debug output.\n\n```js\nmyPropSymbol = Symbol(\"optional, developer-friendly description\");\n```\n\n| NOTE: |\n| :--- |\n| Symbols are sort of like numbers or strings, except that their value is *opaque* to, and globally unique within, the JS program. In other words, you can create and use symbols, but JS doesn't let you know anything about, or do anything with, the underlying value; that's kept as a hidden implementation detail by the JS engine. |\n\nComputed property names, as previously described, are how to define a symbol property name on an object literal:\n\n```js\nmyPropSymbol = Symbol(\"optional, developer-friendly description\");\n\nanotherObj = {\n    [myPropSymbol]: \"Hello, symbol!\"\n};\n```\n\nThe computed property name used to define the property on `anotherObj` will be the actual primitive symbol value (whatever it is), not the optional description string (`\"optional, developer-friendly description\"`).\n\nBecause symbols are globally unique in your program, there's **no** chance of accidental collision where one part of the program might accidentally define a property name the same as another part of the program tried defined/assigned.\n\nSymbols are also useful to hook into special default behaviors of objects, and we'll cover that in more detail in \"Extending the MOP\" in the next chapter.\n\n### Concise Properties\n\nWhen defining an object literal, it's common to use a property name that's the same as an existing in-scope identifier that holds the value you want to assign.\n\n```js\ncoolFact = \"the first person convicted of speeding was going 8 mph\";\n\nanotherObj = {\n    coolFact: coolFact\n};\n```\n\n| NOTE: |\n| :--- |\n| That would have been the same thing as the quoted property name definition `\"coolFact\": coolFact`, but JS developers rarely quote property names unless strictly necessary. Indeed, it's idiomatic to avoid the quotes unless required, so it's discouraged to include them unnecessarily. |\n\nIn this situation, where the property name and value expression identifier are identical, you can omit the property-name portion of the property definition, as a so-called \"concise property\" definition:\n\n```js\ncoolFact = \"the first person convicted of speeding was going 8 mph\";\n\nanotherObj = {\n    coolFact   // <-- concise property short-hand\n};\n```\n\nThe property name is `\"coolFact\"` (string), and the value assigned to the property is what's in the `coolFact` variable at that moment: `\"the first person convicted of speeding was going 8 mph\"`.\n\nAt first, this shorthand convenience may seem confusing. But as you get more familiar with seeing this very common and popular feature being used, you'll likely favor it for typing (and reading!) less.\n\n### Concise Methods\n\nAnother similar shorthand is defining functions/methods in an object literal using a more concise form:\n\n```js\nanotherObj = {\n    // standard function property\n    greet: function() { console.log(\"Hello!\"); },\n\n    // concise function/method property\n    greet2() { console.log(\"Hello, friend!\"); }\n};\n```\n\nWhile we're on the topic of concise method properties, we can also define generator functions (another ES6 feature):\n\n```js\nanotherObj = {\n    // instead of:\n    //   greet3: function*() { yield \"Hello, everyone!\"; }\n\n    // concise generator method\n    *greet3() { yield \"Hello, everyone!\"; }\n};\n```\n\nAnd though it's not particularly common, concise methods/generators can even have quoted or computed names:\n\n```js\nanotherObj = {\n    \"greet-4\"() { console.log(\"Hello, audience!\"); },\n\n    // concise computed name\n    [ \"gr\" + \"eet 5\" ]() { console.log(\"Hello, audience!\"); },\n\n    // concise computed generator name\n    *[ \"ok, greet 6\".toUpperCase() ]() { yield \"Hello, audience!\"; }\n};\n```\n\n### Object Spread\n\nAnother way to define properties at object literal creation time is with a form of the `...` syntax -- it's not technically an operator, but it certainly seems like one -- often referred to as \"object spread\".\n\nThe `...` when used inside an object literal will \"spread\" out the contents (properties, aka key/value pairs) of another object value into the object being defined:\n\n```js\nanotherObj = {\n    favoriteNumber: 12,\n\n    ...myObj,   // object spread, shallow copies `myObj`\n\n    greeting: \"Hello!\"\n}\n```\n\nThe spreading of `myObj`'s properties is shallow, in that it only copies the top-level properties from `myObj`; any values those properties hold are simply assigned over. If any of those values are references to other objects, the references themselves are assigned (by copy), but the underlying object values are *not* duplicated -- so you end up with multiple shared references to the same object(s).\n\nYou can think of object spreading like a `for` loop that runs through the properties one at a time and does an `=` style assignment from the source object (`myObj`) to the target object (`anotherObj`).\n\nAlso, consider these property definition operations to happen \"in order\", from top to bottom of the object literal. In the above snippet, since `myObj` has a `favoriteNumber` property, the object spread will end up overwriting the `favoriteNumber: 12` property assignment from the previous line. Moreover, if `myObj` had contained a `greeting` property that was copied over, the next line (`greeting: \"Hello!\"`) would override that property definition.\n\n| NOTE: |\n| :--- |\n| Object spread also only copies *owned* properties (those directly on the object) that are *enumerable* (allowed to be enumerated/listed). It does not duplicate the property -- as in, actually mimic the property's exact characteristics -- but rather do a simple assignment style copy. We'll cover more such details in the \"Property Descriptors\" section of the next chapter. |\n\nA common way `...` object spread is used is for performing *shallow* object duplication:\n\n```js\nmyObjShallowCopy = { ...myObj };\n```\n\nKeep in mind you cannot `...` spread into an existing object value; the `...` object spread syntax can only appear inside the `{ .. }` object literal, which is creating a new object value. To perform a similar shallow object copy but with APIs instead of syntax, see the \"Object Entries\" section later in this chapter (with coverage of `Object.entries(..)` and `Object.fromEntries(..)`).\n\nBut if you instead want to copy object properties (shallowly) into an *existing* object, see the \"Assigning Properties\" section later in this chapter (with coverage of `Object.assign(..)`).\n\n### Deep Object Copy\n\nAlso, since `...` doesn't do full, deep object duplication, the object spread is generally only suitable for duplicating objects that hold simple, primitive values only, not references to other objects.\n\nDeep object duplication is an incredibly complex and nuanced operation. Duplicating a value like `42` is obvious and straightforward, but what does it mean to copy a function (which is a special kind of object, also held by reference), or to copy an external (not entirely in JS) object reference, such as a DOM element? And what happens if an object has circular references (like where a nested descendant object holds a reference back up to an outer ancestor object)? There's a variety of opinions in the wild about how all these corner cases should be handled, and thus no single standard exists for deep object duplication.\n\nFor deep object duplication, the standard approaches have been:\n\n1. Use a library utility that declares a specific opinion on how the duplication behaviors/nuances should be handled.\n\n2. Use the `JSON.parse(JSON.stringify(..))` round-trip trick -- this only \"works\" correctly if there are no circular references, and if there are no values in the object that cannot be properly serialized with JSON (such as functions).\n\nRecently, though, a third option has landed. This is not a JS feature, but rather a companion API provided to JS by environments like the web platform. Objects can be deep copied now using `structuredClone(..)`[^structuredClone].\n\n```js\nmyObjCopy = structuredClone(myObj);\n```\n\nThe underlying algorithm behind this built-in utility supports duplicating circular references, as well as **many more** types of values than the `JSON` round-trip trick. However, this algorithm still has its limits, including no support for cloning functions or DOM elements.\n\n## Accessing Properties\n\nProperty access of an existing object is preferably done with the `.` operator:\n\n```js\nmyObj.favoriteNumber;    // 42\nmyObj.isDeveloper;       // true\n```\n\nIf it's possible to access a property this way, it's strongly suggested to do so.\n\nIf the property name contains characters that cannot appear in identifiers, such as leading numbers or whitespace, `[ .. ]` brackets can be used instead of the `.`:\n\n```js\nmyObj[\"2 nicknames\"];    // [ \"getify\", \"ydkjs\" ]\n```\n\n```js\nanotherObj[42];          // \"<-- this property name will...\"\nanotherObj[\"41\"];        // \"<-- this property name will...\"\n```\n\nEven though numeric property \"names\" remain as numbers, property access via the `[ .. ]` brackets will coerce a string representation to a number (e.g., `\"42\"` as the `42` numeric equivalent), and then access the associated numeric property accordingly.\n\nSimilar to the object literal, the property name to access can be computed via the `[ .. ]` brackets. The expression can be a simple identifier:\n\n```js\npropName = \"41\";\nanotherObj[propName];\n```\n\nActually, what you put between the `[ .. ]` brackets can be any arbitrary JS expression, not just identifiers or literal values like `42` or `\"isDeveloper\"`. JS will first evaluate the expression, and the resulting value will then be used as the property name to look up on the object:\n\n```js\nfunction howMany(x) {\n    return x + 1;\n}\n\nmyObj[`${ howMany(1) } nicknames`];   // [ \"getify\", \"ydkjs\" ]\n```\n\nIn this snippet, the expression is a back-tick delimited `` `template string literal` `` with an interpolated expression of the function call `howMany(1)`. The overall result of that expression is the string value `\"2 nicknames\"`, which is then used as the property name to access.\n\n### Object Entries\n\nYou can get a listing of the properties in an object, as an array of tuples (two-element sub-arrays) holding the property name and value:\n\n```js\nmyObj = {\n    favoriteNumber: 42,\n    isDeveloper: true,\n    firstName: \"Kyle\"\n};\n\nObject.entries(myObj);\n// [ [\"favoriteNumber\",42], [\"isDeveloper\",true], [\"firstName\",\"Kyle\"] ]\n```\n\nAdded in ES6, `Object.entries(..)` retrieves this list of entries -- containing only owned an enumerable properties; see the \"Property Descriptors\" section in the next chapter -- from a source object.\n\nSuch a list can be looped/iterated over, potentially assigning properties to another existing object. However, it's also possible to create a new object from a list of entries, using `Object.fromEntries(..)` (added in ES2019):\n\n```js\nmyObjShallowCopy = Object.fromEntries( Object.entries(myObj) );\n\n// alternate approach to the earlier discussed:\n// myObjShallowCopy = { ...myObj };\n```\n\n### Destructuring\n\nAnother approach to accessing properties is through object destructuring (added in ES6). Think of destructuring as defining a \"pattern\" that describes what an object value is supposed to \"look like\" (structurally), and then asking JS to follow that \"pattern\" to systematically access the contents of an object value.\n\nThe end result of object destructuring is not another object, but rather one or more assignments to other targets (variables, etc) of the values from the source object.\n\nImagine this sort of pre-ES6 code:\n\n```js\nmyObj = {\n    favoriteNumber: 42,\n    isDeveloper: true,\n    firstName: \"Kyle\"\n};\n\nconst favoriteNumber = (\n    myObj.favoriteNumber !== undefined ? myObj.favoriteNumber : 42\n);\nconst isDev = myObj.isDeveloper;\nconst firstName = myObj.firstName;\nconst lname = (\n    myObj.lastName !== undefined ? myObj.lastName : \"--missing--\"\n);\n```\n\nThose accesses of the property values, and assignments to other identifiers, is generally called \"manual destructuring\". To use the declarative object destructuring syntax, it might look like this:\n\n```js\nmyObj = {\n    favoriteNumber: 42,\n    isDeveloper: true,\n    firstName: \"Kyle\"\n};\n\nconst { favoriteNumber = 12 } = myObj;\nconst {\n    isDeveloper: isDev,\n    firstName: firstName,\n    lastName: lname = \"--missing--\"\n} = myObj;\n\nfavoriteNumber;   // 42\nisDev;            // true\nfirstName;        // \"Kyle\"\nlname;            // \"--missing--\"\n```\n\nAs shown, the `{ .. }` object destucturing resembles an object literal value definition, but it appears on the left-hand side of the `=` operator rather than on the right-hand side where an object value expression would appear. That makes the `{ .. }` on the left-hand side a destructuring pattern rather than another object definition.\n\nThe `{ favoriteNumber } = myObj` destructuring tells JS to find a property named `favoriteNumber` on the object, and to assign its value to an identifier of the same name. The single instance of the `favoriteNumber` identifier in the pattern is similar to \"concise properties\" as discussed earlier in this chapter: if the source (property name) and target (identifier) are the same, you can omit one of them and only list it once.\n\nThe `= 12` part tells JS to provide `12` as a default value for the assignment to `favoriteNumber`, if the source object either doesn't have a `favoriteNumber` property, or if the property holds an `undefined` value.\n\nIn the second destructuring pattern, the `isDeveloper: isDev` pattern is instructing JS to find a property named `isDeveloper` on the source object, and assign its value to an identifier named `isDev`. It's sort of a \"renaming\" of the source to the target. By contrast, `firstName: firstName` is providing the source and target for an assignment, but is redundant since they're identical; a single `firstName` would have sufficed here, and is generally more preferred.\n\nThe `lastName: lname = \"--missing--\"` combines both source-target renaming and a default value (if the `lastName` source property is missing or `undefined`).\n\nThe above snippet combines object destructuring with variable declarations -- in this example, `const` is used, but `var` and `let` work as well -- but it's not inherently a declaration mechanism. Destructuring is about access and assignment (source to target), so it can operate against existing targets rather than declaring new ones:\n\n```js\nlet fave;\n\n// surrounding ( ) are required syntax here,\n// when a declarator is not used\n({ favoriteNumber: fave } = myObj);\n\nfave;  // 42\n```\n\nObject destructuring syntax is generally preferred for its declarative and more readable style, over the heavily imperative pre-ES6 equivalents. But don't go overboard with destructuring. Sometimes just doing `x = someObj.x` is perfectly fine!\n\n### Conditional Property Access\n\nRecently (in ES2020), a feature known as \"optional chaining\" was added to JS, which augments property access capabilities (especially nested property access). The primary form is the two-character compound operator `?.`, like `A?.B`.\n\nThis operator will check the left-hand side reference (`A`) to see if it's null'ish (`null` or `undefined`). If so, the rest of the property access expression is short-circuited (skipped), and `undefined` is returned as the result (even if it was `null` that was actually encountered!). Otherwise, `?.` will access the property just as a normal `.` operator would.\n\nFor example:\n\n```js\nmyObj?.favoriteNumber\n```\n\nHere, the null'ish check is performed against the `myObj`, meaning that the `favoriteNumber` property access is only performed if the value in `myObj` is non-null'ish. Note that it doesn't verify that `myObj` is actually holding a real object, only that it's non-nullish. However, all non-nullish values can \"safely\" (no JS exception) be \"accessed\" via the `.` operator, even if there's no matching property to retrieve.\n\nIt's easy to get confused into thinking that the null'ish check is against the `favoriteNumber` property. But one way to keep it straight is to remember that the `?` is on the side where the safety check is performed, while the `.` is on the side that is only conditionally evaluated if the non-null'ish check passes.\n\nTypically, the `?.` operator is used in nested property accesses that may be 3 or more levels deep, such as:\n\n```js\nmyObj?.address?.city\n```\n\nThe equivalent operation with the `?.` operator would look like this:\n\n```js\n(myObj != null && myObj.address != null) ? myObj.address.city : undefined\n```\n\nAgain, remember that no check has been performed against the right-most property (`city`) here.\n\nAlso, the `?.` should not universally be used in place of every single `.` operator in your programs. You should endeavor to know if a `.` property access will succeed or not before making the access, whenever possible. Use `?.` only when the nature of the values being accessed is subject to conditions that cannot be predicted/controlled.\n\nFor example, in the previous snippet, the `myObj?.` usage is probably mis-guided, because it really shouldn't be the case that you start a chain of property access against a variable that might not even hold a top-level object (aside from its contents potentially missing certain properties in certain conditions).\n\nInstead, I would recommend usage more like this:\n\n```js\nmyObj.address?.city\n```\n\nAnd that expression should only be used in part of your program where you're sure that `myObj` is at least holding a valid object (whether or not it has an `address` property with a sub-object in it).\n\nAnother form of the \"optional chaining\" operator is `?.[`, which is used when the property access you want to make conditional/safe requires a `[ .. ]` bracket.\n\n```js\nmyObj[\"2 nicknames\"]?.[0];   // \"getify\"\n```\n\nEverything asserted about how `?.` behaves goes the same for `?.[`.\n\n| WARNING: |\n| :--- |\n| There's a third form of this feature, named \"optional call\", which uses `?.(` as the operator. It's used for performing a non-null'ish check on a property before executing the function value in the property. For example, instead of `myObj.someFunc(42)`, you can do `myObj.someFunc?.(42)`. The `?.(` checks to make sure `myObj.someFunc` is non-null'ish before invoking it (with the `(42)` part). While that may sound like a useful feature, I think this is dangerous enough to warrant complete avoidance of this form/construct.<br><br>My concern is that `?.(` makes it seem as if we're ensuring that the function is \"callable\" before calling it, when in fact we're only checking if it's non-null'ish. Unlike `?.` which can allow a \"safe\" `.` access against a non-null'ish value that's also not an object, the `?.(` non-null'ish check isn't similarly \"safe\". If the property in question has any non-null'ish, non-function value in it, like `true` or `\"Hello\"`, the `(42)` call part will be invoked and yet throw a JS exception. So in other words, this form is unfortunately masquerading as more \"safe\" than it actually is, and should thus be avoided in essentially all circumstances. If a property value can ever *not be* a function, do a more fullsome check for its function'ness before trying to invoke it. Don't pretend that `?.(` is doing that for you, or future readers/maintainers of your code (including your future self!) will likely regret it. |\n\n### Accessing Properties On Non-Objects\n\nThis may sound counter-intuitive, but you can generally access properties/methods from values that aren't themselves objects:\n\n```js\nfave = 42;\n\nfave;              // 42\nfave.toString();   // \"42\"\n```\n\nHere, `fave` holds a primitive `42` number value. So how can we do `.toString` to access a property from it, and then `()` to invoke the function held in that property?\n\nThis is a tremendously more indepth topic than we'll get into in this book; see book 4, \"Types & Grammar\", of this series for more. However, as a quick glimpse: if you perform a property access (`.` or `[ .. ]`) against a non-object, non-null'ish value, JS will by default (temporarily!) coerce the value into an object-wrapped representation, allowing the property access against that implicitly instantiated object.\n\nThis process is typically called \"boxing\", as in putting a value inside a \"box\" (object container).\n\nSo in the above snippet, just for the moment that `.toString` is being accessed on the `42` value, JS will box this value into a `Number` object, and then perform the property access.\n\nNote that `null` and `undefined` can be object-ified, by calling `Object(null)` / `Object(undefined)`. However, JS does not automatically box these null'ish values, so property access against them will fail (as discussed earlier in the \"Conditional Property Access\" section).\n\n| NOTE: |\n| :--- |\n| Boxing has a counterpart: unboxing. For example, the JS engine will take an object wrapper -- like a `Number` object wrapped around `42` -- created with `Number(42)` or `Object(42)` -- and unwrap it to retrieve the underlying primitive `42`, whenever a mathematical operation (like `*` or `-`) encounters such an object. Unboxing behavior is way out of scope for our discussion, but is covered fully in the aforementioned \"Types & Grammar\" title. |\n\n## Assigning Properties\n\nWhether a property is defined at the time of object literal definition, or added later, the assignment of a property value is done with the `=` operator, as any other normal assignment would be:\n\n```js\nmyObj.favoriteNumber = 123;\n```\n\nIf the `favoriteNumber` property doesn't already exist, that statement will create a new property of that name and assign its value. But if it already exists, that statement will re-assign its value.\n\n| WARNING: |\n| :--- |\n| An `=` assignment to a property may fail (silently or throwing an exception), or it may not directly assign the value but instead invoke a *setter* function that performs some operation(s). More details on these behaviors in the next chapter. |\n\nIt's also possible to assign one or more properties at once -- assuming the source properties (name and value pairs) are in another object -- using the `Object.assign(..)` (added in ES6) method:\n\n```js\n// shallow copy all (owned and enumerable) properties\n// from `myObj` into `anotherObj`\nObject.assign(anotherObj,myObj);\n\nObject.assign(\n    /*target=*/anotherObj,\n    /*source1=*/{\n        someProp: \"some value\",\n        anotherProp: 1001,\n    },\n    /*source2=*/{\n        yetAnotherProp: false\n    }\n);\n```\n\n`Object.assign(..)` takes the first object as target, and the second (and optionally subsequent) object(s) as source(s). Copying is done in the same manner as described earlier in the \"Object Spread\" section.\n\n## Deleting Properties\n\nOnce a property is defined on an object, the only way to remove it is with the `delete` operator:\n\n```js\nanotherObj = {\n    counter: 123\n};\n\nanotherObj.counter;   // 123\n\ndelete anotherObj.counter;\n\nanotherObj.counter;   // undefined\n```\n\nContrary to common misconception, the JS `delete` operator does **not** directly do any deallocation/freeing up of memory, through garbage collection (GC). The only thing it does is remove a property from an object. If the value in the property was a reference (to another object/etc), and there are no other surviving references to that value once the property is removed, that value would likely then be eligible for removal in a future sweep of the GC.\n\nCalling `delete` on anything other than an object property is a misuse of the `delete` operator, and will either fail silently (in non-strict mode) or throw an exception (in strict mode).\n\nDeleting a property from an object is distinct from assigning it a value like `undefined` or `null`. A property assigned `undefined`, either initially or later, is still present on the object, and might still be revealed when enumerating the contents\n\n## Determining Container Contents\n\nYou can determine an object's contents in a variety of ways. To ask an object if it has a specific property:\n\n```js\nmyObj = {\n    favoriteNumber: 42,\n    coolFact: \"the first person convicted of speeding was going 8 mph\",\n    beardLength: undefined,\n    nicknames: [ \"getify\", \"ydkjs\" ]\n};\n\n\"favoriteNumber\" in myObj;            // true\n\nmyObj.hasOwnProperty(\"coolFact\");     // true\nmyObj.hasOwnProperty(\"beardLength\");  // true\n\nmyObj.nicknames = undefined;\nmyObj.hasOwnProperty(\"nicknames\");    // true\n\ndelete myObj.nicknames;\nmyObj.hasOwnProperty(\"nicknames\");    // false\n```\n\nThere *is* an important difference between how the `in` operator and the `hasOwnProperty(..)` method behave. The `in` operator will check not only the target object specified, but if not found there, it will also consult the object's `[[Prototype]]` chain (covered in the next chapter). By contrast, `hasOwnProperty(..)` only consults the target object.\n\nIf you're paying close attention, you may have noticed that `myObj` appears to have a method property called `hasOwnProperty(..)` on it, even though we didn't define such. That's because `hasOwnProperty(..)` is defined as a built-in on `Object.prototype`, which by default is \"inherited by\" all normal objects. There is risk inherent to accessing such an \"inherited\" method, though. Again, more on prototypes in the next chapter.\n\n### Better Existence Check\n\nES2022 (almost official at time of writing) has already settled on a new feature, `Object.hasOwn(..)`. It does essentially the same thing as `hasOwnProperty(..)`, but it's invoked as a static helper external to the object value instead of via the object's `[[Prototype]]`, making it safer and more consistent in usage:\n\n```js\n// instead of:\nmyObj.hasOwnProperty(\"favoriteNumber\")\n\n// we should now prefer:\nObject.hasOwn(myObj,\"favoriteNumber\")\n```\n\nEven though (at time of writing) this feature is just now emerging in JS, there are polyfills that make this API available in your programs even when running in a previous JS environment that doesn't yet have the feature defined. For example, a quick stand-in polyfill sketch:\n\n```js\n// simple polyfill sketch for `Object.hasOwn(..)`\nif (!Object.hasOwn) {\n    Object.hasOwn = function hasOwn(obj,propName) {\n        return Object.prototype.hasOwnProperty.call(obj,propName);\n    };\n}\n```\n\nIncluding a polyfill patch such as that in your program means you can safely start using `Object.hasOwn(..)` for property existence checks no matter whether a JS environment has `Object.hasOwn(..)` built in yet or not.\n\n### Listing All Container Contents\n\nWe already discussed the `Object.entries(..)` API earlier, which tells us what properties an object has (as long as they're enumerable -- more in the next chapter).\n\nThere's a variety of other mechanisms available, as well. `Object.keys(..)` gives us list of the enumerable property names (aka, keys) in an object -- names only, no values; `Object.values(..)` instead gives us list of all values held in enumerable properties.\n\nBut what if we wanted to get *all* the keys in an object (enumerable or not)? `Object.getOwnPropertyNames(..)` seems to do what we want, in that it's like `Object.keys(..)` but also returns non-enumerable property names. However, this list **will not** include any Symbol property names, as those are treated as special locations on the object. `Object.getOwnPropertySymbols(..)` returns all of an object's Symbol properties. So if you concatenate both of those lists together, you'd have all the direct (*owned*) contents of an object.\n\nYet as we've implied several times already, and will cover in full detail in the next chapter, an object can also \"inherit\" contents from its `[[Prototype]]` chain. These are not considered *owned* contents, so they won't show up in any of these lists.\n\nRecall that the `in` operator will potentially traverse the entire chain looking for the existence of a property. Similarly, a `for..in` loop will traverse the chain and list any enumerable (owned or inherited) properties. But there's no built-in API that will traverse the whole chain and return a list of the combined set of both *owned* and *inherited* contents.\n\n## Temporary Containers\n\nUsing a container to hold multiple values is sometimes just a temporary transport mechanism, such as when you want to pass multiple values to a function via a single argument, or when you want a function to return multiple values:\n\n```js\nfunction formatValues({ one, two, three }) {\n    // the actual object passed in as an\n    // argument is not accessible, since\n    // we destructured it into three\n    // separate variables\n\n    one = one.toUpperCase();\n    two = `--${two}--`;\n    three = three.substring(0,5);\n\n    // this object is only to transport\n    // all three values in a single\n    // return statement\n    return { one, two, three };\n}\n\n// destructuring the return value from\n// the function, because that returned\n// object is just a temporary container\n// to transport us multiple values\nconst { one, two, three } =\n\n    // this object argument is a temporary\n    // transport for multiple input values\n    formatValues({\n       one: \"Kyle\",\n       two: \"Simpson\",\n       three: \"getify\"\n    });\n\none;     // \"KYLE\"\ntwo;     // \"--Simpson--\"\nthree;   // \"getif\"\n```\n\nThe object literal passed into `formatValues(..)` is immediately parameter destructured, so inside the function we only deal with three separate variables (`one`, `two`, and `three`). The object literal `return`ed from the function is also immediately destructured, so again we only deal with three separate variables (`one`, `two`, `three`).\n\nThis snippet illustrates the idiom/pattern that an object is sometimes just a temporary transport container rather than a meaningful value in and of itself.\n\n## Containers Are Collections Of Properties\n\nThe most common usage of objects is as containers for multiple values. We create and manage property container objects by:\n\n* defining properties (named locations), either at object creation time or later\n* assigning values, either at object creation time or later\n* accessing values later, using the location names (property names)\n* deleting properties via `delete`\n* determining container contents with `in`, `hasOwnProperty(..)` / `hasOwn(..)`, `Object.entries(..)` / `Object.keys(..)`, etc\n\nBut there's a lot more to objects than just static collections of property names and values. In the next chapter, we'll dive under the hood to look at how they actually work.\n\n[^structuredClone]: \"Structured Clone Algorithm\", HTML Specification; https://html.spec.whatwg.org/multipage/structured-data.html#structured-cloning ; Accessed July 2022\n"
  },
  {
    "path": "objects-classes/ch2.md",
    "content": "# You Don't Know JS Yet: Objects & Classes - 2nd Edition\n# Chapter 2: How Objects Work\n\n| NOTE: |\n| :--- |\n| Work in progress |\n\nObjects are not just containers for multiple values, though clearly that's the context for most interactions with objects.\n\nTo fully understand the object mechanism in JS, and get the most out of using objects in our programs, we need to look more closely at a number of characteristics of objects (and their properties) which can affect their behavior when interacting with them.\n\nThese characteristics that define the underlying behavior of objects are collectively referred to in formal terms as the \"metaobject protocol\" (MOP)[^mop]. The MOP is useful not only for understanding how objects will behave, but also for overriding the default behaviors of objects to bend the language to fit our program's needs more fully.\n\n## Property Descriptors\n\nEach property on an object is internally described by what's known as a \"property descriptor\". This is, itself, an object (aka, \"metaobject\") with several properties (aka \"attributes\") on it, dictating how the target property behaves.\n\nWe can retrieve a property descriptor for any existing property using `Object.getOwnPropertyDescriptor(..)` (ES5):\n\n```js\nmyObj = {\n    favoriteNumber: 42,\n    isDeveloper: true,\n    firstName: \"Kyle\"\n};\n\nObject.getOwnPropertyDescriptor(myObj,\"favoriteNumber\");\n// {\n//     value: 42,\n//     enumerable: true,\n//     writable: true,\n//     configurable: true\n// }\n```\n\nWe can even use such a descriptor to define a new property on an object, using `Object.defineProperty(..)` (ES5):\n\n```js\nanotherObj = {};\n\nObject.defineProperty(anotherObj,\"fave\",{\n    value: 42,\n    enumerable: true,     // default if omitted\n    writable: true,       // default if omitted\n    configurable: true    // default if omitted\n});\n\nanotherObj.fave;          // 42\n```\n\nIf an existing property has not already been marked as non-configurable (with `configurable: false` in its descriptor), it can always be re-defined/overwritten using `Object.defineProperty(..)`.\n\n| WARNING: |\n| :--- |\n| A number of earlier sections in this chapter refer to \"copying\" or \"duplicating\" properties. One might assume such copying/duplication would be at the property descriptor level. However, none of those operations actually work that way; they all do simple `=` style access and assignment, which has the effect of ignoring any nuances in how the underlying descriptor for a property is defined. |\n\nThough it seems far less common out in the wild, we can even define multiple properties at once, each with their own descriptor:\n\n```js\nanotherObj = {};\n\nObject.defineProperties(anotherObj,{\n    \"fave\": {\n        // a property descriptor\n    },\n    \"superFave\": {\n        // another property descriptor\n    }\n});\n```\n\nIt's not very common to see this usage, because it's rarer that you need to specifically control the definition of multiple properties. But it may be useful in some cases.\n\n### Accessor Properties\n\nA property descriptor usually defines a `value` property, as shown above. However, a special kind of property, known as an \"accessor property\" (aka, a getter/setter), can be defined. For these a property like this, its descriptor does not define a fixed `value` property, but would instead look something like this:\n\n```js\n{\n    get() { .. },    // function to invoke when retrieving the value\n    set(v) { .. },   // function to invoke when assigning the value\n    // .. enumerable, etc\n}\n```\n\nA getter looks like a property access (`obj.prop`), but under the covers it invokes the `get()` method as defined; it's sort of like if you had called `obj.prop()`. A setter looks like a property assignment (`obj.prop = value`), but it invokes the `set(..)` method as defined; it's sort of like if you had called `obj.prop(value)`.\n\nLet's illustrate a getter/setter accessor property:\n\n```js\nanotherObj = {};\n\nObject.defineProperty(anotherObj,\"fave\",{\n    get() { console.log(\"Getting 'fave' value!\"); return 123; },\n    set(v) { console.log(`Ignoring ${v} assignment.`); }\n});\n\nanotherObj.fave;\n// Getting 'fave' value!\n// 123\n\nanotherObj.fave = 42;\n// Ignoring 42 assignment.\n\nanotherObj.fave;\n// Getting 'fave' value!\n// 123\n```\n\n### Enumerable, Writable, Configurable\n\nBesides `value` or `get()` / `set(..)`, the other 3 attributes of a property descriptor are (as shown above):\n\n* `enumerable`\n* `writable`\n* `configurable`\n\nThe `enumerable` attribute controls whether the property will appear in various enumerations of object properties, such as `Object.keys(..)`, `Object.entries(..)`, `for..in` loops, and the copying that occurs with the `...` object spread and `Object.assign(..)`. Most properties should be left enumerable, but you can mark certain special properties on an object as non-enumerable if they shouldn't be iterated/copied.\n\nThe `writable` attribute controls whether a `value` assignment (via `=`) is allowed. To make a property \"read only\", define it with `writable: false`. However, as long as the property is still configurable, `Object.defineProperty(..)` can still change the value by setting `value` differently.\n\nThe `configurable` attribute controls whether a property's **descriptor** can be re-defined/overwritten. A property that's `configurable: false` is locked to its definition, and any further attempts to change it with `Object.defineProperty(..)` will fail. A non-configurable property can still be assigned new values (via `=`), as long as `writable: true` is still set on the property's descriptor.\n\n## Object Sub-Types\n\nThere are a variety of specialized sub-types of objects in JS. But by far, the two most common ones you'll interact with are arrays and `function`s.\n\n| NOTE: |\n| :--- |\n| By \"sub-type\", we mean the notion of a derived type that has inherited the behaviors from a parent type but then specialized or extended those behaviors. In other words, values of these sub-types are fully objects, but are also *more than just* objects. |\n\n### Arrays\n\nArrays are objects that are specifically intended to be **numerically indexed**, rather than using string named property locations. They are still objects, so a named property like `favoriteNumber` is legal. But it's greatly frowned upon to mix named properties into numerically indexed arrays.\n\nArrays are preferably defined with literal syntax (similar to objects), but with the `[ .. ]` square brackets rather than `{ .. }` curly brackets:\n\n```js\nmyList = [ 23, 42, 109 ];\n```\n\nJS allows any mixture of value types in arrays, including objects, other arrays, functions, etc. As you're likely already aware, arrays are \"zero-indexed\", meaning the first element in the array is at the index `0`, not `1`:\n\n```js\nmyList = [ 23, 42, 109 ];\n\nmyList[0];      // 23\nmyList[1];      // 42\n```\n\nRecall that any string property name on an object that \"looks like\" an integer -- is able to be validly coerced to a numeric integer -- will actually be treated like an integer property (aka, integer index). The same goes for arrays. You should always use `42` as an integer index (aka, property name), but if you use the string `\"42\"`, JS will assume you meant that as an integer and do that for you.\n\n```js\n// \"2\" works as an integer index here, but it's not advised\nmyList[\"2\"];    // 109\n```\n\nOne exception to the \"no named properties on arrays\" *rule* is that all arrays automatically expose a `length` property, which is automatically kept updated with the \"length\" of the array.\n\n```js\nmyList = [ 23, 42, 109 ];\n\nmyList.length;   // 3\n\n// \"push\" another value onto the end of the list\nmyList.push(\"Hello\");\n\nmyList.length;   // 4\n```\n\n| WARNING: |\n| :--- |\n| Many JS developers incorrectly believe that array `length` is basically a *getter* (see \"Accessor Properties\" earlier in this chapter), but it's not. The offshoot is that these developers feel like it's \"expensive\" to access this property -- as if JS has to on-the-fly recompute the length -- and will thus do things like capture/store the length of an array before doing a non-mutating loop over it. This used to be \"best practice\" from a performance perspective. But for at least 10 years now, that's actually been an anti-pattern, because the JS engine is more efficient at managing the `length` property than our JS code is at trying to \"outsmart\" the engine to avoid invoking something we think is a *getter*. It's more efficient to let the JS engine do its job, and just access the property whenever and however often it's needed. |\n\n#### Empty Slots\n\nJS arrays also have a really unfortunate \"flaw\" in their design, referred to as \"empty slots\". If you assign an index of an array more than one position beyond the current end of the array, JS will leave the in between slots \"empty\" rather than auto-assigning them to `undefined` as you might expect:\n\n```js\nmyList = [ 23, 42, 109 ];\nmyList.length;              // 3\n\nmyList[14] = \"Hello\";\nmyList.length;              // 15\n\nmyList;                     // [ 23, 42, 109, empty x 11, \"Hello\" ]\n\n// looks like a real slot with a\n// real `undefined` value in it,\n// but beware, it's a trick!\nmyList[9];                  // undefined\n```\n\nYou might wonder why empty slots are so bad? One reason: there are APIs in JS, like array's `map(..)`, where empty slots are surprisingly skipped over! Never, ever intentionally create empty slots in your arrays. This in undebateably one of JS's \"bad parts\".\n\n### Functions\n\nI don't have much specifically to say about functions here, other than to point out that they are also sub-object-types. This means that in addition to being executable, they can also have named properties added to or accessed from them.\n\nFunctions have two pre-defined properties you may find yourself interacting with, specifically for meta-programming purposes:\n\n```js\nfunction help(opt1,opt2,...remainingOpts) {\n    // ..\n}\n\nhelp.name;          // \"help\"\nhelp.length;        // 2\n```\n\nThe `length` of a function is the count of its explicitly defined parameters, up to but not including a parameter that either has a default value defined (e.g., `param = 42`) or a \"rest parameter\" (e.g., `...remainingOpts`).\n\n#### Avoid Setting Function-Object Properties\n\nYou should avoid assigning properties on function objects. If you're looking to store extra information associated with a function, use a separate `Map(..)` (or `WeakMap(..)`) with the function object as the key, and the extra information as the value.\n\n```js\nextraInfo = new Map();\n\nextraInfo.set(help,\"this is some important information\");\n\n// later:\nextraInfo.get(help);   // \"this is some important information\"\n```\n\n## Object Characteristics\n\nIn addition to defining behaviors for specific properties, certain behaviors are configurable across the whole object:\n\n* extensible\n* sealed\n* frozen\n\n### Extensible\n\nExtensibility refers to whether an object can have new properties defined/added to it. By default, all objects are extensible, but you can change shut off extensibility for an object:\n\n```js\nmyObj = {\n    favoriteNumber: 42\n};\n\nmyObj.firstName = \"Kyle\";                  // works fine\n\nObject.preventExtensions(myObj);\n\nmyObj.nicknames = [ \"getify\", \"ydkjs\" ];   // fails\nmyObj.favoriteNumber = 123;                // works fine\n```\n\nIn non-strict-mode, an assignment that creates a new property will silently fail, whereas in strict mode an exception will be thrown.\n\n### Sealed\n\n// TODO\n\n### Frozen\n\n// TODO\n\n## Extending The MOP\n\nAs mentioned at the start of this chapter, objects in JS behave according to a set of rules referred to as the Metaobject Protocol (MOP)[^mop]. Now that we understand more fully how objects work by default, we want to turn our attention to how we can hook into some of these default behaviors and override/customize them.\n\n// TODO\n\n## `[[Prototype]]` Chain\n\nOne of the most important, but least obvious, characteristics of an object (part of the MOP) is referred to as its \"prototype chain\"; the official JS specification notation is `[[Prototype]]`. Make sure not to confuse this `[[Prototype]]` with a public property named `prototype`. Despite the naming, these are distinct concepts.\n\nThe `[[Prototype]]` is an internal linkage that an object gets by default when its created, pointing to another object. This linkage is a hidden, often subtle characteristic of an object, but it has profound impacts on how interactions with the object will play out. It's referred to as a \"chain\" because one object links to another, which in turn links to another, ... and so on. There is an *end* or *top* to this chain, where the linkage stops and there's no further to go. More on that shortly.\n\nWe already saw several implications of `[[Prototype]]` linkage in Chapter 1. For example, by default, all objects are `[[Prototype]]`-linked to the built-in object named `Object.prototype`.\n\n| WARNING: |\n| :--- |\n| That `Object.prototype` name itself can be confusing, since it uses a property called `prototype`. How are `[[Prototype]]` and `prototype` related!? Put such questions/confusion on pause for a bit, as we'll come back an explain the differences between `[[Prototype]]` and `prototype` later in this chapter. For the moment, just assume the presence of this important but weirdly named built-in object, `Object.prototype`. |\n\nLet's consider some code:\n\n```js\nmyObj = {\n    favoriteNumber: 42\n};\n```\n\nThat should look familiar from Chapter 1. But what you *don't see* in this code is that the object there was automatically linked (via its internal `[[Prototype]]`) to that automatically built-in, but weirdly named, `Object.prototype` object.\n\nWhen we do things like:\n\n```js\nmyObj.toString();                             // \"[object Object]\"\n\nmyObj.hasOwnProperty(\"favoriteNumber\");   // true\n```\n\nWe're taking advantage of this internal `[[Prototype]]` linkage, without really realizing it. Since `myObj` does not have `toString` or `hasOwnProperty` properties defined on it, those property accesses actually end up **DELEGATING** the access to continue its lookup along the `[[Prototype]]` chain.\n\nSince `myObj` is `[[Prototype]]`-linked to the object named `Object.prototype`, the lookup for `toString` and `hasOwnProperty` properties continues on that object; and indeed, these methods are found there!\n\nThe ability for `myObj.toString` to access the `toString` property even though it doesn't actually have it, is commonly referred to as \"inheritance\", or more specifically, \"prototypal inheritance\". The `toString` and `hasOwnProperty` properties, along with many others, are said to be \"inherited properties\" on `myObj`.\n\n| NOTE: |\n| :--- |\n| I have a lot of frustrations with the usage of the word \"inheritance\" here -- it should be called \"delegation\"! --  but that's what most people refer to it as, so we'll begrudgingly comply and use that same terminology for now (albeit under protest, with \" quotes). I'll save my objections for an appendix of this book. |\n\n`Object.prototype` has several built-in properties and methods, all of which are \"inherited\" by any object that is `[[Prototype]]`-linked, either directly or indirectly through another object's linkage, to `Object.prototype`.\n\nSome common \"inherited\" properties from `Object.prototype` include:\n\n* `constructor`\n* `__proto__`\n* `toString()`\n* `valueOf()`\n* `hasOwnProperty(..)`\n* `isPrototypeOf(..)`\n\nRecall `hasOwnProperty(..)`, which we saw earlier gives us a boolean check for whether a certain property (by string name) is owned by an object:\n\n```js\nmyObj = {\n    favoriteNumber: 42\n};\n\nmyObj.hasOwnProperty(\"favoriteNumber\");   // true\n```\n\nIt's always been considered somewhat unfortunate (semantic organization, naming conflicts, etc) that such an important utility as `hasOwnProperty(..)` was included on the Object `[[Prototype]]` chain as an instance method, instead of being defined as a static utility.\n\nAs of ES2022, JS has finally added the static version of this utility: `Object.hasOwn(..)`.\n\n```js\nmyObj = {\n    favoriteNumber: 42\n};\n\nObject.hasOwn(myObj,\"favoriteNumber\");   // true\n```\n\nThis form is now considered the more preferable and robust option, and the instance method (`hasOwnProperty(..)`) form should now generally be avoided.\n\nSomewhat unfortunately and inconsistently, there's not (yet, as of time of writing) corresponding static utilities, like `Object.isPrototype(..)` (instead of the instance method `isPrototypeOf(..)`). But at least `Object.hasOwn(..)` exists, so that's progress.\n\n### Creating An Object With A Different `[[Prototype]]`\n\nBy default, any object you create in your programs will be `[[Prototype]]`-linked to that `Object.prototype` object. However, you can create an object with a different linkage like this:\n\n```js\nmyObj = Object.create(differentObj);\n```\n\nThe `Object.create(..)` method takes its first argument as the value to set for the newly created object's `[[Prototype]]`.\n\nOne downside to this approach is that you aren't using the `{ .. }` literal syntax, so you don't initially define any contents for `myObj`. You typically then have to define properties one-by-one, using `=`.\n\n| NOTE: |\n| :--- |\n| The second, optional argument to `Object.create(..)` is -- like the second argument to `Object.defineProperties(..)` as discussed earlier -- an object with properties that hold descriptors to initially define the new object with. In practice out in the wild, this form is rarely used, likely because it's more awkward to specify full descriptors instead of just name/value pairs. But it may come in handy in some limited cases. |\n\nAlternately, but less preferably, you can use the `{ .. }` literal syntax along with a special (and strange looking!) property:\n\n```js\nmyObj = {\n    __proto__: differentObj,\n\n    // .. the rest of the object definition\n};\n```\n\n| WARNING: |\n| :--- |\n| The strange looking `__proto__` property has been in some JS engines for more than 20 years, but was only standardized in JS as of ES6 (in 2015). Even still, it was added in Appendix B of the specification[^specApB], which lists features that TC39 begrudgingly includes because they exist popularly in various browser-based JS engines and therefore are a de-facto reality even if they didn't originate with TC39. This feature is thus \"guaranteed\" by the spec to exist in all conforming browser-based JS engines, but is not necessarily guaranteed to work in other independent JS engines. Node.js uses the JS engine (v8) from the Chrome browser, so Node.js gets `__proto__` by default/accident. Be careful when using `__proto__` to be aware of all the JS engine environments your code will run in. |\n\nWhether you use `Object.create(..)` or `__proto__`, the created object in question will usually be `[[Prototype]]`-linked to a different object than the default `Object.prototype`.\n\n#### Empty `[[Prototype]]` Linkage\n\nWe mentioned above that the `[[Prototype]]` chain has to stop somewhere, so as to have lookups not continue forever. `Object.prototype` is typically the top/end of every `[[Prototype]]` chain, as its own `[[Prototype]]` is `null`, and therefore there's nowhere else to continue looking.\n\nHowever, you can also define objects with their own `null` value for `[[Prototype]]`, such as:\n\n```js\nemptyObj = Object.create(null);\n// or: emptyObj = { __proto__: null }\n\nemptyObj.toString;   // undefined\n```\n\nIt can be quite useful to create an object with no `[[Prototype]]` linkage to `Object.prototype`. For example, as mentioned in Chapter 1, the `in` and `for..in` constructs will consult the `[[Prototype]]` chain for inherited properties. But this may be undesirable, as you may not want something like `\"toString\" in myObj` to resolve successfully.\n\nMoreover, an object with an empty `[[Prototype]]` is safe from any accidental \"inheritance\" collision between its own property names and the ones it \"inherits\" from elsewhere. These types of (useful!) objects are sometimes referred to in popular parlance as \"dictionary objects\".\n\n### `[[Prototype]]` vs `prototype`\n\nNotice that public property name `prototype` in the name/location of this special object, `Object.prototype`? What's that all about?\n\n`Object` is the `Object(..)` function; by default, all functions (which are themselves objects!) have such a `prototype` property on them, pointing at an object.\n\nAny here's where the name conflict between `[[Prototype]]` and `prototype` really bites us. The `prototype` property on a function doesn't define any linkage that the function itself experiences. Indeed, functions (as objects) have their own internal `[[Prototype]]` linkage somewhere else -- more on that in a second.\n\nRather, the `prototype` property on a function refers to an object that should be *linked TO* by any other object that is created when calling that function with the `new` keyword:\n\n```js\nmyObj = {};\n\n// is basically the same as:\nmyObj = new Object();\n```\n\nSince the `{ .. }` object literal syntax is essentially the same as a `new Object()` call, the built-in object named/located at `Object.prototype` is used as the internal `[[Prototype]]` value for the new object we create and name `myObj`.\n\nPhew! Talk about a topic made significantly more confusing just because of the name overlap between `[[Prototype]]` and `prototype`!\n\n----\n\nBut where do functions themselves (as objects!) link to, `[[Prototype]]` wise? They link to `Function.prototype`, yet another built-in object, located at the `prototype` property on the `Function(..)` function.\n\nIn other words, you can think of functions themselves as having been \"created\" by a `new Function(..)` call, and then `[[Prototype]]`-linked to the `Function.prototype` object. This object contains properties/methods all functions \"inherit\" by default, such as `toString()` (to string serialize the source code of a function) and `call(..)` / `apply(..)` / `bind(..)` (we'll explain these later in this book).\n\n## Objects Behavior\n\nProperties on objects are internally defined and controlled by a \"descriptor\" metaobject, which includes attributes such as `value` (the property's present value) and `enumerable` (a boolean controlling whether the property is included in enumerable-only listings of properties/property names).\n\nThe way object and their properties work in JS is referred to as the \"metaobject protocol\" (MOP)[^mop]. We can control the precise behavior of properties via `Object.defineProperty(..)`, as well as object-wide behaviors with `Object.freeze(..)`. But even more powerfully, we can hook into and override certain default behaviors on objects using special pre-defined Symbols.\n\nPrototypes are internal linkages between objects that allow property or method access against one object -- if the property/method requested is absent -- to be handled by \"delegating\" that access lookup to another object. When the delegation involves a method, the context for the method to run in is shared from the initial object to the target object via the `this` keyword.\n\n[^mop]: \"Metaobject\", Wikipedia; https://en.wikipedia.org/wiki/Metaobject ; Accessed July 2022.\n\n[^specApB]: \"Appendix B: Additional ECMAScript Features for Web Browsers\", ECMAScript 2022 Language Specification; https://262.ecma-international.org/13.0/#sec-additional-ecmascript-features-for-web-browsers ; Accessed July 2022\n"
  },
  {
    "path": "objects-classes/ch3.md",
    "content": "# You Don't Know JS Yet: Objects & Classes - 2nd Edition\n# Chapter 3: Classy Objects\n\n| NOTE: |\n| :--- |\n| Work in progress |\n\nThe class-design pattern generally entails defining a *type of thing* (class), including data (members) and behaviors (methods), and then creating one or more concrete *instances* of this class definition as actual objects that can interact and perform tasks. Moreover, class-orientation allows declaring a relationship between two or more classes, through what's called \"inheritance\", to derive new and augmented \"subclasses\" that mix-n-match and even re-define behaviors.\n\nPrior to ES6 (2015), JS developers mimicked aspects of class-oriented (aka \"object-oriented\") design using plain functions and objects, along with the `[[Prototype]]` mechanism (as explained in the previous chapter) -- so called \"prototypal classes\".\n\nBut to many developers joy and relief, ES6 introduced dedicated syntax, including the `class` and `extends` keywords, to express class-oriented design more declaratively.\n\nAt the time of ES6's `class` being introduced, this new dedicated syntax was almost entirely *just syntactic sugar* to make class definitions more convenient and readable. However, in the many years since ES6, `class` has matured and grown into its own first class feature mechanism, accruing a significant amount of dedicated syntax and complex behaviors that far surpass the pre-ES6 \"prototypal class\" capabilities.\n\nEven though `class` now bears almost no resemblance to older \"prototypal class\" code style, the JS engine is still *just* wiring up objects to each other through the existing `[[Prototype]]` mechanism. In other words, `class` is not its own separate pillar of the language (as `[[Prototype]]` is), but more like the fancy, decorative *Capital* that tops the pillar/column.\n\nThat said, since `class` style code has now replaced virtually all previous \"prototypal class\" coding, the main text here focuses only on `class` and its various particulars. For historical purposes, we'll briefly cover the old \"prototypal class\" style in an appendix.\n\n## When Should I Class-Orient My Code?\n\nClass-orientation is a design pattern, which means it's a choice for how you organize the information and behavior in your program. It has pros and cons. It's not a universal solution for all tasks.\n\nSo how do you know when you should use classes?\n\nIn a theoretical sense, class-orientation is a way of dividing up the business domain of a program into one or more pieces that can each be defined by an \"is-a\" classification: grouping a thing into the set (or sets) of characteristics that thing shares with other similar things. You would say \"X is a Y\", meaning X has (at least) all the characteristics of a thing of kind Y.\n\nFor example, consider computers. We could say a computer is electrical, since it uses electrical current (voltage, amps, etc) as power. It's furthermore electronic, because it manipulates the electrical current beyond simply routing electrons around (electrical/magnetic fields), creating a meaningful circuit to manipulate the current into performing more complex tasks. By contrast, a basic desk lamp is electrical, but not really electronic.\n\nWe could thus define a class `Electrical` to describe what electrical devices need and can do. We could then define a further class `Electronic`, and define that in addition to being electrical, `Electronic` things manipulate electricity to create more specialized outcomes.\n\nHere's where class-orientation starts to shine. Rather than re-define all the `Electrical` characteristics in the `Electronic` class, we can define `Electronic` in such a way that it \"shares\" or \"inherits\" those characteristics from `Electrical`, and then augments/redefines the unique behaviors that make a device electronic. This relationship between the two classes -- called \"inheritance\" -- is a key aspect of class-orientation.\n\nSo class-orientation is a way of thinking about the entities our program needs, and classifying them into groupings based on their characteristics (what information they hold, what operations can be performed on that data), and defining the relationships between the different grouping of characteristics.\n\nBut moving from the theoretical into in a bit more pragmatic perspective: if your program needs to hold and use multiple collections (instances) of alike data/behavior at once, you *may* benefit from class-orientation.\n\n### Time For An Example\n\nHere's a short illustration.\n\nA couple of decades ago, right after I had gone through nearly all of a Computer Science degree in college, I found myself sitting in my first professional software developer job. I was tasked with building, all by myself, a timesheet and payroll tracking system. I built the backend in PHP (using MySQL for the DB) and used JS for the interface (early as it was in its maturity way back around the turn of the century).\n\nSince my CS degree had emphasized class-orientation heavily throughout my courses, I was eager to put all that theory to work. For my program's design, I defined the concept of a \"timesheet\" entity as a collection of 2-3 \"week\" entities, and each \"week\" as a collection of 5-7 \"day\" entities, and each \"day\" as a collection of \"task\" entities.\n\nIf I wanted to know how many hours were logged into a timesheet instance, I could call a `totalTime()` operation on that instance. The timesheet defined this operation by looping over its collection of weeks, calling `totalTime()` on each of them and summing the values. Each week did the same for all its days, and each day did the same for all its tasks.\n\nThe notion being illustrated here, one of the fundamentals of design patterns like class-orientation, is called *encapsulation*. Each entity level encapsulated (e.g., controlled, hid, abstracted) internal details (data and behavior) while presenting a useful external interface.\n\nBut encapsulation alone isn't a sufficient justification for class-orientation. Other design patterns offer sufficient encapsulation.\n\nHow did my class design take advantage of inheritance? I had a base class that defined a set of operations like `totalTime()`, and each of my entity class types extended/subclassed this base class. That meant that each of them inherited this summation-of-total-time capability, but where each of them applied their own extensions and definitions for the internal details of *how* to do that work.\n\nThere's yet another aspect of the design pattern at play, which is *composition*: each entity was defined as a collection of other entities.\n\n### Single vs Multiple\n\nI mentioned above that a pragmatic way of deciding if you need class-orientation is if your program is going to have multiple instances of a single kind/type of behavior (aka, \"class\"). In the timesheet example, we had 4 classes: Timesheet, Week, Day, and Task. But for each class, we had multiple instances of each at once.\n\nHad we instead only needed a single instance of a class, like just one `Computer` thing that was an instance of the `Electronic` class, which was a subclass of the `Electrical` class, then class-orientation may not offer quite as much benefit. In particular, if the program doesn't need to create an instance of the `Electrical` class, then there's no particular benefit to separating `Electrical` from `Electronic`, so we aren't really getting any help from the inheritance aspect of class-orientation.\n\nSo, if you find yourself designing a program by dividing up a business problem domain into different \"classes\" of entities, but in the actual code of the program you are only ever need one concrete *thing* of one kind/definition of behavior (aka, \"class\"), you might very well not actually need class-orientation. There are other design patterns which may be a more efficient match to your effort.\n\nBut if you find yourself wanting to define classes, and subclasses which inherit from them, and if you're going to be instantiating one or more of those classes multiple times, then class-orientation is a good candidate. And to do class-orientation in JS, you're going to need the `class` keyword.\n\n## Keep It `class`y\n\n`class` defines either a declaration or expression for a class. As a declaration, a class definition appears in a statement position and looks like this:\n\n```js\nclass Point2d {\n    // ..\n}\n```\n\nAs an expression, a class definition appears in a value position and can either have a name or be anonymous:\n\n```js\n// named class expression\nconst pointClass = class Point2d {\n    // ..\n};\n\n// anonymous class expression\nconst anotherClass = class {\n    // ..\n};\n```\n\nThe contents of a `class` body typically include one or more method definitions:\n\n```js\nclass Point2d {\n    setX(x) {\n        // ..\n    }\n    setY(y) {\n        // ..\n    }\n}\n```\n\nInside a `class` body, methods are defined without the `function` keyword, and there's no `,` or `;` separators between the method definitions.\n\n| NOTE: |\n| :--- |\n| Inside a `class` block, all code runs in strict-mode even without the `\"use strict\"` pragma present in the file or its functions. In particular, this impacts the `this` behavior for function calls, as explained in Chapter 4. |\n\n### The Constructor\n\nOne special method that all classes have is called a \"constructor\". If omitted, there's a default empty constructor assumed in the definition.\n\nThe constructor is invoked any time a `new` instance of the class is created:\n\n```js\nclass Point2d {\n    constructor() {\n        console.log(\"Here's your new instance!\");\n    }\n}\n\nvar point = new Point2d();\n// Here's your new instance!\n```\n\nEven though the syntax implies a function actually named `constructor` exists, JS defines a function as specified, but with the name of the class (`Point2d` above):\n\n```js\ntypeof Point2d;       // \"function\"\n```\n\nIt's not *just* a regular function, though; this special kind of function behaves a bit differently:\n\n```js\nPoint2d.toString();\n// class Point2d {\n//   ..\n// }\n\nPoint2d();\n// TypeError: Class constructor Point2d cannot\n// be invoked without 'new'\n\nPoint2d.call({});\n// TypeError: Class constructor Point2d cannot\n// be invoked without 'new'\n```\n\nYou can construct as many different instances of a class as you need:\n\n```js\nvar one = new Point2d();\nvar two = new Point2d();\nvar three = new Point2d();\n```\n\nEach of `one`, `two`, and `three` here are objects that are independent instances of the `Point2d` class.\n\n| NOTE: |\n| :--- |\n| Each of the `one`, `two`, and `three` objects have a `[[Prototype]]` linkage to the `Point2d.prototype` object (see Chapter 2). In this code, `Point2d` is both a `class` definition and the constructor function of the same name. |\n\nIf you add a property to the object `one`:\n\n```js\none.value = 42;\n```\n\nThat property now exists only on `one`, and does not exist in any way that the independent `two` or `three` objects can access:\n\n```js\ntwo.value;      // undefined\nthree.value;    // undefined\n```\n\n### Class Methods\n\nAs shown above, a class definition can include one or more method definitions:\n\n```js\nclass Point2d {\n    constructor() {\n        console.log(\"Here's your new instance!\");\n    }\n    setX(x) {\n        console.log(`Setting x to: ${x}`);\n        // ..\n    }\n}\n\nvar point = new Point2d();\n\npoint.setX(3);\n// Setting x to: 3\n```\n\nThe `setX` property (method) *looks like* it exists on (is owned by) the `point` object here. But that's a mirage. Each class method is added to the `prototype`object, a property of the constructor function.\n\nSo, `setX(..)` only exists as `Point2d.prototype.setX`. Since `point` is `[[Prototype]]` linked to `Point2d.prototype` (see Chapter 2) via the `new` keyword instantiation, the `point.setX(..)` reference traverses the `[[Prototype]]` chain and finds the method to execute.\n\nClass methods should only be invoked via an instance; `Point2d.setX(..)` doesn't work because there *is no* such property. You *could* invoke `Point2d.prototype.setX(..)`, but that's not generally proper/advised in standard class-oriented coding. Always access class methods via the instances.\n\n## Class Instance `this`\n\nWe will cover the `this` keyword in much more detail in a subsequent chapter. But as it relates to class-oriented code, the `this` keyword generally refers to the current instance that is the context of any method invocation.\n\nIn the constructor, as well as any methods, you can use `this.` to either add or access properties on the current instance:\n\n```js\nclass Point2d {\n    constructor(x,y) {\n        // add properties to the current instance\n        this.x = x;\n        this.y = y;\n    }\n    toString() {\n        // access the properties from the current instance\n        console.log(`(${this.x},${this.y})`);\n    }\n}\n\nvar point = new Point2d(3,4);\n\npoint.x;                // 3\npoint.y;                // 4\n\npoint.toString();       // (3,4)\n```\n\nAny properties not holding function values, which are added to a class instance (usually via the constructor), are referred to as *members*, as opposed to the term *methods* for executable functions.\n\nWhile the `point.toString()` method is running, its `this` reference is pointing at the same object that `point` references. That's why both `point.x` and `this.x` reveal the same `3` value that the constructor set with its `this.x = x` operation.\n\n### Public Fields\n\nInstead of defining a class instance member imperatively via `this.` in the constructor or a method, classes can declaratively define *fields* in the `class` body, which correspond directly to members that will be created on each instance:\n\n```js\nclass Point2d {\n    // these are public fields\n    x = 0\n    y = 0\n\n    constructor(x,y) {\n        // set properties (fields) on the current instance\n        this.x = x;\n        this.y = y;\n    }\n    toString() {\n        // access the properties from the current instance\n        console.log(`(${this.x},${this.y})`);\n    }\n}\n```\n\nPublic fields can have a value initialization, as shown above, but that's not required. If you don't initialize a field in the class definition, you almost always should initialize it in the constructor.\n\nFields can also reference each other, via natural `this.` access syntax:\n\n```js\nclass Point3d {\n    // these are public fields\n    x\n    y = 4\n    z = this.y * 5\n\n    // ..\n}\n```\n\n| TIP: |\n| :--- |\n| You can mostly think of public field declarations as if they appear at the top of the `constructor(..)`, each prefixed with an implied `this.` that you get to omit in the declarative `class` body form. But, there's a catch! See \"That's Super!\" later for more information about it. |\n\nJust like computed property names (see Chapter 1), field names can be computed:\n\n```js\nvar coordName = \"x\";\n\nclass Point2d {\n    // computed public field\n    [coordName.toUpperCase()] = 42\n\n    // ..\n}\n\nvar point = new Point2d(3,4);\n\npoint.x;        // 3\npoint.y;        // 4\n\npoint.X;        // 42\n```\n\n#### Avoid This\n\nOne pattern that has emerged and grown quite popular, but which I firmly believe is an anti-pattern for `class`, looks like the following:\n\n```js\nclass Point2d {\n    x = null\n    y = null\n    getDoubleX = () => this.x * 2\n\n    constructor(x,y) {\n        this.x = x;\n        this.y = y;\n    }\n    toString() { /* .. */ }\n}\n\nvar point = new Point2d(3,4);\n\npoint.getDoubleX();    // 6\n```\n\nSee the field holding an `=>` arrow function? I say this is a no-no. But why? Let's unwind what's going on.\n\nFirst, why do this? Because JS developers seem to be perpetually frustrated by the dynamic `this` binding rules (see Chapter 4), so they force a `this` binding via the `=>` arrow function. That way, no matter how `getDoubleX()` is invoked, it's always `this`-bound to the particular instance. That's an understandable convenience to desire, but... it betrays the very nature of the `this` / `[[Prototype]]` pillar of the language. How?\n\nLet's consider the equivalent code to the previous snippet:\n\n```js\nclass Point2d {\n    constructor(x,y) {\n        this.x = null;\n        this.y = null;\n        this.getDoubleX = () => this.x * 2;\n\n        this.x = x;\n        this.y = y;\n    }\n    toString() { /* .. */ }\n}\n\nvar point = new Point2d(3,4);\n\npoint.getDoubleX();    // 6\n```\n\nCan you spot the problem? Look closely. I'll wait.\n\n...\n\nWe've made it clear repeatedly so far that `class` definitions put their methods on the class constructor's `prototype` object -- that's where they belong! -- such that there's just one of each function and it's inherited (shared) by all instances. That's what will happen with `toString()` in the above snippet.\n\nBut what about `getDoubleX()`? That's essentially a class method, but it won't be handled by JS quite the same as `toString()` will. Consider:\n\n```js\nObject.hasOwn(point,\"x\");               // true -- good\nObject.hasOwn(point,\"toString\");        // false -- good\nObject.hasOwn(point,\"getDoubleX\");      // true -- oops :(\n```\n\nYou see now? By defining a function value and attaching it as a field/member property, we're losing the shared prototypal method'ness of the function, and it becomes just like any per-instance property. That means we're creating a new function property **for each instance**, rather than it being created just once on the class constructor's `prototype`.\n\nThat's wasteful in performance and memory, even if by a tiny bit. That alone should be enough to avoid it.\n\nBut I would argue that way more importantly, what you've done with this pattern is invalidate the very reason why using `class` and `this`-aware methods is even remotely useful/powerful!\n\nIf you go to all the trouble to define class methods with `this.` references throughout them, but then you lock/bind most or all of those methods to a specific object instance, you've basically travelled all the way around the world just to go next door.\n\nIf all you want are function(s) that are statically fixed to a particular \"context\", and don't need any dynamicism or sharing, what you want is... **closure**. And you're in luck: I wrote a whole book in this series (\"Scope & Closures\") on how to use closure so functions remember/access their statically defined scope (aka \"context\"). That's a way more appropriate, and simpler to code, approach to get what you're after.\n\nDon't abuse/misuse `class` and turn it into a over-hyped, glorified collection of closure.\n\nTo be clear, I'm *not* saying: never use `=>` arrow functions inside classes.\n\nI *am* saying: never attach an `=>` arrow function as an instance property in place of a dynamic prototypal class method, either out of mindless habit, or laziness in typing fewer characters, or misguided `this`-binding convenience.\n\nIn a subsequent chapter, we'll dive deep into how to understand and properly leverage the full power of the dynamic `this` mechanism.\n\n## Class Extension\n\nThe way to unlock the power of class inheritance is through the `extends` keyword, which defines a relationship between two classes:\n\n```js\nclass Point2d {\n    x = 3\n    y = 4\n\n    getX() {\n        return this.x;\n    }\n}\n\nclass Point3d extends Point2d {\n    x = 21\n    y = 10\n    z = 5\n\n    printDoubleX() {\n        console.log(`double x: ${this.getX() * 2}`);\n    }\n}\n\nvar point = new Point2d();\n\npoint.getX();                   // 3\n\nvar anotherPoint = new Point3d();\n\nanotherPoint.getX();            // 21\nanotherPoint.printDoubleX();    // double x: 42\n```\n\nTake a few moments to re-read that code snippet and make sure you fully understand what's happening.\n\nThe base class `Point2d` defines fields (members) called `x` and `y`, and gives them the initial values `3` and `4`, respectively. It also defines a `getX()` method that accesses this `x` instance member and returns it. We see that behavior illustrated in the `point.getX()` method call.\n\nBut the `Point3d` class extends `Point2d`, making `Point3d` a derived-class, child-class, or (most commonly) subclass. In `Point3d`, the same `x` property that's inherited from `Point2d` is re-initialized with a different `21` value, as is the `y` overridden to value from `4`, to `10`.\n\nIt also adds a new `z` field/member method, as well as a `printDoubleX()` method, which itself calls `this.getX()`.\n\nWhen `anotherPoint.printDoubleX()` is invoked, the inherited `this.getX()` is thus invoked, and that method makes reference to `this.x`. Since `this` is pointing at the class instance (aka, `anotherPoint`), the value it finds is now `21` (instead of `3` from the `point` object's `x` member).\n\n### Extending Expressions\n\n// TODO: cover `class Foo extends ..` where `..` is an expression, not a class-name\n\n### Overriding Methods\n\nIn addition to overriding a field/member in a subclass, you can also override (redefine) a method:\n\n```js\nclass Point2d {\n    x = 3\n    y = 4\n\n    getX() {\n        return this.x;\n    }\n}\n\nclass Point3d extends Point2d {\n    x = 21\n    y = 10\n    z = 5\n\n    getX() {\n        return this.x * 2;\n    }\n    printX() {\n        console.log(`double x: ${this.getX()}`);\n    }\n}\n\nvar point = new Point3d();\n\npoint.printX();       // double x: 42\n```\n\nThe `Point3d` subclass overrides the inherited `getX()` method to give it different behavior. However, you can still instantiate the base `Point2d` class, which would then give an object that uses the original (`return this.x;`) definition for `getX()`.\n\nIf you want to access an inherited method from a subclass even if it's been overridden, you can use `super` instead of `this`:\n\n```js\nclass Point2d {\n    x = 3\n    y = 4\n\n    getX() {\n        return this.x;\n    }\n}\n\nclass Point3d extends Point2d {\n    x = 21\n    y = 10\n    z = 5\n\n    getX() {\n        return this.x * 2;\n    }\n    printX() {\n        console.log(`x: ${super.getX()}`);\n    }\n}\n\nvar point = new Point3d();\n\npoint.printX();       // x: 21\n```\n\nThe ability for methods of the same name, at different levels of the inheritance hierarchy, to exhibit different behavior when either accessed directly, or relatively with `super`, is called *method polymorphism*. It's a very powerful part of class-orientation, when used appropriately.\n\n### That's Super!\n\nIn addition to a subclass method accessing an inherited method definition (even if overriden on the subclass) via `super.` reference, a subclass constructor must manually invoke the inherited base class constructor via `super(..)` function invocation:\n\n```js\nclass Point2d {\n    x\n    y\n    constructor(x,y) {\n        this.x = x;\n        this.y = y;\n    }\n}\n\nclass Point3d extends Point2d {\n    z\n    constructor(x,y,z) {\n        super(x,y);\n        this.z = z;\n    }\n    toString() {\n        console.log(`(${this.x},${this.y},${this.z})`);\n    }\n}\n\nvar point = new Point3d(3,4,5);\n\npoint.toString();       // (3,4,5)\n```\n\n| WARNING: |\n| :--- |\n| An explicitly defined subclass constructor *must* call `super(..)` to run the inherited class's initialization, and that must occur before the subclass constructor makes any references to `this` or finishes/returns. Otherwise, a runtime exception will be thrown when that subclass constructor is invoked (via `new`). If you omit the subclass constructor, the default constructor automatically -- thankfully! -- invokes `super()` for you. |\n\nOne nuance to be aware of: if you define a field (public or private) inside a subclass, and explicitly define a `constructor(..)` for this subclass, the field initializations will be processed not at the top of the constructor, but *between* the `super(..)` call and any subsequent code in the constructor.\n\nPay close attention to the order of console messages here:\n\n```js\nclass Point2d {\n    x\n    y\n    constructor(x,y) {\n        console.log(\"Running Point2d(..) constructor\");\n        this.x = x;\n        this.y = y;\n    }\n}\n\nclass Point3d extends Point2d {\n    z = console.log(\"Initializing field 'z'\")\n\n    constructor(x,y,z) {\n        console.log(\"Running Point3d(..) constructor\");\n        super(x,y);\n\n        console.log(`Setting instance property 'z' to ${z}`);\n        this.z = z;\n    }\n    toString() {\n        console.log(`(${this.x},${this.y},${this.z})`);\n    }\n}\n\nvar point = new Point3d(3,4,5);\n// Running Point3d(..) constructor\n// Running Point2d(..) constructor\n// Initializing field 'z'\n// Setting instance property 'z' to 5\n```\n\nAs the console messages illustrate, the `z = ..` field initialization happens *immediately after* the `super(x,y)` call, *before* the ``console.log(`Setting instance...`)`` is executed. Perhaps think of it like the field initializations attached to the end of the `super(..)` call, so they run before anything else in the constructor does.\n\n#### Which Class?\n\nYou may need to determine in a constructor if that class is being instantiated directly, or being instantiated from a subclass with a `super()` call. We can use a special \"pseudo property\" `new.target`:\n\n```js\nclass Point2d {\n    // ..\n\n    constructor(x,y) {\n        if (new.target === Point2d) {\n            console.log(\"Constructing 'Point2d' instance\");\n        }\n    }\n\n    // ..\n}\n\nclass Point3d extends Point2d {\n    // ..\n\n    constructor(x,y,z) {\n        super(x,y);\n\n        if (new.target === Point3d) {\n            console.log(\"Constructing 'Point3d' instance\");\n        }\n    }\n\n    // ..\n}\n\nvar point = new Point2d(3,4);\n// Constructing 'Point2d' instance\n\nvar anotherPoint = new Point3d(3,4,5);\n// Constructing 'Point3d' instance\n```\n\n### But Which Kind Of Instance?\n\nYou may want to introspect a certain object instance to see if it's an instance of a specific class. We do this with the `instanceof` operator:\n\n```js\nclass Point2d { /* .. */ }\nclass Point3d extends Point2d { /* .. */ }\n\nvar point = new Point2d(3,4);\n\npoint instanceof Point2d;           // true\npoint instanceof Point3d;           // false\n\nvar anotherPoint = new Point3d(3,4,5);\n\nanotherPoint instanceof Point2d;    // true\nanotherPoint instanceof Point3d;    // true\n```\n\nIt may seem strange to see `anotherPoint instanceof Point2d` result in `true`. To understand why better, perhaps it's useful to visualize both `[[Prototype]]` chains:\n\n```\nPoint2d.prototype\n        /       \\\n       /         \\\n      /           \\\n  point   Point3d.prototype\n                    \\\n                     \\\n                      \\\n                    anotherPoint\n```\n\nThe `instanceof` operator doesn't just look at the current object, but rather traverses the entire class inheritance hierarchy (the `[[Prototype]]` chain) until it finds a match. Thus, `anotherPoint` is an instance of both `Point3d` and `Point2d`.\n\nTo illustrate this fact a little more obviously, another (less ergonomic) way of going about the same kind of check as `instanceof` is with the (inherited from `Object.prototype`) utility, `isPrototypeOf(..)`:\n\n```js\nPoint2d.prototype.isPrototypeOf(point);             // true\nPoint3d.prototype.isPrototypeOf(point);             // false\n\nPoint2d.prototype.isPrototypeOf(anotherPoint);      // true\nPoint3d.prototype.isPrototypeOf(anotherPoint);      // true\n```\n\nThis utility makes it a little clearer why both `Point2d.prototype.isPrototypeOf(anotherPoint)` and `anotherPoint instanceof Point2d` result in `true`: the object `Point2d.prototype` *is* in the `[[Prototype]]` chain of `anotherPoint`.\n\nIf you instead wanted to check if the object instance was *only and directly* created by a certain class, check the instance's `constructor` property.\n\n```js\npoint.constructor === Point2d;          // true\npoint.constructor === Point3d;          // false\n\nanotherPoint.constructor === Point2d;   // false\nanotherPoint.constructor === Point3d;   // true\n```\n\n| NOTE: |\n| :--- |\n| The `constructor` property shown here is *not* actually present on (owned) the `point` or `anotherPoint` instance objects. So where does it come from!? It's on each object's `[[Prototype]]` linked prototype object: `Point2d.prototype.constructor === Point2d` and `Point3d.prototype.constructor === Point3d`. |\n\n### \"Inheritance\" Is Sharing, Not Copying\n\nIt may seem as if `Point3d`, when it `extends` the `Point2d` class, is in essence getting a *copy* of all the behavior defined in `Point2d`. Moreover, it may seem as if the concrete object instance `anotherPoint` receives, *copied down* to it, all the methods from `Point3d` (and by extension, also from `Point2d`).\n\nHowever, that's not the correct mental model to use for JS's implementation of class-orientation. Recall this base class and subclass definition, as well as instantiation of `anotherPoint`:\n\n```js\nclass Point2d {\n    x\n    y\n    constructor(x,y) {\n        this.x = x;\n        this.y = y;\n    }\n}\n\nclass Point3d extends Point2d {\n    z\n    constructor(x,y,z) {\n        super(x,y);\n        this.z = z;\n    }\n    toString() {\n        console.log(`(${this.x},${this.y},${this.z})`);\n    }\n}\n\nvar anotherPoint = new Point3d(3,4,5);\n```\n\nIf you inspect the `anotherPoint` object, you'll see it only has the `x`, `y`, and `z` properties (instance members) on it, but not the `toString()` method:\n\n```js\nObject.hasOwn(anotherPoint,\"x\");                       // true\nObject.hasOwn(anotherPoint,\"y\");                       // true\nObject.hasOwn(anotherPoint,\"z\");                       // true\n\nObject.hasOwn(anotherPoint,\"toString\");                // false\n```\n\nWhere is that `toString()` method located? On the prototype object:\n\n```js\nObject.hasOwn(Point3d.prototype,\"toString\");    // true\n```\n\nAnd `anotherPoint` has access to that method via its `[[Prototype]]` linkage (see Chapter 2). In other words, the prototype objects **share access** to their method(s) with the subclass(es) and instance(s). The method(s) stay in place, and are not copied down the inheritance chain.\n\nAs nice as the `class` syntax is, don't forget what's really happening under the syntax: JS is *just* wiring up objects to each other along a `[[Prototype]]` chain.\n\n## Static Class Behavior\n\nWe've so far emphasized two different locations for data or behavior (methods) to reside: on the constructor's prototype, or on the instance. But there's a third option: on the constructor (function object) itself.\n\nIn a traditional class-oriented system, methods defined on a class are not concrete things you could ever invoke or interact with. You have to instantiate a class to have a concrete object to invoke those methods with. Prototypal languages like JS blur this line a bit: all class-defined methods are \"real\" functions residing on the constructor's prototype, and you could therefore invoke them. But as I asserted earlier, you really *should not* do so, as this is not how JS assumes you will write your `class`es, and there are some weird corner-case behaviors you may run into. Best to stay on the narrow path that `class` lays out for you.\n\nNot all behavior that we define and want to associate/organize with a class *needs* to be aware of an instance. Moreover, sometimes a class needs to publicly define data (like constants) that developers using that class need to access, independent of any instance they may or may not have created.\n\nSo, how does a class system enable defining such data and behavior that should be available with a class but independent of (unaware of) instantiated objects? **Static properties and functions**.\n\n| NOTE: |\n| :--- |\n| I'll use \"static property\" / \"static function\", rather than \"member\" / \"method\", just so it's clearer that there's a distinction between instance-bound members / instance-aware methods, and non-instance properties and instance-unaware functions. |\n\nWe use the `static` keyword in our `class` bodies to distinguish these definitions:\n\n```js\nclass Point2d {\n    // class statics\n    static origin = new Point2d(0,0)\n    static distance(point1,point2) {\n        return Math.sqrt(\n            ((point2.x - point1.x) ** 2) +\n            ((point2.y - point1.y) ** 2)\n        );\n    }\n\n    // instance members and methods\n    x\n    y\n    constructor(x,y) {\n        this.x = x;\n        this.y = y;\n    }\n    toString() {\n        return `(${this.x},${this.y})`;\n    }\n}\n\nconsole.log(`Starting point: ${Point2d.origin}`);\n// Starting point: (0,0)\n\nvar next = new Point2d(3,4);\nconsole.log(`Next point: ${next}`);\n// Next point: (3,4)\n\nconsole.log(`Distance: ${\n    Point2d.distance( Point2d.origin, next )\n}`);\n// Distance: 5\n```\n\nThe `Point2d.origin` is a static property, which just so happens to hold a constructed instance of our class. And `Point2d.distance(..)` is a static function that computes the 2-dimensional cartesian distance between two points.\n\nOf course, we could have put these two somewhere other than as `static`s on the class definition. But since they're directly related to the `Point2d` class, it makes *most sense* to organize them there.\n\n| NOTE: |\n| :--- |\n| Don't forget that when you use the `class` syntax, the name `Point2d` is actually the name of a constructor function that JS defines. So `Point2d.origin` is just a regular property access on that function object. That's what I meant at the top of this section when I referred to a third location for storing *things* related to classes; in JS, `static`s are stored as properties on the constructor function. Take care not to confuse those with properties stored on the constructor's `prototype` (methods) and properties stored on the instance (members). |\n\n### Static Property Initializations\n\nThe value in a static initialization (`static whatever = ..`) can include `this` references, which refers to the class itself (actually, the constructor) rather than to an instance:\n\n```js\nclass Point2d {\n    // class statics\n    static originX = 0\n    static originY = 0\n    static origin = new this(this.originX,this.originY)\n\n    // ..\n}\n```\n\n| WARNING: |\n| :--- |\n| I don't recommend actually doing the `new this(..)` trick I've illustrated here. That's just for illustration purposes. The code would read more cleanly with `new Point2d(this.originX,this.originY)`, so prefer that approach. |\n\nAn important detail not to gloss over: unlike public field initializations, which only happen once an instantiation (with `new`) occurs, class static initializations always run *immediately* after the `class` has been defined. Moreover, the order of static initializations matters; you can think of the statements as if they're being evaluated one at a time.\n\nAlso like class members, static properties do not have to be initialized (default: `undefined`), but it's much more common to do so. There's not much utility in declaring a static property with no initialized value (`static whatever`); Accessing either `Point2d.whatever` or `Point2d.nonExistent` would both result in `undefined`.\n\nRecently (in ES2022), the `static` keyword was extended so it can now define a block inside the `class` body for more sophisticated initialization of `static`s:\n\n```js\nclass Point2d {\n    // class statics\n    static origin = new Point2d(0,0)\n    static distance(point1,point2) {\n        return Math.sqrt(\n            ((point2.x - point1.x) ** 2) +\n            ((point2.y - point1.y) ** 2)\n        );\n    }\n\n    // static initialization block (as of ES2022)\n    static {\n        let outerPoint = new Point2d(6,8);\n        this.maxDistance = this.distance(\n            this.origin,\n            outerPoint\n        );\n    }\n\n    // ..\n}\n\nPoint2d.maxDistance;        // 10\n```\n\nThe `let outerPoint = ..` here is not a special `class` feature; it's exactly like a normal `let` declaration in any normal block of scope (see the \"Scope & Closures\" book of this series). We're merely declaring a localized instance of `Point2d` assigned to `outerPoint`, then using that value to derive the assignment to the `maxDistance` static property.\n\nStatic initialization blocks are also useful for things like `try..catch` statements around expression computations.\n\n### Static Inheritance\n\nClass statics are inherited by subclasses (obviously, as statics!), can be overriden, and `super` can be used for base class references (and static function polymorphism), all in much the same way as inheritance works with instance members/methods:\n\n```js\nclass Point2d {\n    static origin = /* .. */\n    static distance(x,y) { /* .. */ }\n\n    static {\n        // ..\n        this.maxDistance = /* .. */;\n    }\n\n    // ..\n}\n\nclass Point3d extends Point2d {\n    // class statics\n    static origin = new Point3d(\n        // here, `this.origin` references wouldn't\n        // work (self-referential), so we use\n        // `super.origin` references instead\n        super.origin.x, super.origin.y, 0\n    )\n    static distance(point1,point2) {\n        // here, super.distance(..) is Point2d.distance(..),\n        // if we needed to invoke it\n\n        return Math.sqrt(\n            ((point2.x - point1.x) ** 2) +\n            ((point2.y - point1.y) ** 2) +\n            ((point2.z - point1.z) ** 2)\n        );\n    }\n\n    // instance members/methods\n    z\n    constructor(x,y,z) {\n        super(x,y);     // <-- don't forget this line!\n        this.z = z;\n    }\n    toString() {\n        return `(${this.x},${this.y},${this.z})`;\n    }\n}\n\nPoint2d.maxDistance;        // 10\nPoint3d.maxDistance;        // 10\n```\n\nAs you can see, the static property `maxDistance` we defined on `Point2d` was inherited as a static property on `Point3d`.\n\n| TIP: |\n| :--- |\n| Remember: any time you define a subclass constructor, you'll need to call `super(..)` in it, usually as the first statement. I find that all too easy to forget. |\n\nDon't skip over the underlying JS behavior here. Just like method inheritance discussed earlier, the static \"inheritance\" is *not* a copying of these static properties/functions from base class to subclass; it's sharing via the `[[Prototype]]` chain. Specifically, the constructor function `Point3d()` has its `[[Prototype]]` linkage changed by JS (from the default of `Function.prototype`) to `Point2d`, which is what allows `Point3d.maxDistance` to delegate to `Point2d.maxDistance`.\n\nIt's also interesting, perhaps only historically now, to note that static inheritance -- which was part of the original ES6 `class` mechanism feature set! -- was one specific feature that went beyond \"just syntax sugar\". Static inheritance, as we see it illustrated here, was *not* possible to achieve/emulate in JS prior to ES6, in the old prototypal-class style of code. It's a special new behavior introduced only as of ES6.\n\n## Private Class Behavior\n\nEverything we've discussed so far as part of a `class` definition is publicly visible/accessible, either as static properties/functions on the class, methods on the constructor's `prototype`, or member properties on the instance.\n\nBut how do you store information that cannot be seen from outside the class? This was one of the most asked for features, and biggest complaints with JS's `class`, up until it was finally addressed in ES2022.\n\n`class` now supports new syntax for declaring private fields (instance members) and private methods. In addition, private static properties/functions are possible.\n\n### Motivation?\n\nBefore we illustrate how to do `class` privates, it bears contemplating why this is a helpful feature?\n\nWith closure-oriented design patterns (again, see the \"Scope & Closures\" book of this series), we automatically get \"privacy\" built-in. When you declare a variable inside a scope, it cannot be seen outside that scope. Period. Reducing the scope visibility of a declaration is helpful in preventing namespace collisions (identical variable names).\n\nBut it's even more important to ensure proper \"defensive\" design of software, the so called \"Principle of Least Privilege\" [^POLP]. POLP states that we should only expose a piece of information or capability in our software to the smallest surface area necessary.\n\nOver-exposure opens our software up to several issues that complicate software security/maintenance, including another piece of code acting maliciously to do something our code didn't expect or intend. Moreover, there's the less critical but still as problematic concern of other parts of our software relying on (using) parts of our code that we should have reserved as hidden implementation detail. Once other code relies on our code's implementation details, we stop being able to refactor our code without potentially breaking other parts of the program.\n\nSo, in short, we *should* hide implementation details if they're not necessary to be exposed. In this sense, JS's `class` system feels a bit too permissive in that everything defaults to being public. Class-private features are a welcomed addition to more proper software design.\n\n#### Too Private?\n\nAll that said, I have to throw a bit of a damper on the class-private party.\n\nI've suggested strongly that you should only use `class` if you're going to really take advantage of most or all of what class-orientation gives you. Otherwise, you'd be better suited using other core pillar features of JS for organizing code, such as with the closure pattern.\n\nOne of the most important aspects of class-orientation is subclass inheritance, as we've seen illustrated numerous times so far in this chapter. Guess what happens to a private member/method in a base class, when it's extended by a subclass?\n\nPrivate members/methods are private **only to the class they're defined in**, and are **not** inherited in any way by a subclass. Uh oh.\n\nThat might not seem like too big of a concern, until you start working with `class` and private members/methods in real software. You might quickly run up against a situation where you need to access a private method, or more often even, just a private member, from the subclass, so that the subclass can extend/augment the behavior of the base class as desired. And you might scream in frustration pretty quickly once you realize this is not possible.\n\nWhat comes next is inevitably an awkward decision: do you just go back to making it public, so the subclass can access it? Ugh. Or, worse, do you try to re-design the base class to contort the design of its members/methods, such that the lack of access is partially worked around. That often involves exhausting over-parameterization (with privates as default parameter values) of methods, and other such tricks. Double ugh.\n\nThere's not a particularly great answer here, to be honest. If you have experience with class-orientation in more traditional class languages like Java or C++, you're probably dubious as to why we don't have *protected* visibility in between *public* and *private*. That's exactly what *protected* is for: keeping something private to a class AND any of its subclasses. Those languages also have *friend* features, but that's beyond the scope of our discussion here.\n\nSadly, not only does JS not have *protected* visibility, it seems (even as useful as it is!) to be unlikely as a JS feature. It's been discussed in great detail for over a decade (before ES6 was even a thing), and there've been multiple proposals for it.\n\nI shouldn't say it will *never* happen, because that's not solid ground to stake on in any software. But it's very unlikely, because it actually betrays the very pillar that `class` is built on. If you are curious, or (more likely) certain that there's just *got to be a way*, I'll cover the incompatibility of *protected* visibility within JS's mechanisms in an appendix.\n\nThe point here is, as of now, JS has no *protected* visibility, and it won't any time soon. And *protected* visibility is actually, in practice, way more useful than *private* visibility.\n\nSo we return to the question: **Why should you care to make any `class` contents private?**\n\nIf I'm being honest: maybe you shouldn't. Or maybe you should. That's up to you. Just go into it aware of the stumbling blocks.\n\n### Private Members/Methods\n\nYou're excited to finally see the syntax for magical *private* visibility, right? Please don't shoot the messenger if you feel angered or sad at what you're about to see.\n\n```js\nclass Point2d {\n    // statics\n    static samePoint(point1,point2) {\n        return point1.#ID === point2.#ID;\n    }\n\n    // privates\n    #ID = null\n    #assignID() {\n        this.#ID = Math.round(Math.random() * 1e9);\n    }\n\n    // publics\n    x\n    y\n    constructor(x,y) {\n        this.#assignID();\n        this.x = x;\n        this.y = y;\n    }\n}\n\nvar one = new Point2d(3,4);\nvar two = new Point2d(3,4);\n\nPoint2d.samePoint(one,two);         // false\nPoint2d.samePoint(one,one);         // true\n```\n\nNo, JS didn't do the sensible thing and introduce a `private` keyword like they did with `static`. Instead, they introduced the `#`. (insert lame joke about social-media millienials loving hashtags, or something)\n\n| TIP: |\n| :--- |\n| And yes, there's a million and one discussions about why not. I could spend chapters recounting the whole history, but honestly I just don't care to. I think this syntax is ugly, and many others do, too. And some love it! If you're in the latter camp, though I rarely do something like this, I'm just going to say: **just accept it**. It's too late for any more debate or pleading. |\n\nThe `#whatever` syntax (including `this.#whatever` form) is only valid inside `class` bodies. It will throw syntax errors if used outside of a `class`.\n\nUnlike public fields/instance members, private fields/instance members *must* be declared in the `class` body. You cannot add a private member to a class declaration dynamically while in the constructor method; `this.#whatever = ..` type assignments only work if the `#whatever` private field is declared in the class body. Moreover, though private fields can be re-assigned, they cannot be `delete`d from an instance, the way a public field/class member can.\n\n#### Subclassing + Privates\n\nI warned earlier that subclassing with classes that have private members/methods can be a limiting trap. But that doesn't mean they cannot be used together.\n\nBecause \"inheritance\" in JS is sharing (through the `[[Prototype]]` chain), if you invoke an inherited method in a subclass, and that inherited method in turn accesses/invokes privates in its host (base) class, this works fine:\n\n```js\nclass Point2d { /* .. */ }\n\nclass Point3d extends Point2d {\n    z\n    constructor(x,y,z) {\n        super(x,y);\n        this.z = z;\n    }\n}\n\nvar one = new Point3d(3,4,5);\n```\n\nThe `super(x,y)` call in this constructor invokes the inherited base class constructor (`Point2d(..)`), which itself accesses `Point2d`'s private method `#assignID()` (see the earlier snippet). No exception is thrown, even though `Point3d` cannot directly see or access the `#ID` / `#assignID()` privates that are indeed stored on the instance (named `one` here).\n\nIn fact, even the inherited `static samePoint(..)` function will work from either `Point3d` or `Point2d`:\n\n```js\nPoint2d.samePoint(one,one);         // true\nPoint3d.samePoint(one,one);         // true\n```\n\nActually, that shouldn't be that surprising, since:\n\n```js\nPoint2d.samePoint === Point3d.samePoint;\n```\n\nThe inherited function reference is *the exact same function* as the base function reference; it's not some copy of the function. Because the function in question has no `this` reference in it, no matter from where it's invoked, it should produce the same outcome.\n\nIt's still a shame though that `Point3d` has no way to access/influence, or indeed even knowledge of, the `#ID` / `#assignID()` privates from `Point2d`:\n\n```js\nclass Point2d { /* .. */ }\n\nclass Point3d extends Point2d {\n    z\n    constructor(x,y,z) {\n        super(x,y);\n        this.z = z;\n\n        console.log(this.#ID);      // will throw!\n    }\n}\n```\n\n| WARNING: |\n| :--- |\n| Notice that this snippet throws an early static syntax error at the time of defining the `Point3d` class, before ever even getting a chance to create an instance of the class. The same exception would be thrown if the reference was `super.#ID` instead of `this.#ID`. |\n\n#### Existence Check\n\nKeep in mind that only the `class` itself knows about, and can therefore check for, such a private field/method.\n\nYou may want to check to see if a private field/method exists on an object instance. For example (as shown below), you may have a static function or method in a class, which receives an external object reference passed in. To check to see if the passed-in object reference is of this same class (and therefore has the same private members/methods in it), you basically need to do a \"brand check\" against the object.\n\nSuch a check could be rather convoluted, because if you access a private field that doesn't already exist on the object, you get a JS exception thrown, requiring ugly `try..catch` logic.\n\nBut there's a cleaner approach, so called an \"ergonomic brand check\", using the `in` keyword:\n\n```js\nclass Point2d {\n    // statics\n    static samePoint(point1,point2) {\n        // \"ergonomic brand checks\"\n        if (#ID in point1 && #ID in point2) {\n            return point1.#ID === point2.#ID;\n        }\n        return false;\n    }\n\n    // privates\n    #ID = null\n    #assignID() {\n        this.#ID = Math.round(Math.random() * 1e9);\n    }\n\n    // publics\n    x\n    y\n    constructor(x,y) {\n        this.#assignID();\n        this.x = x;\n        this.y = y;\n    }\n}\n\nvar one = new Point2d(3,4);\nvar two = new Point2d(3,4);\n\nPoint2d.samePoint(one,two);         // false\nPoint2d.samePoint(one,one);         // true\n```\n\nThe `#privateField in someObject` check will not throw an exception if the field isn't found, so it's safe to use without `try..catch` and use its simple boolean result.\n\n#### Exfiltration\n\nEven though a member/method may be declared with *private* visibility, it can still be exfiltrated (extracted) from a class instance:\n\n```js\nvar id, func;\n\nclass Point2d {\n    // privates\n    #ID = null\n    #assignID() {\n        this.#ID = Math.round(Math.random() * 1e9);\n    }\n\n    // publics\n    x\n    y\n    constructor(x,y) {\n        this.#assignID();\n        this.x = x;\n        this.y = y;\n\n        // exfiltration\n        id = this.#ID;\n        func = this.#assignID;\n    }\n}\n\nvar point = new Point2d(3,4);\n\nid;                     // 7392851012 (...for example)\n\nfunc;                   // function #assignID() { .. }\nfunc.call(point,42);\n\nfunc.call({},100);\n// TypeError: Cannot write private member #ID to an\n// object whose class did not declare it\n```\n\nThe main concern here is to be careful when passing private methods as callbacks (or in any way exposing privates to other parts of the program). There's nothing stopping you from doing so, which can create a bit of an unintended privacy disclosure.\n\n### Private Statics\n\nStatic properties and functions can also use `#` to be marked as private:\n\n```js\nclass Point2d {\n    static #errorMsg = \"Out of bounds.\"\n    static #printError() {\n        console.log(`Error: ${this.#errorMsg}`);\n    }\n\n    // publics\n    x\n    y\n    constructor(x,y) {\n        if (x > 100 || y > 100) {\n            Point2d.#printError();\n        }\n        this.x = x;\n        this.y = y;\n    }\n}\n\nvar one = new Point2d(30,400);\n// Error: Out of bounds.\n```\n\nThe `#printError()` static private function here has a `this`, but that's referencing the `Point2d` class, not an instance. As such, the `#errorMsg` and `#printError()` are independent of instances and thus are best as statics. Moreover, there's no reason for them to be accessible outside the class, so they're marked private.\n\nRemember: private statics are similarly not-inherited by subclasses just as private members/methods are not.\n\n#### Gotcha: Subclassing With Static Privates and `this`\n\nRecall that inherited methods, invoked from a subclass, have no trouble accessing (via `this.#whatever` style references) any privates from their own base class:\n\n```js\nclass Point2d {\n    // ..\n\n    getID() {\n        return this.#ID;\n    }\n\n    // ..\n}\n\nclass Point3d extends Point2d {\n    // ..\n\n    printID() {\n        console.log(`ID: ${this.getID()}`);\n    }\n}\n\nvar point = new Point3d(3,4,5);\npoint.printID();\n// ID: ..\n```\n\nThat works just fine.\n\nUnfortunately, and (to me) quite unexpectedly/inconsistently, the same is not true of private statics accessed from inherited public static functions:\n\n```js\nclass Point2d {\n    static #errorMsg = \"Out of bounds.\"\n    static printError() {\n        console.log(`Error: ${this.#errorMsg}`);\n    }\n\n    // ..\n}\n\nclass Point3d extends Point2d {\n    // ..\n}\n\nPoint2d.printError();\n// Error: Out of bounds.\n\nPoint3d.printError === Point2d.printError;\n// true\n\nPoint3d.printError();\n// TypeError: Cannot read private member #errorMsg\n// from an object whose class did not declare it\n```\n\nThe `printError()` static is inherited (shared via `[[Prototype]]`) from `Point2d` to `Point3d` just fine, which is why the function references are identical. Like the non-static snippet just above, you might have expected the `Point3d.printError()` static invocation to resolve via the `[[Prototype]]` chain to its original base class (`Point2d`) location, thereby letting it access the base class's `#errorMsg` static private.\n\nBut it fails, as shown by the last statement in that snippet. The reason it fails here, but not with the previous snippet, is a convoluted brain twister. I'm not going to dig into the *why* explanation here, frankly because it boils my blood to do so.\n\nThere's a *fix*, though. In the static function, instead of `this.#errorMsg`, swap that for `Point2d.#errorMsg`, and now it works:\n\n```js\nclass Point2d {\n    static #errorMsg = \"Out of bounds.\"\n    static printError() {\n        // the fixed reference vvvvvv\n        console.log(`Error: ${Point2d.#errorMsg}`);\n    }\n\n    // ..\n}\n\nclass Point3d extends Point2d {\n    // ..\n}\n\nPoint2d.printError();\n// Error: Out of bounds.\n\nPoint3d.printError();\n// Error: Out of bounds.  <-- phew, it works now!\n```\n\nIf public static functions are being inherited, use the class name to access any private statics instead of using `this.` references. Beware that gotcha!\n\n## Class Example\n\nOK, we've laid out a bunch of disparate class features. I want to wrap up this chapter by trying to illustrate a sampling of these capabilities in a single example that's a little less basic/contrived.\n\n```js\nclass CalendarItem {\n    static #UNSET = Symbol(\"unset\")\n    static #isUnset(v) {\n        return v === this.#UNSET;\n    }\n    static #error(num) {\n        return this[`ERROR_${num}`];\n    }\n    static {\n        for (let [idx,msg] of [\n            \"ID is already set.\",\n            \"ID is unset.\",\n            \"Don't instantiate 'CalendarItem' directly.\",\n        ].entries()) {\n            this[`ERROR_${(idx+1)*100}`] = msg;\n        }\n    }\n    static isSameItem(item1,item2) {\n        if (#ID in item1 && #ID in item2) {\n            return item1.#ID === item2.#ID;\n        }\n        else {\n            return false;\n        }\n    }\n\n    #ID = CalendarItem.#UNSET\n    #setID(id) {\n        if (CalendarItem.#isUnset(this.#ID)) {\n            this.#ID = id;\n        }\n        else {\n            throw new Error(CalendarItem.#error(100));\n        }\n    }\n\n    description = null\n    startDateTime = null\n\n    constructor() {\n        if (new.target !== CalendarItem) {\n            let id = Math.round(Math.random() * 1e9);\n            this.#setID(id);\n        }\n        else {\n            throw new Error(CalendarItem.#error(300));\n        }\n    }\n    getID() {\n        if (!CalendarItem.#isUnset(this.#ID)) {\n            return this.#ID;\n        }\n        else {\n            throw new Error(CalendarItem.#error(200));\n        }\n    }\n    getDateTimeStr() {\n        if (this.startDateTime instanceof Date) {\n            return this.startDateTime.toUTCString();\n        }\n    }\n    summary() {\n        console.log(`(${\n            this.getID()\n        }) ${\n            this.description\n        } at ${\n            this.getDateTimeStr()\n        }`);\n    }\n}\n\nclass Reminder extends CalendarItem {\n    #complete = false;  // <-- no ASI, semicolon needed\n\n    [Symbol.toStringTag] = \"Reminder\"\n    constructor(description,startDateTime) {\n        super();\n\n        this.description = description;\n        this.startDateTime = startDateTime;\n    }\n    isComplete() {\n        return !!this.#complete;\n    }\n    markComplete() {\n        this.#complete = true;\n    }\n    summary() {\n        if (this.isComplete()) {\n            console.log(`(${this.getID()}) Complete.`);\n        }\n        else {\n            super.summary();\n        }\n    }\n}\n\nclass Meeting extends CalendarItem {\n    #getEndDateTimeStr() {\n        if (this.endDateTime instanceof Date) {\n            return this.endDateTime.toUTCString();\n        }\n    }\n\n    endDateTime = null;  // <-- no ASI, semicolon needed\n\n    [Symbol.toStringTag] = \"Meeting\"\n    constructor(description,startDateTime,endDateTime) {\n        super();\n\n        this.description = description;\n        this.startDateTime = startDateTime;\n        this.endDateTime = endDateTime;\n    }\n    getDateTimeStr() {\n        return `${\n            super.getDateTimeStr()\n        } - ${\n            this.#getEndDateTimeStr()\n        }`;\n    }\n}\n```\n\nTake some time to read and digest those `class` definitions. Did you spot most of the `class` features we talked about in this chapter?\n\n| NOTE: |\n| :--- |\n| One question you may have: why didn't I move the repeated logic of `description` and `startDateTime` setting from both subclass constructors into the single base constructor? This is a nuanced point, but it's not my intention that `CalendarItem` ever be directly instantiated; it's what in class-oriented terms we refer to as an \"abstract class\". That's why I'm using `new.target` to throw an error if the `CalendarItem` class is ever directly instantiated! So I don't want to imply by signature that the `CalendarItem(..)` constructor should ever be directly used. |\n\nLet's now see these three classes in use:\n\n```js\nvar callMyParents = new Reminder(\n    \"Call my parents to say hi\",\n    new Date(\"July 7, 2022 11:00:00 UTC\")\n);\ncallMyParents.toString();\n// [object Reminder]\ncallMyParents.summary();\n// (586380912) Call my parents to say hi at\n// Thu, 07 Jul 2022 11:00:00 GMT\ncallMyParents.markComplete();\ncallMyParents.summary();\n// (586380912) Complete.\ncallMyParents instanceof Reminder;\n// true\ncallMyParents instanceof CalendarItem;\n// true\ncallMyParents instanceof Meeting;\n// false\n\n\nvar interview = new Meeting(\n    \"Job Interview: ABC Tech\",\n    new Date(\"June 23, 2022 08:30:00 UTC\"),\n    new Date(\"June 23, 2022 09:15:00 UTC\")\n);\ninterview.toString();\n// [object Meeting]\ninterview.summary();\n// (994337604) Job Interview: ABC Tech at Thu,\n// 23 Jun 2022 08:30:00 GMT - Thu, 23 Jun 2022\n// 09:15:00 GMT\ninterview instanceof Meeting;\n// true\ninterview instanceof CalendarItem;\n// true\ninterview instanceof Reminder;\n// false\n\n\nReminder.isSameItem(callMyParents,callMyParents);\n// true\nMeeting.isSameItem(callMyParents,interview);\n// false\n```\n\nAdmittedly, some bits of this example are a little contrived. But honestly, I think pretty much all of this is plausible and reasonable usages of the various `class` features.\n\nBy the way, there's probably a million different ways to structure the above code logic. I'm by no means claiming this is the *right* or *best* way to do so. As an exercise for the reader, try your hand and writing it yourself, and take note of things you did differently than my approach.\n\n[^POLP]: \"Principle of Least Privilege\", Wikipedia; https://en.wikipedia.org/wiki/Principle_of_least_privilege ; Accessed July 2022\n"
  },
  {
    "path": "objects-classes/ch4.md",
    "content": "# You Don't Know JS Yet: Objects & Classes - 2nd Edition\n# Chapter 4: This Works\n\n| NOTE: |\n| :--- |\n| Work in progress |\n\nWe've seen the `this` keyword used quite a bit so far, but haven't really dug in to understand exactly how it works in JS. It's time we do so.\n\nBut to properly understand `this` in JS, you need to set aside any preconceptions you may have, especially assumptions from how `this` works in other programming languages you may have experience in.\n\nHere's the most important thing to understand about `this`: the determination of what value (usually, object) `this` points at is not made at author time, but rather determined at runtime. That means you cannot simply look at a `this`-aware function (even a method in a `class` definition) and know for sure what `this` will hold while that function runs.\n\nInstead, you have to find each place the function is invoked, and look at *how* it's invoked (not even *where* matters). That's the only way to fully answer what `this` will point to.\n\nIn fact, a single `this`-aware function can be invoked at least four different ways, and any of those approaches will end up assigning a different `this` for that particular function invocation.\n\nSo the typical question we might ask when reading code -- \"What does `this` point to the function?\" -- is not actually a valid question. The question you really have to ask is, \"When the function is invoked a certain way, what `this` will be assigned for that invocation?\"\n\nIf your brain is already twisting around just reading this chapter intro... good! Settle in for a rewiring of how you think about `this` in JS.\n\n## This Aware\n\nI used the phrase `this`-aware just a moment ago. But what exactly do I mean by that?\n\nAny function that has a `this` keyword in it.\n\nIf a function does not have `this` in it anywhere, then the rules of how `this` behaves don't affect that function in any way. But if it *does* have even a single `this` in it, then you absolutely cannot determine how the function will behave without figuring out, for each invocation of the function, what `this` will point to.\n\nIt's sort of like the `this` keyword is a placeholder in a template. That placeholder's value-replacement doesn't get determined when we author the code; it gets determined while the code is running.\n\nYou might think I'm just playing word games here. Of course, when you write the program, you write out all the calls to each function, so you've already determined what the `this` is going to be when you authored the code, right? Right!?\n\nNot so fast!\n\nFirst of all, you don't always write all the code that invokes your function(s). Your `this`-aware function(s) might be passed as a callback(s) to some other code, either in your code base, or in a third-party framework/utility, or even inside a native built-in mechanism of the language or environment that's hosting your program.\n\nBut even aside from passing functions as callbacks, several mechanisms in JS allow for conditional runtime behaviors to determine which value (again, usually object) will be set for the `this` of a particular function invocation. So even though you may have written all that code, you *at best* will have to mentally execute the different conditions/paths that end up affecting the function invocation.\n\nAnd why does all this matter?\n\nBecause it's not just you, the author of the code, that needs to figure this stuff out. It's *every single reader* of your code, forever. If anyone (even your future self) wants to read a piece of code that defines a `this`-aware function, that inevitably means that, to fully understand and predict its behavior, that person will have to find, read, and understand every single invocation of that function.\n\n### This Confuses Me\n\nNow, in fairness, that's already partially true if we consider a function's parameters. To understand how a function is going to work, we need to know what is being passed into it. So any function with at least one parameter is, in a similar sense, *argument*-aware -- meaning, what argument(s) is/are passed in and assigned to the parameter(s) of the function.\n\nBut with parameters, we often have a bit more of a hint from the function itself what the parameters will do and hold.\n\nWe often see the names of the parameters declared right in the function header, which goes a long way to explaining their nature/purpose. And if there are defaults for the parameters, we often see them declared inline with `= whatever` clauses. Moreover, depending on the code style of the author, we may see in the first several lines of the function a set of logic that applies to these parameters; this could be assertions about the values (disallowed values, etc), or even modifications (type conversion, formatting, etc).\n\nActually, `this` is very much like a parameter to a function, but it's an implicit parameter rather than an explicit one. You don't see any signal that `this` is going to be used, in the function header anywhere. You have to read the entire function body to see if `this` appears anywhere.\n\nThe \"parameter\" name is always `this`, so we don't get much of a hint as to its nature/purpose from such a general name. In fact, there's historically a lot of confusion of what \"this\" even is supposed to mean. And we rarely see much if anything done to validate/convert/etc the `this` value applied to a function invocation. In fact, virtually all `this`-aware code I've seen just neatly assumes the `this` \"parameter\" is holding exactly what value is expected. Talk about **a trap for unexpected bugs!**\n\n### So What Is This?\n\nIf `this` is an implicit parameter, what's its purpose? What's being passed in?\n\nHopefully you have already read the \"Scope & Closures\" book of this series. If not, I strongly encourage you to circle back and read that one once you've finished this one. In that book, I explained at length how scopes (and closures!) work, an especially important characteristic of functions.\n\nLexical scope (including all the variables closed over) represents a *static* context for the function's lexical identifier references to be evaluated against. It's fixed/static because at author time, when you place functions and variable declarations in various (nested) scopes, those decisions are fixed, and unaffected by any runtime conditions.\n\nBy contrast, a different programming language might offer *dynamic* scope, where the context for a function's variable references is not determined by author-time decisions but by runtime conditions. Such a system would be undoubtedly more flexible than static context -- though with flexibility often comes complexity.\n\nTo be clear: JS scope is always and only lexical and *static* (if we ignore non-strict mode cheats like `eval(..)` and `with`). However, one of the truly powerful things about JS is that it offers another mechanism with similar flexibility and capabilities to *dynamic* scope.\n\nThe `this` mechanism is, effectively, *dynamic* context (not scope); it's how a `this`-aware function can be dynamically invoked against different contexts -- something that's impossible with closure and lexical scope identifiers!\n\n### Why Is This So Implicit?\n\nYou might wonder why something as important as a *dynamic* context is handled as an implicit input to a function, rather than being an explicit argument passed in.\n\nThat's a very important question, but it's not one we can quite answer, yet. Hold onto that question though.\n\n### Can We Get On With This?\n\nSo why have I belabored *this* subject for a couple of pages now? You get it, right!? You're ready to move on.\n\nMy point is, you the author of code, and all other readers of the code even years or decades in the future, need to be `this`-aware. That's the choice, the burden, you place on the reading of such code. And yes, that goes for the choice to use `class` (see Chapter 3), as most class methods will be `this`-aware out of necessity.\n\nBe aware of *this* `this` choice in code you write. Do it intentionally, and do it in such a way as to produce more outcome benefit than burden. Make sure `this` usage in your code *carries its own weight*.\n\nLet me put it *this* way: don't use `this`-aware code unless you really can justify it, and you've carefully weighed the costs. Just because you've seen a lot of code examples slinging around `this` in others' code, doesn't mean that `this` belongs in *this* code you're writing.\n\nThe `this` mechanism in JS, paired with `[[Prototype]]` delegation, is an extremely powerful pillar of the language. But as the cliche goes: \"with great power comes great responsibility\". Anecdotally, even though I really like and appreciate *this* pillar of JS, probably less than 5% of the JS code I ever write uses it. And when I do, it's with restraint. It's not my default, go-to JS capability.\n\n## This Is It!\n\nOK, enough of the wordy lecture. You're ready to dive into `this` code, right?\n\nLet's revisit (and extend) `Point2d` from Chapter 3, but just as an object with data properties and functions on it, instead of using `class`:\n\n```js\nvar point = {\n    x: null,\n    y: null,\n\n    init(x,y) {\n        this.x = x;\n        this.y = y;\n    },\n    rotate(angleRadians) {\n        var rotatedX = this.x * Math.cos(angleRadians) -\n            this.y * Math.sin(angleRadians);\n        var rotatedY = this.x * Math.sin(angleRadians) +\n            this.y * Math.cos(angleRadians);\n        this.x = rotatedX;\n        this.y = rotatedY;\n    },\n    toString() {\n        return `(${this.x},${this.y})`;\n    },\n};\n```\n\nAs you can see, the `init(..)`, `rotate(..)`, and `toString()` functions are `this`-aware. You might be in the habit of assuming that the `this` reference will obviously always hold the `point` object. But that's not guaranteed in any way.\n\nKeep reminding yourself as you go through the rest of this chapter: the `this` value for a function is determined by *how* the function is invoked. That means you can't look at the function's definition, nor where the function is defined (not even the enclosing `class`!). In fact, it doesn't even matter where the function is called from.\n\nWe only need to look at *how* the functions are called; that's the only factor that matters.\n\n### Implicit Context Invocation\n\nConsider this call:\n\n```js\npoint.init(3,4);\n```\n\nWe're invoking the `init(..)` function, but notice the `point.` in front of it? This is an *implicit context* binding. It says to JS: invoke the `init(..)` function with `this` referencing `point`.\n\nThat is the *normal* way we'd expect a `this` to work, and that's also one of the most common ways we invoke functions. So the typical invocation gives us the intuitive outcome. That's a good thing!\n\n### Default Context Invocation\n\nBut what happens if we do this?\n\n```js\nconst init = point.init;\ninit(3,4);\n```\n\nYou might assume that we'd get the same outcome as the previous snippet. But that's not how JS `this` assignment works.\n\nThe *call-site* for the function is `init(3,4)`, which is different than `point.init(3,4)`. When there's no *implicit context* (`point.`), nor any other kind of `this` assignment mechanism, the *default context* assignment occurs.\n\nWhat will `this` reference when `init(3,4)` is invoked like that?\n\n*It depends.*\n\nUh oh. Depends? That sounds confusing.\n\nDon't worry, it's not as bad as it sounds. The *default context* assignment depends on whether the code is in strict-mode or not. But thankfully, virtually all JS code these days is running in strict-mode; for example, ESM (ES Modules) always run in strict-mode, as does code inside a `class` block. And virtually all transpiled JS code (via Babel, TypeScript, etc) is written to declare strict-mode.\n\nSo almost all of the time, modern JS code will be running in strict-mode, and thus the *default assignment* context won't \"depend\" on anything; it's pretty straightforward: `undefined`. That's it!\n\n| NOTE: |\n| :--- |\n| Keep in mind: `undefined` does not mean \"not defined\"; it means, \"defined with the special empty `undefined` value\". I know, I know... the name and meaning are mismatched. That's language legacy baggage, for you. (shrugging shoulders) |\n\nThat means `init(3,4)`, if run in strict-mode, would throw an exception. Why? Because the `this.x` reference in `init(..)` is a `.x` property access on `undefined` (i.e., `undefined.x`), which is not allowed:\n\n```js\n\"use strict\";\n\nvar point = { /* .. */ };\n\nconst init = point.init;\ninit(3,4);\n// TypeError: Cannot set properties of\n// undefined (setting 'x')\n```\n\nStop for a moment and consider: why would JS choose to default the context to `undefined`, so that any *default context* invocation of a `this`-aware function will fail with such an exception?\n\nBecause a `this`-aware function **always needs a `this`**. The invocation `init(3,4)` isn't providing a `this`, so that *is* a mistake, and *should* raise an exception so the mistake can be corrected. The lesson: never invoke a `this`-aware function without providing it a `this`!\n\nJust for completeness sake: in the less common non-strict mode, the *default context* is the global object -- JS defines it as `globalThis`, which in browser JS is essentially an alias to `window`, and in Node it's `global`. So, when `init(3,4)` runs in non-strict mode, the `this.x` expression is `globalThis.x` -- also known as `window.x` in the browser, or `global.x` in Node. Thus, `globalThis.x` gets set as `3` and `globalThis.y` gets set as `4`.\n\n```js\n// no strict-mode here, beware!\n\nvar point = { /* .. */ };\n\nconst init = point.init;\ninit(3,4);\n\nglobalThis.x;   // 3\nglobalThis.y;   // 4\npoint.x;        // null\npoint.y;        // null\n```\n\nThat's unfortunate, because it's almost certainly *not* the intended outcome. Not only is it bad if it's a global variable, but it's also *not* changing the property on our `point` object, so program bugs are guaranteed.\n\n| WARNING: |\n| :--- |\n| Ouch! Nobody wants accidental global variables implicitly created from all over the code. The lesson: always make sure your code is running in strict-mode! |\n\n### Explicit Context Invocation\n\nFunctions can alternately be invoked with *explicit context*, using the built-in `call(..)` or `apply(..)` utilities:\n\n```js\nvar point = { /* .. */ };\n\nconst init = point.init;\n\ninit.call( point, 3, 4 );\n// or: init.apply( point, [ 3, 4 ] )\n\npoint.x;        // 3\npoint.y;        // 4\n```\n\n`init.call(point,3,4)` is effectively the same as `point.init(3,4)`, in that both of them assign `point` as the `this` context for the `init(..)` invocation.\n\n| NOTE: |\n| :--- |\n| Both `call(..)` and `apply(..)` utilities take as their first argument a `this` context value; that's almost always an object, but can technically can be any value (number, string, etc). The `call(..)` utility takes subsequent arguments and passes them through to the invoked function, whereas `apply(..)` expects its second argument to be an array of values to pass as arguments. |\n\nIt might seem awkward to contemplate invoking a function with the *explicit context* assignment (`call(..)` / `apply(..)`) style in your program. But it's more useful than might be obvious at first glance.\n\nLet's recall the original snippet:\n\n```js\nvar point = {\n    x: null,\n    y: null,\n\n    init(x,y) {\n        this.x = x;\n        this.y = y;\n    },\n    rotate(angleRadians) { /* .. */ },\n    toString() {\n        return `(${this.x},${this.y})`;\n    },\n};\n\npoint.init(3,4);\n\nvar anotherPoint = {};\npoint.init.call( anotherPoint, 5, 6 );\n\npoint.x;                // 3\npoint.y;                // 4\nanotherPoint.x;         // 5\nanotherPoint.y;         // 6\n```\n\nAre you seeing what I did there?\n\nI wanted to define `anotherPoint`, but I didn't want to repeat the definitions of those `init(..)` / `rotate(..)` / `toString()` functions from `point`. So I \"borrowed\" a function reference, `point.init`, and explicitly set the empty object `anotherPoint` as the `this` context, via `call(..)`.\n\nWhen `init(..)` is running at that moment, `this` inside it will reference `anotherPoint`, and that's why the `x` / `y` properties (values `5` / `6`, respectively) get set there.\n\nAny `this`-aware functions can be borrowed like this: `point.rotate.call(anotherPoint, ..)`, `point.toString.call(anotherPoint)`.\n\n#### Revisiting Implicit Context Invocation\n\nAnother approach to share behavior between `point` and `anotherPoint` would have been:\n\n```js\nvar point = { /* .. */ };\n\nvar anotherPoint = {\n    init: point.init,\n    rotate: point.rotate,\n    toString: point.toString,\n};\n\nanotherPoint.init(5,6);\n\nanotherPoint.x;         // 5\nanotherPoint.y;         // 6\n```\n\nThis is another way of \"borrowing\" the functions, by adding shared references to the functions on any target object (e.g., `anotherPoint`). The call-site invocation `anotherPoint.init(5,6)` is the more natural/ergonomic style that relies on *implicit context* assignment.\n\nIt may seem this approach is a little cleaner, comparing `anotherPoint.init(5,6)` to `point.init.call(anotherPoint,5,6)`.\n\nBut the main downside is having to modify any target object with such shared function references, which can be verbose, manual, and error-prone. Sometimes such an approach is acceptable, but many other times, *explicit context* assignment with `call(..)` / `apply(..)` is more preferable.\n\n### New Context Invocation\n\nWe've so far seen three different ways of context assignment at the function call-site: *default*, *implicit*, and *explicit*.\n\nA fourth way to call a function, and assign the `this` for that invocation, is with the `new` keyword:\n\n```js\nvar point = {\n    // ..\n\n    init: function() { /* .. */ }\n\n    // ..\n};\n\nvar anotherPoint = new point.init(3,4);\n\nanotherPoint.x;     // 3\nanotherPoint.y;     // 4\n```\n\n| TIP: |\n| :--- |\n| This example has a bit of nuance to be explained. The `init: function() { .. }` form shown here -- specifically, a function expression assigned to a property -- is required for the function to be validly called with the `new` keyword. From previous snippets, the concise method form of `init() { .. }` defines a function that *cannot* be called with `new`. |\n\nYou've typically seen `new` used with `class` for creating instances. But as an underlying mechanism of the JS language, `new` is not inherently a `class` operation.\n\nIn a sense, the `new` keyword hijacks a function and forces its behavior into a different mode than a normal invocation. Here are the 4 special steps that JS performs when a function is invoked with `new`:\n\n1. create a brand new empty object, out of thin air.\n\n2. link the `[[Prototype]]` of that new empty object to the function's `.prototype` object (see Chapter 2).\n\n3. invoke the function with the `this` context set to that new empty object.\n\n4. if the function doesn't return its own object value explicitly (with a `return ..` statement), assume the function call should instead return the new object (from steps 1-3).\n\n| WARNING: |\n| :--- |\n| Step 4 implies that if you `new` invoke a function that *does* return its own object -- like `return { .. }`, etc -- then the new object from steps 1-3 is *not* returned. That's a tricky gotcha to be aware of, in that it effectively discards that new object before the program has a chance to receive and store a reference to it. Essentially, `new` should never be used to invoke a function that has explicit `return ..` statement(s) in it. |\n\nTo understand these 4 `new` steps more concretely, I'm going to illustrate them in code, as an alternate to using the `new` keyword:\n\n```js\n// alternative to:\n//   var anotherPoint = new point.init(3,4)\n\nvar anotherPoint;\n// this is a bare block to hide local\n// `let` declarations\n{\n    // (Step 1)\n    let tmpObj = {};\n\n    // (Step 2)\n    Object.setPrototypeOf(\n        tmpObj, point.init.prototype\n    );\n    // or: tmpObj.__proto__ = point.init.prototype\n\n    // (Step 3)\n    let res = point.init.call(tmpObj,3,4);\n\n    // (Step 4)\n    anotherPoint = (\n        typeof res !== \"object\" ? tmpObj : res\n    );\n}\n```\n\nClearly, the `new` invocation streamlines that set of manual steps!\n\n| TIP: |\n| :--- |\n| The `Object.setPrototypeOf(..)` in step 2 could also have been done via the `__proto__` property, such as `tmpObj.__proto__ = point.init.prototype`, or even as part of the object literal (step 1) with `tmpObj = { __proto__: point.init.prototype }`. |\n\nSkipping some of the formality of these steps, let's recall an earlier snippet and see how `new` approximates a similar outcome:\n\n```js\nvar point = { /* .. */ };\n\n// this approach:\nvar anotherPoint = {};\npoint.init.call(anotherPoint,5,6);\n\n// can instead be approximated as:\nvar yetAnotherPoint = new point.init(5,6);\n```\n\nThat's a bit nicer! But there's a caveat here.\n\nUsing the other functions that `point` holds against `anotherPoint` / `yetAnotherPoint`, we won't want to do with `new`. Why? Because `new` is creating a *new* object, but that's not what we want if we intend to invoke a function against an existing object.\n\nInstead, we'll likely use *explicit context* assignment:\n\n```js\npoint.rotate.call( anotherPoint, /*angleRadians=*/Math.PI );\n\npoint.toString.call( yetAnotherPoint );\n// (5,6)\n```\n\n### Review This\n\nWe've seen four rules for `this` context assignment in function calls. Let's put them in order of precedence:\n\n1. Is the function invoked with `new`, creating and setting a *new* `this`?\n\n2. Is the function invoked with `call(..)` or `apply(..)`, *explicitly* setting `this`?\n\n3. Is the function invoked with an object reference at the call-site (e.g., `point.init(..)`), *implicitly* setting `this`?\n\n4. If none of the above... are we in non-strict mode? If so, *default* the `this` to `globalThis`. But if in strict-mode, *default* the `this` to `undefined`.\n\nThese rules, *in this order*, are how JS determines the `this` for a function invocation. If multiple rules match a call-site (e.g., `new point.init.call(..)`), the first rule from the list to match wins.\n\nThat's it, you're now master over the `this` keyword. Well, not quite. There's a bunch more nuance to cover. But you're well on your way!\n\n## An Arrow Points Somewhere\n\nEverything I've asserted so far about `this` in functions, and how its determined based on the call-site, makes one giant assumption: that you're dealing with a *regular* function (or method).\n\nSo what's an *irregular* function?!? It looks like this:\n\n```js\nconst x = x => x <= x;\n```\n\n| NOTE: |\n| :--- |\n| Yes, I'm being a tad sarcastic and unfair to call an arrow function \"irregular\" and to use such a contrived example. It's a joke, ok? |\n\nHere's a real example of an `=>` arrow function:\n\n```js\nconst clickHandler = evt =>\n    evt.target.matches(\"button\") ?\n        this.theFormElem.submit() :\n        evt.stopPropagation();\n```\n\nFor comparison sake, let me also show the non-arrow equivalent:\n\n```js\nconst clickHandler = function(evt) {\n    evt.target.matches(\"button\") ?\n        this.theFormElem.submit() :\n        evt.stopPropagation();\n};\n```\n\nOr if we went a bit old-school about it -- this is my jam! -- we could try the standalone function declaration form:\n\n```js\nfunction clickHandler(evt) {\n    evt.target.matches(\"button\") ?\n        this.theFormElem.submit() :\n        evt.stopPropagation();\n}\n```\n\nOr if the function appeared as a method in a `class` definition, or as a concise method in an object literal, it would look like this:\n\n```js\n// ..\nclickHandler(evt) {\n    evt.target.matches(\"button\") ?\n        this.theFormElem.submit() :\n        evt.stopPropagation();\n}\n```\n\nWhat I really want to focus on is how each of these forms of the function will behave with respect to their `this` reference, and whether the first `=>` form differs from the others (hint: it does!). But let's start with a little quiz to see if you've been paying attention.\n\nFor each of those function forms just shown, how do we know what each `this` will reference?\n\n### Where's The Call-site?\n\nHopefully, you responded with something like: \"first, we need to see how the functions are called.\"\n\nFair enough.\n\nLet's say our program looks like this:\n\n```js\nvar infoForm = {\n    theFormElem: null,\n    theSubmitBtn: null,\n\n    init() {\n        this.theFormElem =\n            document.getElementById(\"the-info-form\");\n        this.theSubmitBtn =\n            theFormElem.querySelector(\"button[type=submit]\");\n\n        // is *this* the call-site?\n        this.theSubmitBtn.addEventListener(\n            \"click\",\n            this.clickHandler,\n            false\n        );\n    },\n\n    // ..\n}\n```\n\nAh, interesting. Half of you readers have never seen actual DOM API code like `getElementById(..)`, `querySelector(..)`, and `addEventListener(..)` before. I heard the confusion bells whistle just now!\n\n| NOTE: |\n| :--- |\n| Sorry, I'm dating myself, here. I've been doing this stuff long enough that I remember when we did that kind of code long before we had utilities like jQuery cluttering up the code with `$` everywhere. And after many years of front-end evolution, we seem to have landed somewhere quite a bit more \"modern\" -- at least, that's the prevailing presumption. |\n\nI'm guessing many of you these days are used to seeing component-framework code (React, etc) somewhat like this:\n\n```jsx\n// ..\n\ninfoForm(props) {\n    return (\n        <form ref={this.theFormElem}>\n            <button type=submit onClick=this.clickHandler>\n                Click Me\n            </button>\n        </form>\n    );\n}\n\n// ..\n```\n\nOf course, there's a bunch of other ways that code might be shaped, depending on if you're using one framework or another, etc.\n\nOr maybe you're not even using `class` / `this` style components anymore, because you've moved everything to hooks and closures. In any case, for our discussion purposes, *this* chapter is all about `this`, so we need to stick to a coding style like the above, to have code related to the discussion.\n\nAnd neither of those two previous code snippets show the `clickHandler` function being defined. But I've said repeatedly so far, that doesn't matter; all that matters is ... what? say it with me... all that matters is *how* the function is invoked.\n\nSo how is `clickHandler` being invoked? What's the call-site, and which context assignment rule does it match?\n\n### Hidden From Sight\n\nIf you're stuck, don't worry. I'm deliberately making this difficult, to point something very important out.\n\nWhen the `\"click\"` or `onClick=` event handler bindings happen, in both cases, we specified `this.clickHandler`, which implies that there is a `this` context object with a property on it called `clickHandler`, which is holding our function definition.\n\nSo, is `this.clickHandler` the call-site? If it was, what assignment rule applies? The *implicit context* rule (#3)?\n\nUnfortunately, no.\n\nThe problem is, **we cannot actually see the call-site** in this program. Uh oh.\n\nIf we can't see the call-site, how do we know *how* the function is going to actually get called?\n\n*That's* the exact point I'm making.\n\nIt doesn't matter that we passed in `this.clickHandler`. That is merely a reference to a function object value. It's not a call-site.\n\nUnder the covers, somewhere inside a framework, library, or even the JS environment itself, when a user clicks the button, a reference to the `clickHandler(..)` function is going to be invoked. And as we've implied, that call-site is even going to pass in the DOM event object as the `evt` argument.\n\nSince we can't see the call-site, we have to *imagine* it. Might it look like...?\n\n```js\n// ..\neventCallback( domEventObj );\n// ..\n```\n\nIf it did, which `this` rule would apply? The *default context* rule (#4)?\n\nOr, what if the call-site looked like this...?\n\n```js\n// ..\neventCallback.call( domElement, domEventObj );\n```\n\nNow which `this` rule would apply? The *explicit context* rule (#2)?\n\nUnless you open and view the source code for the framework/library, or read the documentation/specification, you won't *know* what to expect of that call-site. Which means that predicting, ultimately, what `this` points to in the `clickHandler` function you write, is... to put it mildly... a bit convoluted.\n\n### *This* Is Wrong\n\nTo spare you any more pain here, I'll cut to the chase.\n\nPretty much all implementations of a click-handler mechanism are going to do something like the `.call(..)`, and they're going to set the DOM element (e.g., button) the event listener is bound to, as the *explicit context* for the invocation.\n\nHmmm... is that ok, or is that going to be a problem?\n\nRecall that our `clickHandler(..)` function is `this`-aware, and that its `this.theFormElem` reference implies referencing an object with a `theFormElem` property, which in turn is pointing at the parent `<form>` element. DOM buttons do not, by default, have a `theFormElem` property on them.\n\nIn other words, the `this` reference that our event handler will have set for it is almost certainly wrong. Oops.\n\nUnless we want to rewrite the `clickHandler` function, we're going to need to fix that.\n\n### Fixing `this`\n\nLet's consider some options to address the mis-assignment. To keep things focused, I'll stick to this style of event binding for the discussion:\n\n```js\nthis.submitBtnaddEventListener(\n    \"click\",\n    this.clickHandler,\n    false\n);\n```\n\nHere's one way to address it:\n\n```js\n// store a fixed reference to the current\n// `this` context\nvar context = this;\n\nthis.submitBtn.addEventListener(\n    \"click\",\n    function handler(evt){\n        return context.clickHandler(evt);\n    },\n    false\n);\n```\n\n| TIP: |\n| :--- |\n| Most older JS code that uses this approach will say something like `var self = this` instead of the `context` name I'm giving it here. \"Self\" is a shorter word, and sounds cooler. But it's also entirely the wrong semantic meaning. The `this` keyword is not a \"self\" reference to the function, but rather the context for that current function invocation. Those may seem like the same thing at a glance, but they're completely different concepts, as different as apples and a Beatles song. So... to paraphrase them, \"Hey developer, don't make it bad. Take a sad `self` and make it better `context`.\" |\n\nWhat's going on here? I recognized that the enclosing code, where the `addEventListener` call is going to run, has a current `this` context that is correct, and we need to ensure that same `this` context is applied when `clickHandler(..)` gets invoked.\n\nI defined a surrounding function (`handler(..)`) and then forced the call-site to look like:\n\n```js\ncontext.clickHandler(evt);\n```\n\n| TIP: |\n| :--- |\n| Which `this` context assignment rule is applied here? That's right, the *implicit context* rule (#3). |\n\nNow, it doesn't matter what the internal call-site of the library/framework/environment looks like. But, why?\n\nBecause we're now *actually* in control of the call-site. It doesn't matter how `handler(..)` gets invoked, or what its `this` is assigned. It only matters than when `clickHandler(..)` is invoked, the `this` context is set to what we wanted.\n\nI pulled off that trick not only by defining a surrounding function (`handler(..)`) so I can control the call-site, but... and this is important, so don't miss it... I defined `handler(..)` as a NON-`this`-aware function! There's no `this` keyword inside of `handler(..)`, so whatever `this` gets set (or not) by the library/framework/environment, is completely irrelevant.\n\nThe `var context = this` line is critical to the trick. It defines a lexical variable `context`, which is not some special keyword, holding a snapshot of the value in the outer `this`. Then inside `clickHandler`, we merely reference a lexical variable (`context`), no relative/magic `this` keyword.\n\n### Lexical This\n\nThe name for this pattern, by the way, is \"lexical this\", meaning a `this` that behaves like a lexical scope variable instead of like a dynamic context binding.\n\nBut it turns out JS has an easier way of performing the \"lexical this\" magic trick. Are you ready for the trick reveal!?\n\n...\n\nThe `=>` arrow function! Tada!\n\nThat's right, the `=>` function is, unlike all other function forms, special, in that it's not special at all. Or, rather, that it doesn't define anything special for `this` behavior whatsoever.\n\nIn an `=>` function, the `this` keyword... **is not a keyword**. It's absolutely no different from any other variable, like `context` or `happyFace` or `foobarbaz`.\n\nLet me illustrate *this* point more directly:\n\n```js\nfunction outer() {\n    console.log(this.value);\n\n    // define a return an \"inner\"\n    // function\n    var inner = () => {\n        console.log(this.value);\n    };\n\n    return inner;\n}\n\nvar one = {\n    value: 42,\n};\nvar two = {\n    value: \"sad face\",\n};\n\nvar innerFn = outer.call(one);\n// 42\n\ninnerFn.call(two);\n// 42   <-- not \"sad face\"\n```\n\nThe `innerFn.call(two)` would, for any *regular* function definition, have resulted in `\"sad face\"` here. But since the `inner` function we defined and returned (and assigned to `innerFn`) was an *irregular* `=>` arrow function, it has no special `this` behavior, but instead has \"lexical this\" behavior.\n\nWhen the `innerFn(..)` (aka `inner(..)`) function is invoked, even with an *explicit context* assignment via `.call(..)`, that assignment is ignored.\n\n| NOTE: |\n| :--- |\n| I'm not sure why `=>` arrow functions even have a `call(..)` / `apply(..)` on them, since they are silent no-op functions. I guess it's for consistency with normal functions. But as we'll see later, there are other inconsistencies between *regular* functions and *irregular* `=>` arrow functions. |\n\nWhen a `this` is encountered (`this.value`) inside an `=>` arrow function, `this` is treated like a normal lexical variable, not a special keyword. And since there is no `this` variable in that function itself, JS does what it always does with lexical variables: it goes up one level of lexical scope -- in this case, to the surrounding `outer(..)` function, and it checks to see if there's any registered `this` in that scope.\n\nLuckily, `outer(..)` is a *regular* function, which means it has a normal `this` keyword. And the `outer.call(one)` invocation assigned `one` to its `this`.\n\nSo, `innerFn.call(two)` is invoking `inner()`, but when `inner()` looks up a value for `this`, it gets... `one`, not `two`.\n\n#### Back To The... Button\n\nYou thought I was going to make a pun joke and say \"future\" there, didn't you!?\n\nA more direct and appropriate way of solving our earlier issue, where we had done `var context = this` to get a sort of faked \"lexical this\" behavior, is to use the `=>` arrow function, since its primary design feature is... \"lexical this\".\n\n```js\nthis.submitBtn.addEventListener(\n    \"click\",\n    evt => this.clickHandler(evt),\n    false\n);\n```\n\nBoom! Problem solved! Mic drop!\n\nHear me on *this*: the `=>` arrow function is *not* -- I repeat, *not* -- about typing fewer characters. The primary point of the `=>` function being added to JS was to give us \"lexical this\" behavior without having to resort to `var context = this` (or worse, `var self = this`) style hacks.\n\n| TIP: |\n| :--- |\n| If you need \"lexical this\", always prefer an `=>` arrow function. If you don't need \"lexical this\", well... the `=>` arrow function might not be the best tool for the job. |\n\n#### Confession Time\n\nI've said all along in this chapter, that how you write a function, and where you write the function, has *nothing* to do with how its `this` will be assigned.\n\nFor regular functions, that's true. But when we consider an irregular `=>` arrow function, it's not entirely accurate anymore.\n\nRecall the original `=>` form of `clickHandler` from earlier in the chapter?\n\n```js\nconst clickHandler = evt =>\n    evt.target.matches(\"button\") ?\n        this.theFormElem.submit() :\n        evt.stopPropagation();\n```\n\nIf we use that form, in the same context as our event binding, it could look like this:\n\n```js\nconst clickHandler = evt =>\n    evt.target.matches(\"button\") ?\n        this.theFormElem.submit() :\n        evt.stopPropagation();\n\nthis.submitBtn.addEventListener(\"click\",clickHandler,false);\n```\n\nA lot of developers prefer to even further reduce it, to an inline `=>` arrow function:\n\n```js\nthis.submitBtn.addEventListener(\n    \"click\",\n    evt => evt.target.matches(\"button\") ?\n        this.theFormElem.submit() :\n        evt.stopPropagation(),\n    false\n);\n```\n\nWhen we write an `=>` arrow function, we know for sure that its `this` binding will exactly be the current `this` binding of whatever surrounding function is running, regardless of what the call-site of the `=>` arrow function looks like. So in other words, *how* we wrote the `=>` arrow function, and *where* we wrote it, does matter.\n\nThat doesn't fully answer the `this` question, though. It just shifts the question to *how the enclosing function was invoked*. Actually, the focus on the call-site is still the only thing that matters.\n\nBut the nuance I'm confessing to having omitted until *this* moment is: it matters *which* call-site we consider, not just *any* call-site in the current call stack. The call-site that matters is, the nearest function-invocation in the current call stack ***that actually assigns a `this` context***.\n\nSince an `=>` arrow function never has a `this`-assigning call-site (no matter what), that call-site isn't relevant to the question. We have to keep stepping up the call stack until we find a function invocation that *is* `this`-assigning -- even if such invoked function is not itself `this`-aware.\n\n**THAT** is the only call-site that matters.\n\n#### Find The Right Call-Site\n\nLet me illustrate, with a convoluted mess of a bunch of nested functions/calls:\n\n```js\nglobalThis.value = { result: \"Sad face\" };\n\nfunction one() {\n    function two() {\n        var three = {\n            value: { result: \"Hmmm\" },\n\n            fn: () => {\n                const four = () => this.value;\n                return four.call({\n                    value: { result: \"OK\", },\n                });\n            },\n        };\n        return three.fn();\n    };\n    return two();\n}\n\nnew one();          // ???\n```\n\nCan you run through that (nightmare) in your head and determine what will be returned from the `new one()` invocation?\n\nIt could be any of these:\n\n```js\n// from `four.call(..)`:\n{ result: \"OK\" }\n\n// or, from `three` object:\n{ result: \"Hmmm\" }\n\n// or, from the `globalThis.value`:\n{ result: \"Sad face\" }\n\n// or, empty object from the `new` call:\n{}\n```\n\nThe call-stack for that `new one()` invocation is:\n\n```\nfour         |\nthree.fn     |\ntwo          | (this = globalThis)\none          | (this = {})\n[ global ]   | (this = globalThis)\n```\n\nSince `four()` and `fn()` are both `=>` arrow functions, the `three.fn()` and `four.call(..)` call-sites are not `this`-assigning; thus, they're irrelevant for our query. What's the next invocation to consider in the call-stack? `two()`. That's a regular function (it can accept `this`-assignment), and the call-site matches the *default context* assignment rule (#4). Since we're not in strict-mode, `this` is assigned `globalThis`.\n\nWhen `four()` is running, `this` is just a normal variable. It looks then to its containing function (`three.fn()`), but it again finds a function with no `this`. So it goes up another level, and finds a `two()` *regular* function that has a `this` defined. And that `this` is `globalThis`. So the `this.value` expression resolves to `globalThis.value`, which returns us... `{ result: \"Sad face\" }`.\n\n...\n\nTake a deep breath. I know that's a lot to mentally process. And in fairness, that's a super contrived example. You'll almost never see all that complexity mixed in one call-stack.\n\nBut you absolutely will find mixed call-stacks in real programs. You need to get comfortable with the analysis I just illustrated, to be able to unwind the call-stack until you find the most recent `this`-assigning call-site.\n\nRemember the addage I quoted earlier: \"with great power comes great responsibility\". Choosing `this`-oriented code (even `class`es) means choosing both the flexibility it affords us, as well as needing to be comfortable navigating the call-stack to understand how it will behave.\n\nThat's the only way to effectively write (and later read!) `this`-aware code.\n\n### This Is Bound To Come Up\n\nBacking up a bit, there's another option if you don't want to use an `=>` arrow function's \"lexical this\" behavior to address the button event handler functionality.\n\nIn addition to `call(..)` / `apply(..)` -- these invoke functions, remember! -- JS functions also have a third utility built in, called `bind(..)` -- which does *not* invoke the function, just to be clear.\n\nThe `bind(..)` utility defines a *new* wrapped/bound version of a function, where its `this` is preset and fixed, and cannot be overridden with a `call(..)` or `apply(..)`, or even an *implicit context* object at the call-site:\n\n```js\nthis.submitBtn.addEventListener(\n    \"click\",\n    this.clickHandler.bind(this),\n    false\n);\n```\n\nSince I'm passing in a `this`-bound function as the event handler, it similarly doesn't matter how that utility tries to set a `this`, because I've already forced the `this` to be what I wanted: the value of `this` from the surrounding function invocation context.\n\n#### Hardly New\n\nThis pattern is often referred to as \"hard binding\", since we're creating a function reference that is strongly bound to a particular `this`. A lot of JS writings have claimed that the `=>` arrow function is essentially just syntax for the `bind(this)` hard-binding. It's not. Let's dig in.\n\nIf you were going to create a `bind(..)` utility, it might look kinda like *this*:\n\n```js\nfunction bind(fn,context) {\n    return function bound(...args){\n        return fn.apply(context,args);\n    };\n}\n```\n\n| NOTE: |\n| :--- |\n| This is not actually how `bind(..)` is implemented. The behavior is more sophisticated and nuanced. I'm only illustrating one portion of its behavior in this snippet. |\n\nDoes that look familiar? It's using the good ol' fake \"lexical this\" hack. And under the covers, it's an *explicit context* assignment, in this case via `apply(..)`.\n\nSo wait... doesn't that mean we could just do it with an `=>` arrow function?\n\n```js\nfunction bind(fn,context) {\n    return (...args) => fn.apply(context,args);\n}\n```\n\nEh... not quite. As with most things in JS, there's a bit of nuance. Let me illustrate:\n\n```js\n// candidate implementation, for comparison\nfunction fakeBind(fn,context) {\n    return (...args) => fn.apply(context,args);\n}\n\n// test subject\nfunction thisAwareFn() {\n    console.log(`Value: ${this.value}`);\n}\n\n// control data\nvar obj = {\n    value: 42,\n};\n\n// experiment\nvar f = thisAwareFn.bind(obj);\nvar g = fakeBind(thisAwareFn,obj);\n\nf();            // Value: 42\ng();            // Value: 42\n\nnew f();        // Value: undefined\nnew g();        // <--- ???\n```\n\nFirst, look at the `new f()` call. That's admittedly a strange usage, to call `new` on a hard-bound function. It's probably quite rare that you'd ever do so. But it shows something kind of interesting. Even though `f()` was hard-bound to a `this` context of `obj`, the `new` operator was able to hijack the hard-bound function's `this` and re-bind it to the newly created and empty object. That object has no `value` property, which is why we see `\"Value: undefined\"` printed out.\n\nIf that feels strange, I agree. It's a weird corner nuance. It's not something you'd likely ever exploit. But I point it out not just for trivia. Refer back to the four rules presented earlier in this chapter. Remember how I asserted their order-of-precedence, and `new` was at the top (#1), ahead of *explicit* `call(..)` / `apply(..)` assignment rule (#2)?\n\nSince we can sort of think of `bind(..)` as a variation of that rule, we now see that order-of-precedence proven. `new` is more precedent than, and can override, even a hard-bound function. Sort of makes you think the hard-bound function is maybe not so \"hard\"-bound, huh?!\n\nBut... what's going to happen with the `new g()` call, which is invoking `new` on the returned `=>` arrow function? Do you predict the same outcome as `new f()`?\n\nSorry to disappoint.\n\nThat line will actually throw an exception, because an `=>` function cannot be used with the `new` keyword.\n\nBut why? My best answer, not being authoritative on TC39 myself, is that conceptually and actually, an `=>` arrow function is not a function with a hard-bound `this`, it's a function that has no `this` at all. As such, `new` makes no sense against such a function, so JS just disallows it.\n\n| NOTE: |\n| :--- |\n| Recall earlier, when I pointed out that `=>` arrow functions have `call(..)`, `apply(..)`, and indeed even a `bind(..)`. But we've see that such functions basically ignore these utilities as no-ops. It's a bit strange, in my opinion, that `=>` arrow functions have all those utilities as pass-through no-ops, but for the `new` keyword, that's not just, again, a no-op pass-through, but rather disallowed with an exception. |\n\nBut the main point is: an `=>` arrow function is *not* a syntactic form of `bind(this)`.\n\n### Losing This Battle\n\nReturning once again to our button event handler example:\n\n```js\nthis.submitBtnaddEventListener(\n    \"click\",\n    this.clickHandler,\n    false\n);\n```\n\nThere's a deeper concern we haven't yet addressed.\n\nWe've seen several different approaches to construct a different callback function reference to pass in there, in place of `this.clickHandler`.\n\nBut whichever of those ways we choose, they are producing literally a different function, not just an in-place modification to our existing `clickHandler` function.\n\nWhy does that matter?\n\nWell, first of all, the more functions we create (and re-create), the more processing time (very slight) and the more memory (pretty small, usually) we're chewing up. And when we're re-creating a function reference, and throwing an old one away, that's also leaving un-reclaimed memory sitting around, which puts pressure on the garbage collector (GC) to more often, pause the universe of our program momentarily while it cleans up and reclaims that memory.\n\nIf hooking up this event listening is a one-time operation, no big deal. But if it's happening over and over again, the system-level performance effects *can* start to add up. Ever had an otherwise smooth animation jitter? That was probably the GC kicking in, cleaning up a bunch of reclaimable memory.\n\nBut another concern is, for things like event handlers, if we're going to remove an event listener at some later time, we need to keep a reference to the exact same function we attached originally. If we're using a library/framework, often (but not always!) they take care of that little dirty-work detail for you. But otherwise, it's on us to make sure that whatever function we plan to attach, we hold onto a reference just in case we need it later.\n\nSo the point I'm making is: presetting a `this` assignment, no matter how you do it, so that it's predictable, comes with a cost. A system level cost and a program maintenance/complexity cost. It is *never* free.\n\nOne way of reacting to that fact is to decide, OK, we're just going to manufacture all those `this`-assigned function references once, ahead of time, up-front. That way, we're sure to reduce both the system pressure, and the code pressure, to a minimum.\n\nSounds reasonable, right? Not so fast.\n\n#### Pre-Binding Function Contexts\n\nIf you have a one-off function reference that needs to be `this`-bound, and you use an `=>` arrow or a `bind(this)` call, I don't see any problems with that.\n\nBut if most or all of the `this`-aware functions in a segment of your code invoked in ways where the `this` isn't the predictable context you expect, and so you decide you need to hard-bind them all... I think that's a big warning signal that you're going about things the wrong way.\n\nPlease recall the discussion in the \"Avoid This\" section from Chapter 3, which started with this snippet of code:\n\n```js\nclass Point2d {\n    x = null\n    getDoubleX = () => this.x * 2\n\n    constructor(x,y) {\n        this.x = x;\n        this.y = y;\n    }\n    toString() { /* .. */ }\n}\n\nvar point = new Point2d(3,4);\n```\n\nNow imagine we did this with that code:\n\n```js\nconst getX = point.getDoubleX;\n\n// later, elsewhere\n\ngetX();         // 6\n```\n\nAs you can see, the problem we were trying to solve is the same as we've been dealing with here in this chapter. It's that we wanted to be able to invoke a function reference like `getX()`, and have that *mean* and *behave like* `point.getDoubleX()`. But `this` rules on *regular* functions don't work that way.\n\nSo we used an `=>` arrow function. No big deal, right!?\n\nWrong.\n\nThe real root problem is that we *want* two conflicting things out of our code, and we're trying to use the same *hammer* for both *nails*.\n\nWe want to have a `this`-aware method stored on the `class` prototype, so that there's only one definition for the function, and all our subclasses and instances nicely share that same function. And the way they all share is through the power of the dynamic `this` binding.\n\nBut at the same time, we *also* want those function references to magically stay `this`-assinged to our instance when we pass those function references around and other code is in charge of the call-site.\n\nIn other words, sometimes we want something like `point.getDoubleX` to mean, \"give me a reference that's `this`-assigned to `point`\", and other times we want the same expression `point.getDoubleX` to mean, give me a dynamic `this`-assignable function reference so it can properly get the context I need it to at this moment.\n\nPerhaps JS could offer a different operator besides `.`, like `::` or `->` or something like that, which would let you distinguish what kind of function reference you're after. In fact, there's a long-standing proposal for a `this`-binding operator (`::`), that picks up attention from time to time, and then seems to stall out. Who knows, maybe someday such an operator will finally land, and we'll have better options.\n\nBut I strongly suspect that even if it does land someday, it's going to vend a whole new function reference, exactly as the `=>` or `bind(this)` approaches we've already talked about. It won't come as a free and perfect solution. There will always be a tension between wanting the same function to sometimes be `this`-flexible and sometimes be `this`-predictable.\n\nWhat JS authors of `class`-oriented code often run up against, sooner or later, is this exact tension. And you know what they do?\n\nThey don't consider the *costs* of simply pre-binding all the class's `this`-aware methods as instead `=>` arrow functions in member properties. They don't realize that it's completely defeated the entire purpose of the `[[Prototype]]` chain. And they don't realize that if fixed-context is what they *really need*, there's an entirely different mechanism in JS that is better suited for that purpose.\n\n#### Take A More Critical Look\n\nSo when you do this sort of thing:\n\n```js\nclass Point2d {\n    x = null\n    y = null\n    getDoubleX = () => this.x * 2\n    toString = () => `(${this.x},${this.y})`\n\n    constructor(x,y) {\n        this.x = x;\n        this.y = y;\n    }\n}\n\nvar point = new Point2d(3,4);\nvar anotherPoint = new Point2d(5,6);\n\nvar f = point.getDoubleX;\nvar g = anotherPoint.toString;\n\nf();            // 6\ng();            // (5,6)\n```\n\nI say, \"ick!\", to the hard-bound `this`-aware methods `getDoubleX()` and `toString()` there. To me, that's a code smell. But here's an even *worse* approach that has been favored by many developers in the past:\n\n```js\nclass Point2d {\n    x = null\n    y = null\n\n    constructor(x,y) {\n        this.x = x;\n        this.y = y;\n        this.getDoubleX = this.getDoubleX.bind(this);\n        this.toString = this.toString.bind(this);\n    }\n    getDoubleX() { return this.x * 2; }\n    toString() { return `(${this.x},${this.y})`; }\n}\n\nvar point = new Point2d(3,4);\nvar anotherPoint = new Point2d(5,6);\n\nvar f = point.getDoubleX;\nvar g = anotherPoint.toString;\n\nf();            // 6\ng();            // (5,6)\n```\n\nDouble ick.\n\nIn both cases, you're using a `this` mechanism but completely betraying/neutering it, by taking away all the powerful dynamicism of `this`.\n\nYou really should at least be contemplating this alternate approach, which skips the whole `this` mechanism altogether:\n\n```js\nfunction Point2d(px,py) {\n    var x = px;\n    var y = py;\n\n    return {\n        getDoubleX() { return x * 2; },\n        toString() { return `(${x},${y})`; }\n    };\n}\n\nvar point = Point2d(3,4);\nvar anotherPoint = Point2d(5,6);\n\nvar f = point.getDoubleX;\nvar g = anotherPoint.toString;\n\nf();            // 6\ng();            // (5,6)\n```\n\nYou see? No ugly or complex `this` to clutter up that code or worry about corner cases for. Lexical scope is super straightforward and intuitive.\n\nWhen all we want is for most/all of our function behaviors to have a fixed and predictable context, the most appropriate solution, the most straightforward and even performant solution, is lexical variables and scope closure.\n\nWhen you go to all to the trouble of sprinkling `this` references all over a piece of code, and then you cut off the whole mechanism at the knees with `=>` \"lexical this\" or `bind(this)`, you chose to make the code more verbose, more complex, more overwrought. And you got nothing out of it that was more beneficial, except to follow the `this` (and `class`) bandwagon.\n\n...\n\nDeep breath. Collect yourself.\n\nI'm talking to myself, not you. But if what I just said bothers you, I'm talking to you, too!\n\nOK, listen. That's just my opinion. If you don't agree, that's fine. But apply the same level of rigor to thinking about how these mechanisms work, as I have, when you decide what conclusions you want to arrive at.\n\n## Variations\n\nBefore we close out our lengthy discussion of `this`, there's a few irregular variations on function calls that we should discuss.\n\n### Indirect Function Calls\n\nRecall this example from earlier in the chapter?\n\n```js\nvar point = {\n    x: null,\n    y: null,\n\n    init(x,y) {\n        this.x = x;\n        this.y = y;\n    },\n    rotate(angleRadians) { /* .. */ },\n    toString() { /* .. */ },\n};\n\nvar init = point.init;\ninit(3,4);                  // broken!\n```\n\nThis is broken because the `init(3,4)` call-site doesn't provide the necessary `this`-assignment signal. But there's other ways to observe a similar breakage. For example:\n\n```js\n(1,point.init)(3,4);        // broken!\n```\n\nThis strange looking syntax is first evaluating an expression `(1,point.init)`, which is a comma series expression. The result of such an expression is the final evaluated value, which in this case is the function reference (held by `point.init`).\n\nSo the outcome puts that function reference onto the expression stack, and then invokes that value with `(3,4)`. That's an indirect invocation of the function. And what's the result? It actually matches the *default context* assignment rule (#4) we looked at earlier in the chapter.\n\nThus, in non-strict mode, the `this` for the `point.init(..)` call will be `globalThis`. Had we been in strict-mode, it would have been `undefined`, and the `this.x = x` operation would then have thrown an exception for invalidly accessing the `x` property on the `undefined` value.\n\nThere's several different ways to get an indirect function invocation. For example:\n\n```js\n(()=>point.init)()(3,4);    // broken!\n```\n\nAnd another example of indirect function invocation is the Immediately Invoked Function Expression (IIFE) pattern:\n\n```js\n(function(){\n    // `this` assigned via \"default\" rule\n})();\n```\n\nAs you can see, the function expression value is put onto the expression stack, and then it's invoked with the `()` on the end.\n\nBut what about this code:\n\n```js\n(point.init)(3,4);\n```\n\nWhat will be the outcome of that code?\n\nBy the same reasoning we've seen in the previous examples, it stands to reason that the `point.init` expression puts the function value onto the expression stack, and then invoked indirectly with `(3,4)`.\n\nNot quite, though! JS grammar has a special rule to handle the invocation form `(someIdentifier)(..)` as if it had been `someIdentifier(..)` (without the `(..)` around the identifier name).\n\nWondering why you might want to ever force the *default context* for `this` assignment via an indirect function invocation?\n\n### Accessing `globalThis`\n\nBefore we answer that, let's introduce another way of performing indirect function `this` assignment. Thus far, the indirect function invocation patterns shown are sensitive to strict-mode. But what if we wanted an indirect function `this` assignment that doesn't respect strict-mode.\n\nThe `Function(..)` constructor takes a string of code and dynamically defines the equivalent function. However, it always does so as if that function had been declared in the global scope. And furthermore, it ensures such function *does not* run in strict-mode, no matter the strict-mode status of the program. That's the same outcome as running an indirect\n\nOne niche usage of such strict-mode agnostic indirect function `this` assignment is for getting a reliable reference to the true global object prior to when the JS specification actually defined the `globalThis` identifier (for example, in a polyfill for it):\n\n```js\n\"use strict\";\n\nvar gt = new Function(\"return this\")();\ngt === globalThis;                      // true\n```\n\nIn fact, a similar outcome, using the comma operator trick (see previous section) and `eval(..)`:\n\n```js\n\"use strict\";\n\nfunction getGlobalThis() {\n    return (1,eval)(\"this\");\n}\n\ngetGlobalThis() === globalThis;      // true\n```\n\n| NOTE: |\n| :--- |\n| `eval(\"this\")` would be sensitive to strict-mode, but `(1,eval)(\"this\")` is not, and therefor reliably gives us the `globalThis` in any program. |\n\nUnfortunately, the `new Function(..)` and `(1,eval)(..)` approaches both have an important limitation: that code will be blocked in browser-based JS code if the app is served with certain Content-Security-Policy (CSP) restrictions, disallowing dynamic code evaluation (for security reasons).\n\nCan we get around this? Yes, mostly. [^globalThisPolyfill]\n\nThe JS specification says that a getter function defined on the global object, or on any object that inherits from it (like `Object.prototype`), runs the getter function with `this` context assigned to `globalThis`, regardless of the program's strict-mode.\n\n```js\n// Adapted from: https://mathiasbynens.be/notes/globalthis#robust-polyfill\nfunction getGlobalThis() {\n    Object.defineProperty(Object.prototype,\"__get_globalthis__\",{\n        get() { return this; },\n        configurable: true\n    });\n    var gt = __get_globalthis__;\n    delete Object.prototype.__get_globalthis__;\n    return gt;\n}\n\ngetGlobalThis() === globalThis;      // true\n```\n\nYeah, that's super gnarly. But that's JS `this` for you!\n\n### Template Tag Functions\n\nThere's one more unusual variation of function invocation we should cover: tagged template functions.\n\nTemplate strings -- what I prefer to call interpolated literals -- can be \"tagged\" with a prefix function, which is invoked with the parsed contents of the template literal:\n\n```js\nfunction tagFn(/* .. */) {\n    // ..\n}\n\ntagFn`actually a function invocation!`;\n```\n\nAs you can see, there's no `(..)` invocation syntax, just the tag function (`tagFn`) appearing before the `` `template literal` ``; whitespace is allowed between them, but is very uncommon.\n\nDespite the strange appearance, the function `tagFn(..)` will be invoked. It's passed the list of one or more string literals that were parsed from the template literal, along with any interpolated expression values that were encountered.\n\nWe're not going to cover all the ins and outs of tagged template functions -- they're seriously one of the most powerful and interesting features ever added to JS -- but since we're talking about `this` assignment in function invocations, for completeness sake we need to talk about how `this` will be assigned.\n\nThe other form for tag functions you may encounter is:\n\n```js\nvar someObj = {\n    tagFn() { /* .. */ }\n};\n\nsomeObj.tagFn`also a function invocation!`;\n```\n\nHere's the easy explanation: `` tagFn`..` `` and `` someObj.tagFn`..` `` will each have `this`-assignment behavior corresponding to call-sites as `tagFn(..)` and `someObj.tagFn(..)`, respectively. In other words, `` tagFn`..` `` behaves by the *default context* assignment rule (#4), and `` someObj.tagFn`..` `` behaves by the *implicit context* assignment rule (#3).\n\nLuckily for us, we don't need to worry about the `new` or `call(..)` / `apply(..)` assignment rules, as those forms aren't possible with tag functions.\n\nIt should be pointed out that it's pretty rare for a tagged template literal function to be defined as `this`-aware, so it's fairly unlikely you'll need to apply these rules. But just in case, now you're in the *know*.\n\n## Stay Aware\n\nSo, that's `this`. I'm willing to bet for many of you, it was a bit more... shall we say, involved... than you might have been expecting.\n\nThe good news, perhaps, is that in practice you don't often trip over all these different complexities. But the more you use `this`, the more it requires you, and the readers of your code, to understand how it actually works.\n\nThe lesson here is that you should be intentional and aware of all aspects of `this` before you go sprinkling it about your code. Make sure you're using it most effectively and taking full advantage of this important pillar of JS.\n\n[^globalThisPolyfill]: \"A horrifying globalThis polyfill in universal JavaScript\"; Mathias Bynens; April 18 2019; https://mathiasbynens.be/notes/globalthis#robust-polyfill ; Accessed July 2022\n"
  },
  {
    "path": "objects-classes/ch5.md",
    "content": "# You Don't Know JS Yet: Objects & Classes - 2nd Edition\n# Chapter 5: Delegation\n\n| NOTE: |\n| :--- |\n| Work in progress |\n\nWe've thoroughly explored objects, prototypes, classes, and now the `this` keyword. But we're now going to revisit what we've learned so far from a bit of a different perspective.\n\nWhat if you could leverage all the power of the objects, prototypes, and dynamic `this` mechanisms together, without ever using `class` or any of its descendants?\n\nIn fact, I would argue JS is inherently less class-oriented than the `class` keyword might appear. Because JS is a dynamic, prototypal language, its strong suit is actually... *delegation*.\n\n## Preamble\n\nBefore we begin looking at delegation, I want to offer a word of caution. This perspective on JS's object `[[Prototype]]` and `this` function context mechanisms is *not* mainstream. It's *not* how framework authors and libraries utilize JS. You won't, to my knowledge, find any big apps out there using this pattern.\n\nSo why on earth would I devote a chapter to such a pattern, if it's so unpopular?\n\nGood question. The cheeky answer is: because it's my book and I can do what I feel like!\n\nBut the deeper answer is, because I think developing *this* understanding of one of the language's core pillars helps you *even if* all you ever do is use `class`-style JS patterns.\n\nTo be clear, delegation is not my invention. It's been around as a design pattern for decades. And for a long time, developers argued that prototypal delegation was *just* the dynamic form of inheritance.[^TreatyOfOrlando] But I think that was a mistake to conflate the two.[^ClassVsPrototype]\n\nFor the purposes of this chapter, I'm going to present delegation, as implemented via JS mechanics, as an alternative design pattern, positioned somewhere between class-orientation and object-closure/module patterns.\n\nThe first step is to *de-construct* the `class` mechanism down to its individual parts. Then we'll cherry-pick and mix the parts a bit differently.\n\n## What's A Constructor, Anyway?\n\nIn Chapter 3, we saw `constructor(..)` as the main entry point for construction of a `class` instance. But the `constructor(..)` doesn't actually do any *creation* work, it's only *initialization* work. In other words, the instance is already created by the time the `constructor(..)` runs and initializes it -- e.g., `this.whatever` types of assignments.\n\nSo where does the *creation* work actually happen? In the `new` operator. As the section \"New Context Invocation\" in Chapter 4 explains, there are four steps the `new` keyword performs; the first of those is the creation of a new empty object (the instance). The `constructor(..)` isn't even invoked until step 3 of `new`'s efforts.\n\nBut `new` is not the only -- or perhaps even, best -- way to *create* an object \"instance\". Consider:\n\n```js\n// a non-class \"constructor\"\nfunction Point2d(x,y) {\n    // create an object (1)\n    var instance = {};\n\n    // initialize the instance (3)\n    instance.x = x;\n    instance.y = y;\n\n    // return the instance (4)\n    return instance;\n}\n\nvar point = Point2d(3,4);\n\npoint.x;                    // 3\npoint.y;                    // 4\n```\n\nThere's no `class`, just a regular function definition (`Point2d(..)`). There's no `new` invocation, just a regular function call (`Point2d(3,4)`). And there's no `this` references, just regular object property assignments (`instance.x = ..`).\n\nThe term that's most often used to refer to this pattern of code is that `Point2d(..)` here is a *factory function*. Invoking it causes the construction (creation and initialization) of an object, and returns that back to us. That's an extremely common pattern, at least as common as class-oriented code.\n\nI comment-annotated `(1)`, `(3)`, and `(4)` in that snippet, which roughly correspond to steps 1, 3, and 4 of the `new` operation. But where's step 2?\n\nIf you recall, step 2 of `new` is about linking the object (created in step 1) to another object, via its `[[Prototype]]` slot (see Chapter 2). So what object might we want to link our `instance` object to? We could link it to an object that holds functions we'd like to associate/use with our instance.\n\nLet's amend the previous snippet:\n\n```js\nvar prototypeObj = {\n    toString() {\n        return `(${this.x},${this.y})`;\n    },\n}\n\n// a non-class \"constructor\"\nfunction Point2d(x,y) {\n    // create an object (1)\n    var instance = {\n        // link the instance's [[Prototype]] (2)\n        __proto__: prototypeObj,\n    };\n\n    // initialize the instance (3)\n    instance.x = x;\n    instance.y = y;\n\n    // return the instance (4)\n    return instance;\n}\n\nvar point = Point2d(3,4);\n\npoint.toString();           // (3,4)\n```\n\nNow you see the `__proto__` assignment that's setting up the internal `[[Prototype]]` linkage, which was the missing step 2. I used the `__proto__` here merely for illustration purposes; using `setPrototypeOf(..)` as shown in Chapter 4 would have accomplished the same task.\n\n### *New* Factory Instance\n\nWhat do you think would happen if we used `new` to invoke the `Point2d(..)` function as shown here?\n\n```js\nvar anotherPoint = new Point2d(5,6);\n\nanotherPoint.toString(5,6);         // (5,6)\n```\n\nWait! What's going on here? A regular, non-`class` factory function in invoked with the `new` keyword, as if it was a `class`. Does that change anything about the outcome of the code?\n\nNo... and yes. `anotherPoint` here is exactly the same object as it would have been had I not used `new`. But! The object that `new` creates, links, and assigns as `this` context? *That* object was completely ignored and thrown away, ultimately to be garbage collected by JS. Unfortunately, the JS engine cannot predict that you're not going to use the object that you asked `new` to create, so it always still gets cteated even if it goes unused.\n\nThat's right! Using a `new` keyword against a factory function might *feel* more ergonomic or familiar, but it's quite wasteful, in that it creates **two** objects, and wastefully throws one of them away.\n\n### Factory Initialization\n\nIn the current code example, the `Point2d(..)` function still looks an awful lot like a normal `constructor(..)` of a `class` definition. But what if we moved the initialization code to a separate function, say named `init(..)`:\n\n```js\nvar prototypeObj = {\n    init(x,y) {\n        // initialize the instance (3)\n        this.x = x;\n        this.y = y;\n    },\n    toString() {\n        return `(${this.x},${this.y})`;\n    },\n}\n\n// a non-class \"constructor\"\nfunction Point2d(x,y) {\n    // create an object (1)\n    var instance = {\n        // link the instance's [[Prototype]] (2)\n        __proto__: prototypeObj,\n    };\n\n    // initialize the instance (3)\n    instance.init(x,y);\n\n    // return the instance (4)\n    return instance;\n}\n\nvar point = Point2d(3,4);\n\npoint.toString();           // (3,4)\n```\n\nThe `instance.init(..)` call makes use of the `[[Prototype]]` linkage set up via `__proto__` assignment. Thus, it *delegates* up the prototype chain to `prototypeObj.init(..)`, and invokes it with a `this` context of `instance` -- via *implicit context* assignment (see Chapter 4).\n\nLet's continue the deconstruction. Get ready for a switcheroo!\n\n```js\nvar Point2d = {\n    init(x,y) {\n        // initialize the instance (3)\n        this.x = x;\n        this.y = y;\n    },\n    toString() {\n        return `(${this.x},${this.y})`;\n    },\n};\n```\n\nWhoa, what!? I discarded the `Point2d(..)` function, and instead renamed the `prototypeObj` as `Point2d`. Weird.\n\nBut let's look at the rest of the code now:\n\n```js\n// steps 1, 2, and 4\nvar point = { __proto__: Point2d, };\n\n// step 3\npoint.init(3,4);\n\npoint.toString();           // (3,4)\n```\n\nAnd one last refinement: let's use a built-in utility JS provides us, called `Object.create(..)`:\n\n```js\n// steps 1, 2, and 4\nvar point = Object.create(Point2d);\n\n// step 3\npoint.init(3,4);\n\npoint.toString();           // (3,4)\n```\n\nWhat operations does `Object.create(..)` perform?\n\n1. create a brand new empty object, out of thin air.\n\n2. link the `[[Prototype]]` of that new empty object to the function's `.prototype` object.\n\nIf those look familiar, it's because those are exactly the same first two steps of the `new` keyword (see Chapter 4).\n\nLet's put this back together now:\n\n```js\nvar Point2d = {\n    init(x,y) {\n        this.x = x;\n        this.y = y;\n    },\n    toString() {\n        return `(${this.x},${this.y})`;\n    },\n};\n\nvar point = Object.create(Point2d);\n\npoint.init(3,4);\n\npoint.toString();           // (3,4)\n```\n\nHmmm. Take a few moments to ponder what's been derived here. How does it compare to the `class` approach?\n\nThis pattern ditches the `class` and `new` keywords, but accomplishes the exact same outcome. The *cost*? The single `new` operation was broken up into two statements: `Object.create(Point2d)` and `point.init(3,4)`.\n\n#### Help Me Reconstruct!\n\nIf having those two operations separate bothers you -- is it *too deconstructed*!? -- they can always be recombined in a little factory helper:\n\n```js\nfunction make(objType,...args) {\n    var instance = Object.create(objType);\n    instance.init(...args);\n    return instance;\n}\n\nvar point = make(Point2d,3,4);\n\npoint.toString();           // (3,4)\n```\n\n| TIP: |\n| :--- |\n| Such a `make(..)` factory function helper works generally for any object-type, as long as you follow the implied convention that each `objType` you link to has a function named `init(..)` on it. |\n\nAnd of course, you can still create as many instances as you'd like:\n\n```js\nvar point = make(Point2d,3,4);\n\nvar anotherPoint = make(Point2d,5,6);\n```\n\n## Ditching Class Thinking\n\nQuite frankly, the *deconstruction* we just went through only ends up in slightly different, and maybe slightly better or slightly worse, code as compared to the `class` style. If that's all delegation was about, it probably wouldn't even be useful enough for more than a footnote, much less a whole chapter.\n\nBut here's where we're going to really start pushing the class-oriented thinking itself, not just the syntax, aside.\n\nClass-oriented design inherently creates a hierarchy of *classification*, meaning how we divide up and group characteristics, and then stack them vertically in an inheritance chain. Moreover, defining a subclass is a specialization of the generalized base class. Instantiating is a specialization of the generalized class.\n\nBehavior in a traditional class hierarchy is a vertical composition through the layers of the inheritance chain. Attempts have been made over the decades, and even become rather popular at times, to flatten out deep hierarchies of inheritance, and favor a more horizontal composition through *mixins* and related ideas.\n\nI'm not asserting there's anything wrong with those ways of approaching code. But I am saying that they aren't *naturally* how JS works, so adopting them in JS has been a long, winding, complicated road, and has variously accreted lots of nuanced syntax to retrofit on top of JS's core `[[Prototype]]` and `this` pillar.\n\nFor the rest of this chapter, I intend to discard both the syntax of `class` *and* the thinking of *class*.\n\n## Delegation Illustrated\n\nSo what is delegation about? At its core, it's about two or more *things* sharing the effort of completing a task.\n\nInstead of defining a `Point2d` general parent *thing* that represents shared behavior that a set of one or more child `point` / `anotherPoint` *things* inherit from, delegation moves us to building our program with discrete peer *things* that cooperate with each other.\n\nI'll sketch that out in some code:\n\n```js\nvar Coordinates = {\n    setX(x) {\n        this.x = x;\n    },\n    setY(y) {\n        this.y = y;\n    },\n    setXY(x,y) {\n        this.setX(x);\n        this.setY(y);\n    },\n};\n\nvar Inspect = {\n    toString() {\n        return `(${this.x},${this.y})`;\n    },\n};\n\nvar point = {};\n\nCoordinates.setXY.call(point,3,4);\nInspect.toString.call(point);         // (3,4)\n\nvar anotherPoint = Object.create(Coordinates);\n\nanotherPoint.setXY(5,6);\nInspect.toString.call(anotherPoint);  // (5,6)\n```\n\nLet's break down what's happening here.\n\nI've defined `Coordinates` as a concrete object that holds some behaviors I associate with setting point coordinates (`x` and `y`). I've also defined `Inspect` as a concrete object that holds some debug inspection logic, such as `toString()`.\n\nI then create two more concrete objects, `point` and `anotherPoint`.\n\n`point` has no specific `[[Prototype]]` (default: `Object.prototype`). Using *explicit context* assignment (see Chapter 4), I invoke the `Coordinates.setXY(..)` and `Inspect.toString()` utilities in the context of `point`. That is what I call *explicit delegation*.\n\n`anotherPoint` is `[[Prototype]]` linked to `Coordinates`, mostly for a bit of convenience. That lets me use *implicit context* assignment with `anotherPoint.setXY(..)`. But I can still *explicitly* share `anotherPoint` as context for the `Inspect.toString()` call. That's what I call *implicit delegation*.\n\n**Don't miss *this*:** We still accomplished composition: we composed the behaviors from `Coordinates` and `Inspect`, during runtime function invocations with `this` context sharing. We didn't have to author-combine those behaviors into a single `class` (or base-subclass `class` hierarchy) for `point` / `anotherPoint` to inherit from. I like to call this runtime composition, **virtual composition**.\n\nThe *point* here is: none of these four objects is a parent or child. They're all peers of each other, and they all have different purposes. We can organize our behavior in logical chunks (on each respective object), and share the context via `this` (and, optionally `[[Prototype]]` linkage), which ends up with the same composition outcomes as the other patterns we've examined thus far in the book.\n\n*That* is the heart of the **delegation** pattern, as JS embodies it.\n\n| TIP: |\n| :--- |\n| In the first edition of this book series, this book (\"this & Object Prototypes\") coined a term, \"OLOO\", which stands for \"Objects Linked to Other Objects\" -- to stand in contrast to \"OO\" (\"Object Oriented\"). In this preceding example, you can see the essence of OLOO: all we have are objects, linked to and cooperating with, other objects. I find this beautiful in its simplicity. |\n\n## Composing Peer Objects\n\nLet's take *this delegation* even further.\n\nIn the preceding snippet, `point` and `anotherPoint` merely held data, and the behaviors they delegated to were on other objects (`Coordinates` and `Inspect`). But we can add behaviors directly to any of the objects in a delegation chain, and those behaviors can even interact with each other, all through the magic of *virtual composition* (`this` context sharing).\n\nTo illustrate, we'll evolve our current *point* example a fair bit. And as a bonus we'll actually draw our points on a `<canvas>` element in the DOM. Let's take a look:\n\n```js\nvar Canvas = {\n    setOrigin(x,y) {\n        this.ctx.translate(x,y);\n\n        // flip the canvas context vertically,\n        // so coordinates work like on a normal\n        // 2d (x,y) graph\n        this.ctx.scale(1,-1);\n    },\n    pixel(x,y) {\n        this.ctx.fillRect(x,y,1,1);\n    },\n    renderScene() {\n        // clear the canvas\n        var matrix = this.ctx.getTransform();\n        this.ctx.resetTransform();\n        this.ctx.clearRect(\n            0, 0,\n            this.ctx.canvas.width,\n            this.ctx.canvas.height\n        );\n        this.ctx.setTransform(matrix);\n\n        this.draw();  // <-- where is draw()?\n    },\n};\n\nvar Coordinates = {\n    setX(x) {\n        this.x = Math.round(x);\n    },\n    setY(y) {\n        this.y = Math.round(y);\n    },\n    setXY(x,y) {\n        this.setX(x);\n        this.setY(y);\n        this.render();   // <-- where is render()?\n    },\n};\n\nvar ControlPoint = {\n    // delegate to Coordinates\n    __proto__: Coordinates,\n\n    // NOTE: must have a <canvas id=\"my-canvas\">\n    // element in the DOM\n    ctx: document.getElementById(\"my-canvas\")\n        .getContext(\"2d\"),\n\n    rotate(angleRadians) {\n        var rotatedX = this.x * Math.cos(angleRadians) -\n            this.y * Math.sin(angleRadians);\n        var rotatedY = this.x * Math.sin(angleRadians) +\n            this.y * Math.cos(angleRadians);\n        this.setXY(rotatedX,rotatedY);\n    },\n    draw() {\n        // plot the point\n        Canvas.pixel.call(this,this.x,this.y);\n    },\n    render() {\n        // clear the canvas, and re-render\n        // our control-point\n        Canvas.renderScene.call(this);\n    },\n};\n\n// set the logical (0,0) origin at this\n// physical location on the canvas\nCanvas.setOrigin.call(ControlPoint,100,100);\n\nControlPoint.setXY(30,40);\n// [renders point (30,40) on the canvas]\n\n// ..\n// later:\n\n// rotate the point about the (0,0) origin\n// 90 degrees counter-clockwise\nControlPoint.rotate(Math.PI / 2);\n// [renders point (-40,30) on the canvas]\n```\n\nOK, that's a lot of code to digest. Take your time and re-read the snippet several times. I added a couple of new concrete objects (`Canvas` and `ControlPoint`) alongside the previous `Coordinates` object.\n\nMake sure you see and understand the interactions between these three concrete objects.\n\n`ControlPoint` is linked (via `__proto__`) to *implicitly delegate* (`[[Prototype]]` chain) to `Coordinates`.\n\nHere's an *explicit delegation*: `Canvas.setOrigin.call(ControlPoint,100,100);`; I'm invoking the `Canvas.setOrigin(..)` call in the context of `ControlPoint`. That has the effect of sharing `ctx` with `setOrigin(..)`, via `this`.\n\n`ControlPoint.setXY(..)` delegates *implicitly* to `Coordinates.setXY(..)`, but still in the context of `ControlPoint`. Here's a key detail that's easy to miss: see the `this.render()` inside of `Coordinates.setXY(..)`? Where does that come from? Since the `this` context is `ControlPoint` (not `Coordinates`), it's invoking `ControlPoint.render()`.\n\n`ControlPoint.render()` *explicitly delegates* to `Canvas.renderScene()`, again still in the `ControlPoint` context. `renderScene()` calls `this.draw()`, but where does that come from? Yep, still from `ControlPoint` (via `this` context).\n\nAnd `ControlPoint.draw()`? It *explicitly delegates* to `Canvas.pixel(..)`, yet again still in the `ControlPoint` context.\n\nAll three objects have methods that end up invoking each other. But these calls aren't particularly hard-wired. `Canvas.renderScene()` doesn't call `ControlPoint.draw()`, it calls `this.draw()`. That's important, because it means that `Canvas.renderScene()` is more flexible to use in a different `this` context -- e.g., against another kind of *point* object besides `ControlPoint`.\n\nIt's through the `this` context, and the `[[Prototype]]` chain, that these three objects basically are mixed (composed) virtually together, as needed at each step, so that they work together **as if they're one object rather than three seperate objects**.\n\nThat's the *beauty* of virtual composition as realized by the delegation pattern in JS.\n\n### Flexible Context\n\nI mentioned above that we can pretty easily add other concrete objects into the mix. Here's an example:\n\n```js\nvar Coordinates = { /* .. */ };\n\nvar Canvas = {\n    /* .. */\n    line(start,end) {\n        this.ctx.beginPath();\n        this.ctx.moveTo(start.x,start.y);\n        this.ctx.lineTo(end.x,end.y);\n        this.ctx.stroke();\n    },\n};\n\nfunction lineAnchor(x,y) {\n    var anchor = {\n        __proto__: Coordinates,\n        render() {},\n    };\n    anchor.setXY(x,y);\n    return anchor;\n}\n\nvar GuideLine = {\n    // NOTE: must have a <canvas id=\"my-canvas\">\n    // element in the DOM\n    ctx: document.getElementById(\"my-canvas\")\n        .getContext(\"2d\"),\n\n    setAnchors(sx,sy,ex,ey) {\n        this.start = lineAnchor(sx,sy);\n        this.end = lineAnchor(ex,ey);\n        this.render();\n    },\n    draw() {\n        // plot the point\n        Canvas.line.call(this,this.start,this.end);\n    },\n    render() {\n        // clear the canvas, and re-render\n        // our line\n        Canvas.renderScene.call(this);\n    },\n};\n\n// set the logical (0,0) origin at this\n// physical location on the canvas\nCanvas.setOrigin.call(GuideLine,100,100);\n\nGuideLine.setAnchors(-30,65,45,-17);\n// [renders line from (-30,65) to (45,-17)\n//   on the canvas]\n```\n\nThat's pretty nice, I think!\n\nBut I think another less-obvious benefit is that having objects linked dynamically via `this` context tends to make testing different parts of the program independently, somewhat easier.\n\nFor example, `Object.setPrototypeOf(..)` can be used to dynamically change the `[[Prototype]]` linkage of an object, delegating it to a different object such as a mock object. Or you could dynamically redefine `GuideLine.draw()` and `GuideLine.render()` to *explicitly delegate* to a `MockCanvas` instead of `Canvas`.\n\nThe `this` keyword, and the `[[Prototype]]` link, are a tremendously flexible mechanism when you understand and leverage them fully.\n\n## Why *This*?\n\nOK, so it's hopefully clear that the delegation pattern leans heavily on implicit input, sharing context via `this` rather than through an explicit parameter.\n\nYou might rightly ask, why not just always pass around that context explicitly? We can certainly do so, but... to manually pass along the necessary context, we'll have to change pretty much every single function signature, and any corresponding call-sites.\n\nLet's revisit the earlier `ControlPoint` delegation example, and implement it without any delegation-oriented `this` context sharing. Pay careful attention to the differences:\n\n```js\nvar Canvas = {\n    setOrigin(ctx,x,y) {\n        ctx.translate(x,y);\n        ctx.scale(1,-1);\n    },\n    pixel(ctx,x,y) {\n        ctx.fillRect(x,y,1,1);\n    },\n    renderScene(ctx,entity) {\n        // clear the canvas\n        var matrix = ctx.getTransform();\n        ctx.resetTransform();\n        ctx.clearRect(\n            0, 0,\n            ctx.canvas.width,\n            ctx.canvas.height\n        );\n        ctx.setTransform(matrix);\n\n        entity.draw();\n    },\n};\n\nvar Coordinates = {\n    setX(entity,x) {\n        entity.x = Math.round(x);\n    },\n    setY(entity,y) {\n        entity.y = Math.round(y);\n    },\n    setXY(entity,x,y) {\n        this.setX(entity,x);\n        this.setY(entity,y);\n        entity.render();\n    },\n};\n\nvar ControlPoint = {\n    // NOTE: must have a <canvas id=\"my-canvas\">\n    // element in the DOM\n    ctx: document.getElementById(\"my-canvas\")\n        .getContext(\"2d\"),\n\n    setXY(x,y) {\n        Coordinates.setXY(this,x,y);\n    },\n    rotate(angleRadians) {\n        var rotatedX = this.x * Math.cos(angleRadians) -\n            this.y * Math.sin(angleRadians);\n        var rotatedY = this.x * Math.sin(angleRadians) +\n            this.y * Math.cos(angleRadians);\n        this.setXY(rotatedX,rotatedY);\n    },\n    draw() {\n        // plot the point\n        Canvas.pixel(this.ctx,this.x,this.y);\n    },\n    render() {\n        // clear the canvas, and re-render\n        // our control-point\n        Canvas.renderScene(this.ctx,this);\n    },\n};\n\n// set the logical (0,0) origin at this\n// physical location on the canvas\nCanvas.setOrigin(ControlPoint.ctx,100,100);\n\n// ..\n```\n\nTo be honest, some of you may prefer that style of code. And that's OK if you're in that camp. This snippet avoids `[[Prototype]]` entirely, and only relies on far fewer basic `this.`-style references to properties and methods.\n\nBy contrast, the delegation style I'm advocating for in this chapter is unfamiliar and uses `[[Prototype]]` and `this` sharing in ways you're not likely familiar with. To use such a style effectively, you'll have to invest the time and practice to build a deeper familiarity.\n\nBut in my opinion, the \"cost\" of avoiding virtual composition through delegation can be felt across all the function signatures and call-sites; I find them way more cluttered. That explicit context passing is quite a tax.\n\nIn fact, I'd never advocate that style of code at all. If you want to avoid delegation, it's probably best to just stick to `class` style code, as seen in Chapter 3. As an exercise left to the reader, try to convert the earlier `ControlPoint` / `GuideLine` code snippets to use `class`.\n\n[^TreatyOfOrlando]: \"Treaty of Orlando\"; Henry Lieberman, Lynn Andrea Stein, David Ungar; Oct 6, 1987; https://web.media.mit.edu/~lieber/Publications/Treaty-of-Orlando-Treaty-Text.pdf ; PDF; Accessed July 2022\n\n[^ClassVsPrototype]: \"Classes vs. Prototypes, Some Philosophical and Historical Observations\"; Antero Taivalsaari; Apr 22, 1996; https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.56.4713&rep=rep1&type=pdf ; PDF; Accessed July 2022\n"
  },
  {
    "path": "objects-classes/foreword.md",
    "content": "# You Don't Know JS Yet: Objects & Classes - 2nd Edition\n# Foreword\n\nKyle Simpson has an unmatched brilliance in the art of explanation.\n\nIn April of 2015 I was honored to author the foreword for Kyle's book [You Don't Know JS: ES6 & Beyond](https://www.oreilly.com/library/view/you-dont-know/9781491905241/), an exciting and detailed deep-dive into new JavaScript language features that hadn't even yet been ratified by Ecma (that wouldn't happen until June 2015), but had already made their way out into the world. At the time, there was gap in meaningful documentation and educational resources, and I declared that no better person had stepped up to fill it. I stand by everything I wrote in 2015, and I'm here in 2022 to double down for [You Don't Know JS Yet: Objects & Classes]().\n\nWe are all better off for the time, effort and resources that Kyle pours into forming a better understanding of the JavaScript programming language for himself, and for the betterment of his peers: learning, honing and distilling complex semantics into easily digestable concepts that can be built upon in infinite, myriad ways. And that's exactly what we witness here: Kyle becomes an expert in programming subject matter by consuming it at every level. By probing the semantics of new language features, luring them out from the shadows, releasing them from arcane origins and freeing them for our consumption and growth.\n\nEven as a successful professional software engineer, I keep Kyle's works close at hand. At times these tomes are helpful in explaining deeply complex concepts to teammates and peers, while other times they serve as refreshers for myself, because there's always some interesting take-away or new perspective to gain.\n\nRick Waldron (@rwaldron)<br>\nLead Software Engineer<br>\nLightning Web Security<br>\nSalesforce\n"
  },
  {
    "path": "objects-classes/thanks.md",
    "content": "# You Don't Know JS Yet: Objects & Classes - 2nd Edition\n# Thank You!\n\nThe following 371 Kickstarter backers generously backed the campaign to write/publish the four remaining books of the second edition. Without their faithful and patient support, these books would not have happened.\n\nI am deeply grateful to each of you!\n\n> Marc at Frontend Masters, Bassim, Tasos Tsournos, Lauren Clark, Simon, Appgrader, Marcos S., Noah Rodenbeek, Lichtjaeger, Jon Miller, Anil, Greg Gerard, Frank Deberle, Davide Bonifacio, Brandon Leichty, Rowdy Rabouw, Gaspar Radu, Sukumar Vaddi, Gordon, jakecodes, Leo Furze-Waddock, Nick de Jong, D. Vinci, Brian Vogel, Gareth loot, Simon Taylor, Chris O’Brien, Nayana Davis, Mark Kramer, Sunil Samuel, @nestor.j.g, Ryan McDaniel, Mert Even, Haim Yulzari, Josh Marks, Chiril Sarajiu, Barnabas Jovanovics, LynchyC, Yahya Jideh, Chris Weber, Dan Cortes, Johnny Tordgeman, Ky Lee, Brian Wisti, Steven Marrocco, Thomas Randolph, Petri Lindholm, John Cole, github, @denysmarkov, Jacob Scherber, Pierre-Yves Lebrun, mcekiera, Matthew Wasbrough, Génicot Jean-Baptiste, Adam Zając, Lenny Erlesand, Samuel Gustafsson, Hunter Jansen, Theo Armour, Nate Hargitt, Anon, Github repo, cawel, mpelikan, @farisaziz12, Ojars, Camilo Segura, Sean Seagren, Michael Vendivel, Evan, Eric Schwertfeger, Gene Garbutt, Elena Rogleva, Fiona Cheung, Anton Levholm, Lorenzo Bersano, Ando NARY, Ruben Krbashyan, Anonymous please, @jcubic, Bhavin Dave, A. Hitchcock, H0rn0chse, Yaniv Wainer, Zach, Raúl Pineda, Rohan Gupta, Karthik, Kapil, Ricardo Trejos, InvisibleLuis, BruceRobertson, Neil Lupton, Chris Schweda, Luca Mezzalira, antonio molinari, David Pinezich, Jon Barson, Nick Kaufmann, Just Andrew, Rock Kayode Winner, @omar12, Page Han, Aurélien Bottazini, Michael, Petr Siegl, Ilya Sarantsev, Alfredo Delgado, aharvard, Jannaee, Aaron McBride, Toma, epmatsw, Igor \"kibertoad\" Savin, Christian Rackerseder, NC Patro, Kevin, Brian Holt, Brian Ashenfelter, Selina Chang, cwavedave, Alex Grant, Craig Robertson, Eduardo Sanz Martin, oieduardorabelo, Esteban Massuh, tedhexaflow, Gershon Gerchikov, Harika Yedidi, Brad Dougherty, Nitin, Leo Balter, Syed Ahmad, Kaz de Groot, Pinnemouche Studio, Jerome Amos, Dan Poynor, John Liu, @thedavefulton, Madeline Bernard, Ikigai42, Antonio Chillaron, Sachin, Prakasam Venkatachalam, jmarti705, Mihailo23, Mihailo Pantovic, Magloire, samrudh, Mykenzie Rogers, Len, Lyza Danger Gardner, Ryan, Roman, Radojica Radivojevic, Gabrien Symons, Ryan Parker, Andrés, Merlin, rushabh_badani, notacouch, Anna Borja, Steve Albers, Marc at Frontend Masters, Bala Vemula, @chrismcdonald84, stern9, Janne Hellsten, Alexandre Madurell, Tanner Hodges, Joe Chellman, Joachim Kliemann, Stefano Frasson Pianizzola, Sergey Kochergan, Spiridonov Dmitriy, IonutBihari, Alexandru Olteanu, Javi, Marlee Peters, @vadocondes1, Gerardo Leal, Albert Sebastian, Atish Raina, Andreas Gebhardt, David Deren, Maksym Gerashchenko, Alexandru, Matt Peck, William Lacroix, Pavlo, Jon, Brett Walker, Iosif Psychas, Ferran Buireu, crs1138, Emiliano anichini, Max Koretskyi, Sander Elias, Michael Romanov, Barkóczi Dávid, Daw-Chih Liou, Dale Caffull, Amanda Dillon, Mike, Justin Hefko, Muhammad Ali Shah, Ketan Srivastav, redeemefy, Stefan Trivunčić, Manuel Juan Fosela Águila, Dragan Majstorović, Harsha C G, Himanshu, Luke, Sai Ponnada, Mark Franco, David Whittaker, Dr. Teresa Vasquez, Ian Wright, Lora Rusinouskaya, Petar, Harish, Mairead, shimon simo moyal, Sunny Puri, Максим Кочанов, Alex Georoceanu, Nicolas Carreras, damijanc, zach.dev, Coati, Brian Whitton, Denis Ciccale, Piotr Seefeld, Chase Hagwood, Amritha K, Κώστας Μηναϊδης, Trey Aughenbaugh, J David Eisenberg, Paul Thaden, Corina S, Chris Dhanaraj, Nahid Hossain, Justin McCullough, Arseny, Mark Trostler, Lucy Barker, Maaz Syed Adeeb, mcginkel, Derick Rodriguez, Helen Tsui, Rus Ustyugov, Vassilis Mastorostergios, Ryan Ewing, Rob Huelga, jinujj, ultimateoverload, Chaos, Andy Howell (spacebeers), Archana, AG Grid, theblang, Coyotiv School of Software Engineering, Ayush Rajniwal, Manish Bhatt, Shea Leslein, Jordan Chipman, jg0x42, Arvind Kumar, Eduardo Grigolo, Peter Svegrup, Jakub Kotula, William Richardson, Jonah and Ali, nicciwill, Lauren Hodges, Travis Sauer, Alexandros, Abhas, Kirankumar Ambati, Gopalakrishnan, Mika Rehman, Sreeram Sama, Shubhamsatyam Verma, Heejae Chang, Andrico karoulla, Niek Heezemans, Stanislav Horáček, Luis Ibanhi, Jasmine Wang, Yunier, Brian Barrow, Matteo Hertel, Aleksandar Milicevic, achung89, kushavi, Ahmed Fouad, Venkat Kaluva, Ian Wotkun, Andreas Näsman, ivan-siachoque, Paul Gain, Santhosh R, Gustavo Morales, ScottAwseome, Fredrik Thorkildsen, Manvel, holleB, James Sullivan, Adam Kaźmierczak, carlottosson, Alvee, Alex Reardon, Olie Chan, Fredrik S, Brett.Buskirk, Rui Sereno, Nathan Strong, lostdesign, ppseprus, James, anthonybsd, Alena Charnova, Kevin K, @codingthirty, Tim Davis, Jonathan Yee, Christa, Fabian Merchan, Nathanael McDaniel, Dave N, Brian Chirgwin, Abdulrahman (Abdu) Assabri, rmeja, Jan Václavek, Phillip Hogan, Adhithya Rajagopalan (xadhix), Jason Humphrey, Antoinette Smith, Elliot Redhead, zokocx, John Sims, Michalis Garganourakis, Adarsh Konchady, Anton Oleg Dobrovolskyy, George Tharakan, syd, Ryan D., Iris Nathan, Srishti Gupta, Miguel Rivero, @saileshraghavan, Yojan, @bgollum, Junyts, Like Ezugworie, Vsh13, LocalPCGuy, DMGabriel, Juan Tincho, William Greenlaw, atisbacsi, cris ryan tan, Jonathan Clifron, Daniel Dolich, Praj, Caisman, Michał, Mark C, 3xpedia\n\nA special thanks to:\n\n* A. Hitchcock\n* Alexandru\n* Appgrader\n* Coyotiv School of Software Engineering\n* Gaspar Radu\n* IonutBihari\n* jmarti705\n* John Liu\n* Syed Ahmad\n* Travis Sauer\n* William Greenlaw\n\nAll of you are fantastic!\n"
  },
  {
    "path": "objects-classes/toc.md",
    "content": "# You Don't Know JS Yet: Objects & Classes - 2nd Edition\n\n| NOTE: |\n| :--- |\n| Work in progress |\n\n## Table of Contents\n\n* Foreword\n* Preface\n* Chapter 1: Object Foundations\n    * About This Book\n    * Objects As Containers\n    * Defining Properties\n    * Accessing Properties\n    * Assigning Properties\n    * Deleting Properties\n    * Determining Container Contents\n    * Temporary Containers\n    * Containers Are Collections Of Properties\n* Chapter 2: How Objects Work\n    * Property Descriptors\n    * Object Sub-Types\n    * Object Characteristics\n    * Extending the MOP\n    * `[[Prototype]]` Chain\n    * Objects Behavior\n* Chapter 3: Classy Objects\n    * When Should I Class-Orient My Code?\n    * Keep It `class`y\n    * Class Instance `this`\n    * Class Extension\n    * Static Class Behavior\n    * Private Class Behavior\n    * Class Example\n* Chapter 4: This Works\n    * This Aware\n    * This Is It!\n    * An Arrow Points Somewhere\n    * Variations\n    * Stay Aware\n* Chapter 5: Delegation\n    * Preamble\n    * What's A Constructor, Anyway?\n    * Ditching Class Thinking\n    * Delegation Illustrated\n    * Composing Peer Objects\n    * Why *This*?\n* Thank You!\n* TODO:\n    * object wrappers (String, Boolean, etc)\n    * object coercions (valueof, tostring, boxing)\n    * well-known symbols extension points on objects\n    * proxies\n    * old \"prototypal class\" style\n    * \"inheritance\" objections\n    * protected visibility\n"
  },
  {
    "path": "preface.md",
    "content": "# You Don't Know JS Yet - 2nd Edition\n# Preface\n\nWelcome to the 2nd edition of the widely acclaimed *You Don't Know JS* (**YDKJS**) book series: *You Don't Know JS **Yet*** (**YDKJSY**).\n\nIf you've read any of the 1st edition books, you can expect a refreshed approach in these new ones, with plenty of updated coverage of what's changed in JS over the last five years. But what I hope and believe you'll still *get* is the same commitment to respecting JS and digging into what really makes it tick.\n\nIf this is your first time reading these books, I'm glad you're here. Prepare for a deep and extensive journey into all the corners of JavaScript.\n\nIf you are new to programming or JS, be aware that these books are not intended as a gentle \"intro to JavaScript.\" This material is, at times, complex and challenging, and goes much deeper than is typical for a first-time learner. You're welcome here no matter what your background is, but these books are written assuming you're already comfortable with JS and have at least 6–9 months experience with it.\n\n## The Parts\n\nThese books approach JavaScript intentionally opposite of how *The Good Parts* treats the language. No, that doesn't mean we're looking at *the bad parts*, but rather, exploring **all the parts**.\n\nYou may have been told, or felt yourself, that JS is a deeply flawed language that was poorly designed and inconsistently implemented. Many have asserted that it's the worst most popular language in the world; that nobody writes JS because they want to, only because they have to given its place at the center of the web. That's a ridiculous, unhealthy, and wholly condescending claim.\n\nMillions of developers write JavaScript every day, and many of them appreciate and respect the language.\n\nLike any great language, it has its brilliant parts as well as its scars. Even the creator of JavaScript himself, Brendan Eich, laments some of those parts as mistakes. But he's wrong: they weren't mistakes at all. JS is what it is today—the world's most ubiquitous and thus most influential programming language—precisely because of *all those parts*.\n\nDon't buy the lie that you should only learn and use a small collection of *good parts* while avoiding all the bad stuff. Don't buy the \"X is the new Y\" snake oil, that some new feature of the language instantly relegates all usage of a previous feature as obsolete and ignorant. Don't listen when someone says your code isn't \"modern\" because it isn't yet using a stage-0 feature that was only proposed a few weeks ago!\n\nEvery part of JS is useful. Some parts are more useful than others. Some parts require you to be more careful and intentional.\n\nI find it absurd to try to be a truly effective JavaScript developer while only using a small sliver of what the language has to offer. Can you imagine a construction worker with a toolbox full of tools, who only uses their hammer and scoffs at the screwdriver or tape measure as inferior? That's just silly.\n\nMy unreserved claim is that you should go about learning all parts of JavaScript, and where appropriate, use them! And if I may be so bold as to suggest: it's time to discard any JS books that tell you otherwise.\n\n## The Title?\n\nSo what's the title of the series all about?\n\nI'm not trying to insult you with criticism about your current lack of knowledge or understanding of JavaScript. I'm not suggesting you can't or won't be able to learn JavaScript. I'm not boasting about secret advanced insider wisdom that I and only a select few possess.\n\nSeriously, all those were real reactions to the original series title before folks even read the books. And they're baseless.\n\nThe primary point of the title \"You Don't Know JS Yet\" is to point out that most JS developers don't take the time to really understand how the code that they write works. They know *that* it works—that it produces a desired outcome. But they either don't understand exactly *how*, or worse, they have an inaccurate mental model for the *how* that falters on closer scrutiny.\n\nI'm presenting a gentle but earnest challenge to you the reader, to set aside the assumptions you have about JS, and approach it with fresh eyes and an invigorated curiosity that leads you to ask *why* for every line of code you write. Why does it do what it does? Why is one way better or more appropriate than the other half-dozen ways you could have accomplished it? Why do all the \"popular kids\" say to do X with your code, but it turns out that Y might be a better choice?\n\nI added \"Yet\" to the title, not only because it's the second edition, but because ultimately I want these books to challenge you in a hopeful rather than discouraging way.\n\nBut let me be clear: I don't think it's possible to ever fully *know* JS. That's not an achievement to be obtained, but a goal to strive after. You don't finish knowing everything about JS, you just keep learning more and more as you spend more time with the language. And the deeper you go, the more you revisit what you *knew* before, and you re-learn it from that more experienced perspective.\n\nI encourage you to adopt a mindset around JavaScript, and indeed all of software development, that you will never fully have mastered it, but that you can and should keep working to get closer to that end, a journey that will stretch for the entirety of your software development career, and beyond.\n\nYou can always know JS better than you currently do. That's what I hope these YDKJSY books represent.\n\n## The Mission\n\nThe case doesn't really need to be made for why developers should take JS seriously—I think it's already more than proven worthy of first-class status among the world's programming languages.\n\nBut a different, more important case still needs to be made, and these books rise to that challenge.\n\nI've taught more than 5,000 developers from teams and companies all over the world, in more than 25 countries on six continents. And what I've seen is that far too often, what *counts* is generally just the result of the program, not how the program is written or how/why it works.\n\nMy experience not only as a developer but in teaching many other developers tells me: you will always be more effective in your development work if you more completely understand how your code works than you are solely *just* getting it to produce a desired outcome.\n\nIn other words, *good enough to work* is not, and should not be, *good enough*.\n\nAll developers regularly struggle with some piece of code not working correctly, and they can't figure out why. But far too often, JS developers will blame this on the language rather than admitting it's their own understanding that is falling short. These books serve as both the question and answer: why did it do *this*, and here's how to get it to do *that* instead.\n\nMy mission with YDKJSY is to empower every single JS developer to fully own the code they write, to understand it and to write with intention and clarity.\n\n## The Path\n\nSome of you have started reading this book with the goal of completing all six books, back to back.\n\nI would like to caution you to consider changing that plan.\n\nIt is not my intention that YDKJSY be read straight through. The material in these books is dense, because JavaScript is powerful, sophisticated, and in parts rather complex. Nobody can really hope to *download* all this information to their brains in a single pass and retain any significant amount of it. That's unreasonable, and it's foolish to try.\n\nMy suggestion is you take your time going through YDKJSY. Take one chapter, read it completely through start to finish, and then go back and re-read it section by section. Stop in between each section, and practice the code or ideas from that section. For larger concepts, it probably is a good idea to expect to spend several days digesting, re-reading, practicing, then digesting some more.\n\nYou could spend a week or two on each chapter, and a month or two on each book, and a year or more on the whole series, and you would still not be squeezing every ounce of YDKJSY out.\n\nDon't binge these books; be patient and spread out your reading. Interleave reading with lots of practice on real code in your job or on projects you participate in. Wrestle with the opinions I've presented along the way, debate with others, and most of all, disagree with me! Run a study group or book club. Teach mini-workshops at your office. Write blog posts on what you've learned. Speak about these topics at local JS meetups.\n\nIt's never my goal to convince you to agree with my opinion, but to encourage you to own and be able to defend your opinions. You can't get *there* with an expedient read-through of these books. That's something that takes a long while to emerge, little by little, as you study and ponder and re-visit.\n\nThese books are meant to be a field-guide on your wanderings through JavaScript, from wherever you currently are with the language, to a place of deeper understanding. And the deeper you understand JS, the more questions you will ask and the more you will have to explore! That's what I find so exciting!\n\nI'm so glad you're embarking on this journey, and I am so honored you would consider and consult these books along the way. It's time to start *getting to know JS*.\n"
  },
  {
    "path": "scope-closures/README.md",
    "content": "# You Don't Know JS Yet: Scope & Closures - 2nd Edition\n\n<img src=\"images/cover.png\" width=\"300\">\n\n-----\n\n**[Purchase ebook/PDF from Leanpub](https://leanpub.com/ydkjsy-scope-closures)**\n\n-----\n\n[Table of Contents](toc.md)\n\n* [Foreword](foreword.md) (by [Sarah Drasner](https://sarah.dev/))\n* [Preface](../preface.md)\n* [Chapter 1: What's the Scope?](ch1.md)\n* [Chapter 2: Illustrating Lexical Scope](ch2.md)\n* [Chapter 3: The Scope Chain](ch3.md)\n* [Chapter 4: Around the Global Scope](ch4.md)\n* [Chapter 5: The (Not So) Secret Lifecycle of Variables](ch5.md)\n* [Chapter 6: Limiting Scope Exposure](ch6.md)\n* [Chapter 7: Using Closures](ch7.md)\n* [Chapter 8: The Module Pattern](ch8.md)\n* [Appendix A: Exploring Further](apA.md)\n* [Appendix B: Practice](apB.md)\n"
  },
  {
    "path": "scope-closures/apA.md",
    "content": "# You Don't Know JS Yet: Scope & Closures - 2nd Edition\n# Appendix A: Exploring Further\n\nWe will now explore a number of nuances and edges around many of the topics covered in the main text of this book. This appendix is optional, supporting material.\n\nSome people find diving too deeply into the nuanced corner cases and varying opinions creates nothing but noise and distraction—supposedly, developers are better served by sticking to the commonly-tread paths. My approach has been criticized as being impractical and counterproductive. I understand and appreciate that perspective, even if I don't necessarily share it.\n\nI believe it's better to be empowered by knowledge of how things work than to just gloss over details with assumptions and lack of curiosity. Ultimately, you will encounter situations where something bubbles up from a piece you hadn't explored. In other words, you won't get to spend all your time riding on the smooth *happy path*. Wouldn't you rather be prepared for the inevitable bumps of off-roading?\n\nThese discussions will also be more heavily influenced by my opinions than the main text was, so keep that in mind as you consume and consider what is presented. This appendix is a bit like a collection of mini-blog posts that elaborate on various book topics. It's long and deep in the weeds, so take your time and don't rush through everything here.\n\n## Implied Scopes\n\nScopes are sometimes created in non-obvious places. In practice, these implied scopes don't often impact your program behavior, but it's still useful to know they're happening. Keep an eye out for the following surprising scopes:\n\n* Parameter scope\n* Function name scope\n\n### Parameter Scope\n\nThe conversation metaphor in Chapter 2 implies that function parameters are basically the same as locally declared variables in the function scope. But that's not always true.\n\nConsider:\n\n```js\n// outer/global scope: RED(1)\n\nfunction getStudentName(studentID) {\n    // function scope: BLUE(2)\n\n    // ..\n}\n```\n\nHere, `studentID` is a considered a \"simple\" parameter, so it does behave as a member of the BLUE(2) function scope. But if we change it to be a non-simple parameter, that's no longer technically the case. Parameter forms considered non-simple include parameters with default values, rest parameters (using `...`), and destructured parameters.\n\nConsider:\n\n```js\n// outer/global scope: RED(1)\n\nfunction getStudentName(/*BLUE(2)*/ studentID = 0) {\n    // function scope: GREEN(3)\n\n    // ..\n}\n```\n\nHere, the parameter list essentially becomes its own scope, and the function's scope is then nested inside *that* scope.\n\nWhy? What difference does it make? The non-simple parameter forms introduce various corner cases, so the parameter list becomes its own scope to more effectively deal with them.\n\nConsider:\n\n```js\nfunction getStudentName(studentID = maxID, maxID) {\n    // ..\n}\n```\n\nAssuming left-to-right operations, the default `= maxID` for the `studentID` parameter requires a `maxID` to already exist (and to have been initialized). This code produces a TDZ error (Chapter 5). The reason is that `maxID` is declared in the parameter scope, but it's not yet been initialized because of the order of parameters. If the parameter order is flipped, no TDZ error occurs:\n\n```js\nfunction getStudentName(maxID,studentID = maxID) {\n    // ..\n}\n```\n\nThe complication gets even more *in the weeds* if we introduce a function expression into the default parameter position, which then can create its own closure (Chapter 7) over parameters in this implied parameter scope:\n\n```js\nfunction whatsTheDealHere(id,defaultID = () => id) {\n    id = 5;\n    console.log( defaultID() );\n}\n\nwhatsTheDealHere(3);\n// 5\n```\n\nThat snippet probably makes sense, because the `defaultID()` arrow function closes over the `id` parameter/variable, which we then re-assign to `5`. But now let's introduce a shadowing definition of `id` in the function scope:\n\n```js\nfunction whatsTheDealHere(id,defaultID = () => id) {\n    var id = 5;\n    console.log( defaultID() );\n}\n\nwhatsTheDealHere(3);\n// 3\n```\n\nUh oh! The `var id = 5` is shadowing the `id` parameter, but the closure of the `defaultID()` function is over the parameter, not the shadowing variable in the function body. This proves there's a scope bubble around the parameter list.\n\nBut it gets even crazier than that!\n\n```js\nfunction whatsTheDealHere(id,defaultID = () => id) {\n    var id;\n\n    console.log(`local variable 'id': ${ id }`);\n    console.log(\n        `parameter 'id' (closure): ${ defaultID() }`\n    );\n\n    console.log(\"reassigning 'id' to 5\");\n    id = 5;\n\n    console.log(`local variable 'id': ${ id }`);\n    console.log(\n        `parameter 'id' (closure): ${ defaultID() }`\n    );\n}\n\nwhatsTheDealHere(3);\n// local variable 'id': 3   <--- Huh!? Weird!\n// parameter 'id' (closure): 3\n// reassigning 'id' to 5\n// local variable 'id': 5\n// parameter 'id' (closure): 3\n```\n\nThe strange bit here is the first console message. At that moment, the shadowing `id` local variable has just been `var id` declared, which Chapter 5 asserts is typically auto-initialized to `undefined` at the top of its scope. Why doesn't it print `undefined`?\n\nIn this specific corner case (for legacy compat reasons), JS doesn't auto-initialize `id` to `undefined`, but rather to the value of the `id` parameter (`3`)!\n\nThough the two `id`s look at that moment like they're one variable, they're actually still separate (and in separate scopes). The `id = 5` assignment makes the divergence observable, where the `id` parameter stays `3` and the local variable becomes `5`.\n\nMy advice to avoid getting bitten by these weird nuances:\n\n* Never shadow parameters with local variables\n\n* Avoid using a default parameter function that closes over any of the parameters\n\nAt least now you're aware and can be careful about the fact that the parameter list is its own scope if any of the parameters are non-simple.\n\n### Function Name Scope\n\nIn the \"Function Name Scope\" section in Chapter 3, I asserted that the name of a function expression is added to the function's own scope. Recall:\n\n```js\nvar askQuestion = function ofTheTeacher(){\n    // ..\n};\n```\n\nIt's true that `ofTheTeacher` is not added to the enclosing scope (where `askQuestion` is declared), but it's also not *just* added to the scope of the function, the way you're likely assuming. It's another strange corner case of implied scope.\n\nThe name identifier of a function expression is in its own implied scope, nested between the outer enclosing scope and the main inner function scope.\n\nIf `ofTheTeacher` was in the function's scope, we'd expect an error here:\n\n```js\nvar askQuestion = function ofTheTeacher(){\n    // why is this not a duplicate declaration error?\n    let ofTheTeacher = \"Confused, yet?\";\n};\n```\n\nThe `let` declaration form does not allow re-declaration (see Chapter 5). But this is perfectly legal shadowing, not re-declaration, because the two `ofTheTeacher` identifiers are in separate scopes.\n\nYou'll rarely run into any case where the scope of a function's name identifier matters. But again, it's good to know how these mechanisms actually work. To avoid being bitten, never shadow function name identifiers.\n\n## Anonymous vs. Named Functions\n\nAs discussed in Chapter 3, functions can be expressed either in named or anonymous form. It's vastly more common to use the anonymous form, but is that a good idea?\n\nAs you contemplate naming your functions, consider:\n\n* Name inference is incomplete\n* Lexical names allow self-reference\n* Names are useful descriptions\n* Arrow functions have no lexical names\n* IIFEs also need names\n\n### Explicit or Inferred Names?\n\nEvery function in your program has a purpose. If it doesn't have a purpose, take it out, because you're just wasting space. If it *does* have a purpose, there *is* a name for that purpose.\n\nSo far many readers likely agree with me. But does that mean we should always put that name into the code? Here's where I'll raise more than a few eyebrows. I say, unequivocally, yes!\n\nFirst of all, \"anonymous\" showing up in stack traces is just not all that helpful to debugging:\n\n```js\nbtn.addEventListener(\"click\",function(){\n    setTimeout(function(){\n        [\"a\",42].map(function(v){\n            console.log(v.toUpperCase());\n        });\n    },100);\n});\n// Uncaught TypeError: v.toUpperCase is not a function\n//     at myProgram.js:4\n//     at Array.map (<anonymous>)\n//     at myProgram.js:3\n```\n\nUgh. Compare to what is reported if I give the functions names:\n\n```js\nbtn.addEventListener(\"click\",function onClick(){\n    setTimeout(function waitAMoment(){\n        [\"a\",42].map(function allUpper(v){\n            console.log(v.toUpperCase());\n        });\n    },100);\n});\n// Uncaught TypeError: v.toUpperCase is not a function\n//     at allUpper (myProgram.js:4)\n//     at Array.map (<anonymous>)\n//     at waitAMoment (myProgram.js:3)\n```\n\nSee how `waitAMoment` and `allUpper` names appear and give the stack trace more useful information/context for debugging? The program is more debuggable if we use reasonable names for all our functions.\n\n| NOTE: |\n| :--- |\n| The unfortunate \"&lt;anonymous>\" that still shows up refers to the fact that the implementation of `Array.map(..)` isn't present in our program, but is built into the JS engine. It's not from any confusion our program introduces with readability shortcuts. |\n\nBy the way, let's make sure we're on the same page about what a named function is:\n\n```js\nfunction thisIsNamed() {\n    // ..\n}\n\najax(\"some.url\",function thisIsAlsoNamed(){\n   // ..\n});\n\nvar notNamed = function(){\n    // ..\n};\n\nmakeRequest({\n    data: 42,\n    cb /* also not a name */: function(){\n        // ..\n    }\n});\n\nvar stillNotNamed = function butThisIs(){\n    // ..\n};\n```\n\n\"But wait!\", you say. Some of those *are* named, right!?\n\n```js\nvar notNamed = function(){\n    // ..\n};\n\nvar config = {\n    cb: function(){\n        // ..\n    }\n};\n\nnotNamed.name;\n// notNamed\n\nconfig.cb.name;\n// cb\n```\n\nThese are referred to as *inferred* names. Inferred names are fine, but they don't really address the full concern I'm discussing.\n\n### Missing Names?\n\nYes, these inferred names might show up in stack traces, which is definitely better than \"anonymous\" showing up. But...\n\n```js\nfunction ajax(url,cb) {\n    console.log(cb.name);\n}\n\najax(\"some.url\",function(){\n    // ..\n});\n// \"\"\n```\n\nOops. Anonymous `function` expressions passed as callbacks are incapable of receiving an inferred name, so `cb.name` holds just the empty string `\"\"`. The vast majority of all `function` expressions, especially anonymous ones, are used as callback arguments; none of these get a name. So relying on name inference is incomplete, at best.\n\nAnd it's not just callbacks that fall short with inference:\n\n```js\nvar config = {};\n\nconfig.cb = function(){\n    // ..\n};\n\nconfig.cb.name;\n// \"\"\n\nvar [ noName ] = [ function(){} ];\nnoName.name\n// \"\"\n```\n\nAny assignment of a `function` expression that's not a *simple assignment* will also fail name inferencing. So, in other words, unless you're careful and intentional about it, essentially almost all anonymous `function` expressions in your program will in fact have no name at all.\n\nName inference is just... not enough.\n\nAnd even if a `function` expression *does* get an inferred name, that still doesn't count as being a full named function.\n\n### Who am I?\n\nWithout a lexical name identifier, the function has no internal way to refer to itself. Self-reference is important for things like recursion and event handling:\n\n```js\n// broken\nrunOperation(function(num){\n    if (num <= 1) return 1;\n    return num * oopsNoNameToCall(num - 1);\n});\n\n// also broken\nbtn.addEventListener(\"click\",function(){\n   console.log(\"should only respond to one click!\");\n   btn.removeEventListener(\"click\",oopsNoNameHere);\n});\n```\n\nLeaving off the lexical name from your callback makes it harder to reliably self-reference the function. You *could* declare a variable in an enclosing scope that references the function, but this variable is *controlled* by that enclosing scope—it could be re-assigned, etc.—so it's not as reliable as the function having its own internal self-reference.\n\n### Names are Descriptors\n\nLastly, and I think most importantly of all, leaving off a name from a function makes it harder for the reader to tell what the function's purpose is, at a quick glance. They have to read more of the code, including the code inside the function, and the surrounding code outside the function, to figure it out.\n\nConsider:\n\n```js\n[ 1, 2, 3, 4, 5 ].filter(function(v){\n    return v % 2 == 1;\n});\n// [ 1, 3, 5 ]\n\n[ 1, 2, 3, 4, 5 ].filter(function keepOnlyOdds(v){\n    return v % 2 == 1;\n});\n// [ 1, 3, 5 ]\n```\n\nThere's just no reasonable argument to be made that **omitting** the name `keepOnlyOdds` from the first callback more effectively communicates to the reader the purpose of this callback. You saved 13 characters, but lost important readability information. The name `keepOnlyOdds` very clearly tells the reader, at a quick first glance, what's happening.\n\nThe JS engine doesn't care about the name. But human readers of your code absolutely do.\n\nCan the reader look at `v % 2 == 1` and figure out what it's doing? Sure. But they have to infer the purpose (and name) by mentally executing the code. Even a brief pause to do so slows down reading of the code. A good descriptive name makes this process almost effortless and instant.\n\nThink of it this way: how many times does the author of this code need to figure out the purpose of a function before adding the name to the code? About once. Maybe two or three times if they need to adjust the name. But how many times will readers of this code have to figure out the name/purpose? Every single time this line is ever read. Hundreds of times? Thousands? More?\n\nNo matter the length or complexity of the function, my assertion is, the author should figure out a good descriptive name and add it to the code. Even the one-liner functions in `map(..)` and `then(..)` statements should be named:\n\n```js\nlookupTheRecords(someData)\n.then(function extractSalesRecords(resp){\n   return resp.allSales;\n})\n.then(storeRecords);\n```\n\nThe name `extractSalesRecords` tells the reader the purpose of this `then(..)` handler *better* than just inferring that purpose from mentally executing `return resp.allSales`.\n\nThe only excuse for not including a name on a function is either laziness (don't want to type a few extra characters) or uncreativity (can't come up with a good name). If you can't figure out a good name, you likely don't understand the function and its purpose yet. The function is perhaps poorly designed, or it does too many things, and should be re-worked. Once you have a well-designed, single-purpose function, its proper name should become evident.\n\nHere's a trick I use: while first writing a function, if I don't fully understand its purpose and can't think of a good name to use, I just use `TODO` as the name. That way, later when reviewing my code, I'm likely to find those name placeholders, and I'm more inclined (and more prepared!) to go back and figure out a better name, rather than just leave it as `TODO`.\n\nAll functions need names. Every single one. No exceptions. Any name you omit is making the program harder to read, harder to debug, harder to extend and maintain later.\n\n### Arrow Functions\n\nArrow functions are **always** anonymous, even if (rarely) they're used in a way that gives them an inferred name. I just spent several pages explaining why anonymous functions are a bad idea, so you can probably guess what I think about arrow functions.\n\nDon't use them as a general replacement for regular functions. They're more concise, yes, but that brevity comes at the cost of omitting key visual delimiters that help our brains quickly parse out what we're reading. And, to the point of this discussion, they're anonymous, which makes them worse for readability from that angle as well.\n\nArrow functions have a purpose, but that purpose is not to save keystrokes. Arrow functions have *lexical this* behavior, which is somewhat beyond the bounds of our discussion in this book.\n\nBriefly: arrow functions don't define a `this` identifier keyword at all. If you use a `this` inside an arrow function, it behaves exactly as any other variable reference, which is that the scope chain is consulted to find a function scope (non-arrow function) where it *is* defined, and to use that one.\n\nIn other words, arrow functions treat `this` like any other lexical variable.\n\nIf you're used to hacks like `var self = this`, or if you prefer to call `.bind(this)` on inner `function` expressions, just to force them to inherit a `this` from an outer function like it was a lexical variable, then `=>` arrow functions are absolutely the better option. They're designed specifically to fix that problem.\n\nSo, in the rare cases you need *lexical this*, use an arrow function. It's the best tool for that job. But just be aware that in doing so, you're accepting the downsides of an anonymous function. You should expend additional effort to mitigate the readability *cost*, such as more descriptive variable names and code comments.\n\n### IIFE Variations\n\nAll functions should have names. I said that a few times, right!? That includes IIFEs.\n\n```js\n(function(){\n    // don't do this!\n})();\n\n(function doThisInstead(){\n    // ..\n})();\n```\n\nHow do we come up with a name for an IIFE? Identify what the IIFE is there for. Why do you need a scope in that spot? Are you hiding a cache variable for student records?\n\n```js\nvar getStudents = (function StoreStudentRecords(){\n    var studentRecords = [];\n\n    return function getStudents() {\n        // ..\n    }\n})();\n```\n\nI named the IIFE `StoreStudentRecords` because that's what it's doing: storing student records. Every IIFE should have a name. No exceptions.\n\nIIFEs are typically defined by placing `( .. )` around the `function` expression, as shown in those previous snippets. But that's not the only way to define an IIFE. Technically, the only reason we're using that first surrounding set of `( .. )` is just so the `function` keyword isn't in a position to qualify as a `function` declaration to the JS parser. But there are other syntactic ways to avoid being parsed as a declaration:\n\n```js\n!function thisIsAnIIFE(){\n    // ..\n}();\n\n+function soIsThisOne(){\n    // ..\n}();\n\n~function andThisOneToo(){\n    // ..\n}();\n```\n\nThe `!`, `+`, `~`, and several other unary operators (operators with one operand) can all be placed in front of `function` to turn it into an expression. Then the final `()` call is valid, which makes it an IIFE.\n\nI actually kind of like using the `void` unary operator when defining a standalone IIFE:\n\n```js\nvoid function yepItsAnIIFE() {\n    // ..\n}();\n```\n\nThe benefit of `void` is, it clearly communicates at the beginning of the function that this IIFE won't be returning any value.\n\nHowever you define your IIFEs, show them some love by giving them names.\n\n## Hoisting: Functions and Variables\n\nChapter 5 articulated both *function hoisting* and *variable hoisting*. Since hoisting is often cited as mistake in the design of JS, I wanted to briefly explore why both these forms of hoisting *can* be beneficial and should still be considered.\n\nGive hoisting a deeper level of consideration by considering the merits of:\n\n* Executable code first, function declarations last\n* Semantic placement of variable declarations\n\n### Function Hoisting\n\nTo review, this program works because of *function hoisting*:\n\n```js\ngetStudents();\n\n// ..\n\nfunction getStudents() {\n    // ..\n}\n```\n\nThe `function` declaration is hoisted during compilation, which means that `getStudents` is an identifier declared for the entire scope. Additionally, the `getStudents` identifier is auto-initialized with the function reference, again at the beginning of the scope.\n\nWhy is this useful? The reason I prefer to take advantage of *function hoisting* is that it puts the *executable* code in any scope at the top, and any further declarations (functions) below. This means it's easier to find the code that will run in any given area, rather than having to scroll and scroll, hoping to find a trailing `}` marking the end of a scope/function somewhere.\n\nI take advantage of this inverse positioning in all levels of scope:\n\n```js\ngetStudents();\n\n// *************\n\nfunction getStudents() {\n    var whatever = doSomething();\n\n    // other stuff\n\n    return whatever;\n\n    // *************\n\n    function doSomething() {\n        // ..\n    }\n}\n```\n\nWhen I first open a file like that, the very first line is executable code that kicks off its behavior. That's very easy to spot! Then, if I ever need to go find and inspect `getStudents()`, I like that its first line is also executable code. Only if I need to see the details of `doSomething()` do I go and find its definition down below.\n\nIn other words, I think *function hoisting* makes code more readable through a flowing, progressive reading order, from top to bottom.\n\n### Variable Hoisting\n\nWhat about *variable hoisting*?\n\nEven though `let` and `const` hoist, you cannot use those variables in their TDZ (see Chapter 5). So, the following discussion only applies to `var` declarations. Before I continue, I'll admit: in almost all cases, I completely agree that *variable hoisting* is a bad idea:\n\n```js\npleaseDontDoThis = \"bad idea\";\n\n// much later\nvar pleaseDontDoThis;\n```\n\nWhile that kind of inverted ordering was helpful for *function hoisting*, here I think it usually makes code harder to reason about.\n\nBut there's one exception that I've found, somewhat rarely, in my own coding. It has to do with where I place my `var` declarations inside a CommonJS module definition.\n\nHere's how I typically structure my module definitions in Node:\n\n```js\n// dependencies\nvar aModuleINeed = require(\"very-helpful\");\nvar anotherModule = require(\"kinda-helpful\");\n\n// public API\nvar publicAPI = Object.assign(module.exports,{\n    getStudents,\n    addStudents,\n    // ..\n});\n\n// ********************************\n// private implementation\n\nvar cache = { };\nvar otherData = [ ];\n\nfunction getStudents() {\n    // ..\n}\n\nfunction addStudents() {\n    // ..\n}\n```\n\nNotice how the `cache` and `otherData` variables are in the \"private\" section of the module layout? That's because I don't plan to expose them publicly. So I organize the module so they're located alongside the other hidden implementation details of the module.\n\nBut I've had a few rare cases where I needed the assignments of those values to happen *above*, before I declare the exported public API of the module. For instance:\n\n```js\n// public API\nvar publicAPI = Object.assign(module.exports,{\n    getStudents,\n    addStudents,\n    refreshData: refreshData.bind(null,cache)\n});\n```\n\nI need the `cache` variable to have already been assigned a value, because that value is used in the initialization of the public API (the `.bind(..)` partial-application).\n\nShould I just move the `var cache = { .. }` up to the top, above this public API initialization? Well, perhaps. But now it's less obvious that `var cache` is a *private* implementation detail. Here's the compromise I've (somewhat rarely) used:\n\n```js\ncache = {};   // used here, but declared below\n\n// public API\nvar publicAPI = Object.assign(module.exports,{\n    getStudents,\n    addStudents,\n    refreshData: refreshData.bind(null,cache)\n});\n\n// ********************************\n// private implementation\n\nvar cache /* = {}*/;\n```\n\nSee the *variable hoisting*? I've declared the `cache` down where it belongs, logically, but in this rare case I've used it earlier up above, in the area where its initialization is needed. I even left a hint at the value that's assigned to `cache` in a code comment.\n\nThat's literally the only case I've ever found for leveraging *variable hoisting* to assign a variable earlier in a scope than its declaration. But I think it's a reasonable exception to employ with caution.\n\n## The Case for `var`\n\nSpeaking of *variable hoisting*, let's have some real talk for a bit about `var`, a favorite villain devs love to blame for many of the woes of JS development. In Chapter 5, we explored `let`/`const` and promised we'd revisit where `var` falls in the whole mix.\n\nAs I lay out the case, don't miss:\n\n* `var` was never broken\n* `let` is your friend\n* `const` has limited utility\n* The best of both worlds: `var` *and* `let`\n\n### Don't Throw Out `var`\n\n`var` is fine, and works just fine. It's been around for 25 years, and it'll be around and useful and functional for another 25 years or more. Claims that `var` is broken, deprecated, outdated, dangerous, or ill-designed are bogus bandwagoning.\n\nDoes that mean `var` is the right declarator for every single declaration in your program? Certainly not. But it still has its place in your programs. Refusing to use it because someone on the team chose an aggressive linter opinion that chokes on `var` is cutting off your nose to spite your face.\n\nOK, now that I've got you really riled up, let me try to explain my position.\n\nFor the record, I'm a fan of `let`, for block-scoped declarations. I really dislike TDZ and I think that was a mistake. But `let` itself is great. I use it often. In fact, I probably use it as much or more than I use `var`.\n\n### `const`-antly Confused\n\n`const` on the other hand, I don't use as often. I'm not going to dig into all the reasons why, but it comes down to `const` not *carrying its own weight*. That is, while there's a tiny bit of benefit of `const` in some cases, that benefit is outweighed by the long history of troubles around `const` confusion in a variety of languages, long before it ever showed up in JS.\n\n`const` pretends to create values that can't be mutated—a misconception that's extremely common in developer communities across many languages—whereas what it really does is prevent re-assignment.\n\n```js\nconst studentIDs = [ 14, 73, 112 ];\n\n// later\n\nstudentIDs.push(6);   // whoa, wait... what!?\n```\n\nUsing a `const` with a mutable value (like an array or object) is asking for a future developer (or reader of your code) to fall into the trap you set, which was that they either didn't know, or sorta forgot, that *value immutability* isn't at all the same thing as *assignment immutability*.\n\nI just don't think we should set those traps. The only time I ever use `const` is when I'm assigning an already-immutable value (like `42` or `\"Hello, friends!\"`), and when it's clearly a \"constant\" in the sense of being a named placeholder for a literal value, for semantic purposes. That's what `const` is best used for. That's pretty rare in my code, though.\n\nIf variable re-assignment were a big deal, then `const` would be more useful. But variable re-assignment just isn't that big of a deal in terms of causing bugs. There's a long list of things that lead to bugs in programs, but \"accidental re-assignment\" is way, way down that list.\n\nCombine that with the fact that `const` (and `let`) are supposed to be used in blocks, and blocks are supposed to be short, and you have a really small area of your code where a `const` declaration is even applicable. A `const` on line 1 of your ten-line block only tells you something about the next nine lines. And the thing it tells you is already obvious by glancing down at those nine lines: the variable is never on the left-hand side of an `=`; it's not re-assigned.\n\nThat's it, that's all `const` really does. Other than that, it's not very useful. Stacked up against the significant confusion of value vs. assignment immutability, `const` loses a lot of its luster.\n\nA `let` (or `var`!) that's never re-assigned is already behaviorally a \"constant\", even though it doesn't have the compiler guarantee. That's good enough in most cases.\n\n### `var` *and* `let`\n\nIn my mind, `const` is pretty rarely useful, so this is only two-horse race between `let` and `var`. But it's not really a race either, because there doesn't have to be just one winner. They can both win... different races.\n\nThe fact is, you should be using both `var` and `let` in your programs. They are not interchangeable: you shouldn't use `var` where a `let` is called for, but you also shouldn't use `let` where a `var` is most appropriate.\n\nSo where should we still use `var`? Under what circumstances is it a better choice than `let`?\n\nFor one, I always use `var` in the top-level scope of any function, regardless of whether that's at the beginning, middle, or end of the function. I also use `var` in the global scope, though I try to minimize usage of the global scope.\n\nWhy use `var` for function scoping? Because that's exactly what `var` does. There literally is no better tool for the job of function scoping a declaration than a declarator that has, for 25 years, done exactly that.\n\nYou *could* use `let` in this top-level scope, but it's not the best tool for that job. I also find that if you use `let` everywhere, then it's less obvious which declarations are designed to be localized and which ones are intended to be used throughout the function.\n\nBy contrast, I rarely use a `var` inside a block. That's what `let` is for. Use the best tool for the job. If you see a `let`, it tells you that you're dealing with a localized declaration. If you see `var`, it tells you that you're dealing with a function-wide declaration. Simple as that.\n\n```js\nfunction getStudents(data) {\n    var studentRecords = [];\n\n    for (let record of data.records) {\n        let id = `student-${ record.id }`;\n        studentRecords.push({\n            id,\n            record.name\n        });\n    }\n\n    return studentRecords;\n}\n```\n\nThe `studentRecords` variable is intended for use across the whole function. `var` is the best declarator to tell the reader that. By contrast, `record` and `id` are intended for use only in the narrower scope of the loop iteration, so `let` is the best tool for that job.\n\nIn addition to this *best tool* semantic argument, `var` has a few other characteristics that, in certain limited circumstances, make it more powerful.\n\nOne example is when a loop is exclusively using a variable, but its conditional clause cannot see block-scoped declarations inside the iteration:\n\n```js\nfunction commitAction() {\n    do {\n        let result = commit();\n        var done = result && result.code == 1;\n    } while (!done);\n}\n```\n\nHere, `result` is clearly only used inside the block, so we use `let`. But `done` is a bit different. It's only useful for the loop, but the `while` clause cannot see `let` declarations that appear inside the loop. So we compromise and use `var`, so that `done` is hoisted to the outer scope where it can be seen.\n\nThe alternative—declaring `done` outside the loop—separates it from where it's first used, and either necessitates picking a default value to assign, or worse, leaving it unassigned and thus looking ambiguous to the reader. I think `var` inside the loop is preferable here.\n\nAnother helpful characteristic of `var` is seen with declarations inside unintended blocks. Unintended blocks are blocks that are created because the syntax requires a block, but where the intent of the developer is not really to create a localized scope. The best illustration of unintended scope is the `try..catch` statement:\n\n```js\nfunction getStudents() {\n    try {\n        // not really a block scope\n        var records = fromCache(\"students\");\n    }\n    catch (err) {\n        // oops, fall back to a default\n        var records = [];\n    }\n    // ..\n}\n```\n\nThere are other ways to structure this code, yes. But I think this is the *best* way, given various trade-offs.\n\nI don't want to declare `records` (with `var` or `let`) outside of the `try` block, and then assign to it in one or both blocks. I prefer initial declarations to always be as close as possible (ideally, same line) to the first usage of the variable. In this simple example, that would only be a couple of lines distance, but in real code it can grow to many more lines. The bigger the gap, the harder it is to figure out what variable from what scope you're assigning to. `var` used at the actual assignment makes it less ambiguous.\n\nAlso notice I used `var` in both the `try` and `catch` blocks. That's because I want to signal to the reader that no matter which path is taken, `records` always gets declared. Technically, that works because `var` is hoisted once to the function scope. But it's still a nice semantic signal to remind the reader what either `var` ensures. If `var` were only used in one of the blocks, and you were only reading the other block, you wouldn't as easily discover where `records` was coming from.\n\nThis is, in my opinion, a little superpower of `var`. Not only can it escape the unintentional `try..catch` blocks, but it's allowed to appear multiple times in a function's scope. You can't do that with `let`. It's not bad, it's actually a little helpful feature. Think of `var` more like a declarative annotation that's reminding you, each usage, where the variable comes from. \"Ah ha, right, it belongs to the whole function.\"\n\nThis repeated-annotation superpower is useful in other cases:\n\n```js\nfunction getStudents() {\n    var data = [];\n\n    // do something with data\n    // .. 50 more lines of code ..\n\n    // purely an annotation to remind us\n    var data;\n\n    // use data again\n    // ..\n}\n```\n\nThe second `var data` is not re-declaring `data`, it's just annotating for the readers' benefit that `data` is a function-wide declaration. That way, the reader doesn't need to scroll up 50+ lines of code to find the initial declaration.\n\nI'm perfectly fine with re-using variables for multiple purposes throughout a function scope. I'm also perfectly fine with having two usages of a variable be separated by quite a few lines of code. In both cases, the ability to safely \"re-declare\" (annotate) with `var` helps make sure I can tell where my `data` is coming from, no matter where I am in the function.\n\nAgain, sadly, `let` cannot do this.\n\nThere are other nuances and scenarios when `var` turns out to offer some assistance, but I'm not going to belabor the point any further. The takeaway is that `var` can be useful in our programs alongside `let` (and the occasional `const`). Are you willing to creatively use the tools the JS language provides to tell a richer story to your readers?\n\nDon't just throw away a useful tool like `var` because someone shamed you into thinking it wasn't cool anymore. Don't avoid `var` because you got confused once years ago. Learn these tools and use them each for what they're best at.\n\n## What's the Deal with TDZ?\n\nThe TDZ (temporal dead zone) was explained in Chapter 5. We illustrated how it occurs, but we skimmed over any explanation of *why* it was necessary to introduce in the first place. Let's look briefly at the motivations of TDZ.\n\nSome breadcrumbs in the TDZ origin story:\n\n* `const`s should never change\n* It's all about time\n* Should `let` behave more like `const` or `var`?\n\n### Where It All Started\n\nTDZ comes from `const`, actually.\n\nDuring early ES6 development work, TC39 had to decide whether `const` (and `let`) were going to hoist to the top of their blocks. They decided these declarations would hoist, similar to how `var` does. Had that not been the case, I think some of the fear was confusion with mid-scope shadowing, such as:\n\n```js\nlet greeting = \"Hi!\";\n\n{\n    // what should print here?\n    console.log(greeting);\n\n    // .. a bunch of lines of code ..\n\n    // now shadowing the `greeting` variable\n    let greeting = \"Hello, friends!\";\n\n    // ..\n}\n```\n\nWhat should we do with that `console.log(..)` statement? Would it make any sense to JS devs for it to print \"Hi!\"? Seems like that could be a gotcha, to have shadowing kick in only for the second half of the block, but not the first half. That's not very intuitive, JS-like behavior. So `let` and `const` have to hoist to the top of the block, visible throughout.\n\nBut if `let` and `const` hoist to the top of the block (like `var` hoists to the top of a function), why don't `let` and `const` auto-initialize (to `undefined`) the way `var` does? Here was the main concern:\n\n```js\n{\n    // what should print here?\n    console.log(studentName);\n\n    // later\n\n    const studentName = \"Frank\";\n\n    // ..\n}\n```\n\nLet's imagine that `studentName` not only hoisted to the top of this block, but was also auto-initialized to `undefined`. For the first half of the block, `studentName` could be observed to have the `undefined` value, such as with our `console.log(..)` statement. Once the `const studentName = ..` statement is reached, now `studentName` is assigned `\"Frank\"`. From that point forward, `studentName` can't ever be re-assigned.\n\nBut, is it strange or surprising that a constant observably has two different values, first `undefined`, then `\"Frank\"`? That does seem to go against what we think a `const`ant means; it should only ever be observable with one value.\n\nSo... now we have a problem. We can't auto-initialize `studentName` to `undefined` (or any other value for that matter). But the variable has to exist throughout the whole scope. What do we do with the period of time from when it first exists (beginning of scope) and when it's assigned its value?\n\nWe call this period of time the \"dead zone,\" as in the \"temporal dead zone\" (TDZ). To prevent confusion, it was determined that any sort of access of a variable while in its TDZ is illegal and must result in the TDZ error.\n\nOK, that line of reasoning does make some sense, I must admit.\n\n### Who `let` the TDZ Out?\n\nBut that's just `const`. What about `let`?\n\nWell, TC39 made the decision: since we need a TDZ for `const`, we might as well have a TDZ for `let` as well. *In fact, if we make let have a TDZ, then we discourage all that ugly variable hoisting people do.* So there was a consistency perspective and, perhaps, a bit of social engineering to shift developers' behavior.\n\nMy counter-argument would be: if you're favoring consistency, be consistent with `var` instead of `const`; `let` is definitely more like `var` than `const`. That's especially true since they had already chosen consistency with `var` for the whole hoisting-to-the-top-of-the-scope thing. Let `const` be its own unique deal with a TDZ, and let the answer to TDZ purely be: just avoid the TDZ by always declaring your constants at the top of the scope. I think this would have been more reasonable.\n\nBut alas, that's not how it landed. `let` has a TDZ because `const` needs a TDZ, because `let` and `const` mimic `var` in their hoisting to the top of the (block) scope. There ya go. Too circular? Read it again a few times.\n\n## Are Synchronous Callbacks Still Closures?\n\nChapter 7 presented two different models for tackling closure:\n\n* Closure is a function instance remembering its outer variables even as that function is passed around and **invoked in** other scopes.\n\n* Closure is a function instance and its scope environment being preserved in-place while any references to it are passed around and **invoked from** other scopes.\n\nThese models are not wildly divergent, but they do approach from a different perspective. And that different perspective changes what we identify as a closure.\n\nDon't get lost following this rabbit trail through closures and callbacks:\n\n* Calling back to what (or where)?\n* Maybe \"synchronous callback\" isn't the best label\n* ***IIF*** functions don't move around, why would they need closure?\n* Deferring over time is key to closure\n\n### What is a Callback?\n\nBefore we revisit closure, let me spend a brief moment addressing the word \"callback.\" It's a generally accepted norm that saying \"callback\" is synonymous with both *asynchronous callbacks* and *synchronous callbacks*. I don't think I agree that this is a good idea, so I want to explain why and propose we move away from that to another term.\n\nLet's first consider an *asynchronous callback*, a function reference that will be invoked at some future *later* point. What does \"callback\" mean, in this case?\n\nIt means that the current code has finished or paused, suspended itself, and that when the function in question is invoked later, execution is entering back into the suspended program, resuming it. Specifically, the point of re-entry is the code that was wrapped in the function reference:\n\n```js\nsetTimeout(function waitForASecond(){\n    // this is where JS should call back into\n    // the program when the timer has elapsed\n},1000);\n\n// this is where the current program finishes\n// or suspends\n```\n\nIn this context, \"calling back\" makes a lot of sense. The JS engine is resuming our suspended program by *calling back in* at a specific location. OK, so a callback is asynchronous.\n\n### Synchronous Callback?\n\nBut what about *synchronous callbacks*? Consider:\n\n```js\nfunction getLabels(studentIDs) {\n    return studentIDs.map(\n        function formatIDLabel(id){\n            return `Student ID: ${\n               String(id).padStart(6)\n            }`;\n        }\n    );\n}\n\ngetLabels([ 14, 73, 112, 6 ]);\n// [\n//    \"Student ID: 000014\",\n//    \"Student ID: 000073\",\n//    \"Student ID: 000112\",\n//    \"Student ID: 000006\"\n// ]\n```\n\nShould we refer to `formatIDLabel(..)` as a callback? Is the `map(..)` utility really *calling back* into our program by invoking the function we provided?\n\nThere's nothing to *call back into* per se, because the program hasn't paused or exited. We're passing a function (reference) from one part of the program to another part of the program, and then it's immediately invoked.\n\nThere's other established terms that might match what we're doing—passing in a function (reference) so that another part of the program can invoke it on our behalf. You might think of this as *Dependency Injection* (DI) or *Inversion of Control* (IoC).\n\nDI can be summarized as passing in necessary part(s) of functionality to another part of the program so that it can invoke them to complete its work. That's a decent description for the `map(..)` call above, isn't it? The `map(..)` utility knows to iterate over the list's values, but it doesn't know what to *do* with those values. That's why we pass it the `formatIDLabel(..)` function. We pass in the dependency.\n\nIoC is a pretty similar, related concept. Inversion of control means that instead of the current area of your program controlling what's happening, you hand control off to another part of the program. We wrapped the logic for computing a label string in the function `formatIDLabel(..)`, then handed invocation control to the `map(..)` utility.\n\nNotably, Martin Fowler cites IoC as the difference between a framework and a library: with a library, you call its functions; with a framework, it calls your functions. [^fowlerIOC]\n\nIn the context of our discussion, either DI or IoC could work as an alternative label for a *synchronous callback*.\n\nBut I have a different suggestion. Let's refer to (the functions formerly known as) *synchronous callbacks*, as *inter-invoked functions* (IIFs). Yes, exactly, I'm playing off IIFEs. These kinds of functions are *inter-invoked*, meaning: another entity invokes them, as opposed to IIFEs, which invoke themselves immediately.\n\nWhat's the relationship between an *asynchronous callback* and an IIF? An *asynchronous callback* is an IIF that's invoked asynchronously instead of synchronously.\n\n### Synchronous Closure?\n\nNow that we've re-labeled *synchronous callbacks* as IIFs, we can return to our main question: are IIFs an example of closure? Obviously, the IIF would have to reference variable(s) from an outer scope for it to have any chance of being a closure. The `formatIDLabel(..)` IIF from earlier does not reference any variables outside its own scope, so it's definitely not a closure.\n\nWhat about an IIF that does have external references, is that closure?\n\n```js\nfunction printLabels(labels) {\n    var list = document.getElementById(\"labelsList\");\n\n    labels.forEach(\n        function renderLabel(label){\n            var li = document.createElement(\"li\");\n            li.innerText = label;\n            list.appendChild(li);\n        }\n    );\n}\n```\n\nThe inner `renderLabel(..)` IIF references `list` from the enclosing scope, so it's an IIF that *could* have closure. But here's where the definition/model we choose for closure matters:\n\n* If `renderLabel(..)` is a **function that gets passed somewhere else**, and that function is then invoked, then yes, `renderLabel(..)` is exercising a closure, because closure is what preserved its access to its original scope chain.\n\n* But if, as in the alternative conceptual model from Chapter 7, `renderLabel(..)` stays in place, and only a reference to it is passed to `forEach(..)`, is there any need for closure to preserve the scope chain of `renderLabel(..)`, while it executes synchronously right inside its own scope?\n\nNo. That's just normal lexical scope.\n\nTo understand why, consider this alternative form of `printLabels(..)`:\n\n```js\nfunction printLabels(labels) {\n    var list = document.getElementById(\"labelsList\");\n\n    for (let label of labels) {\n        // just a normal function call in its own\n        // scope, right? That's not really closure!\n        renderLabel(label);\n    }\n\n    // **************\n\n    function renderLabel(label) {\n        var li = document.createElement(\"li\");\n        li.innerText = label;\n        list.appendChild(li);\n    }\n}\n```\n\nThese two versions of `printLabels(..)` are essentially the same.\n\nThe latter one is definitely not an example of closure, at least not in any useful or observable sense. It's just lexical scope. The former version, with `forEach(..)` calling our function reference, is essentially the same thing. It's also not closure, but rather just a plain ol' lexical scope function call.\n\n### Defer to Closure\n\nBy the way, Chapter 7 briefly mentioned partial application and currying (which *do* rely on closure!). This is an interesting scenario where manual currying can be used:\n\n```js\nfunction printLabels(labels) {\n    var list = document.getElementById(\"labelsList\");\n    var renderLabel = renderTo(list);\n\n    // definitely closure this time!\n    labels.forEach( renderLabel );\n\n    // **************\n\n    function renderTo(list) {\n        return function createLabel(label){\n            var li = document.createElement(\"li\");\n            li.innerText = label;\n            list.appendChild(li);\n        };\n    }\n}\n```\n\nThe inner function `createLabel(..)`, which we assign to `renderLabel`, is closed over `list`, so closure is definitely being utilized.\n\nClosure allows us to remember `list` for later, while we defer execution of the actual label-creation logic from the `renderTo(..)` call to the subsequent `forEach(..)` invocations of the `createLabel(..)` IIF. That may only be a brief moment here, but any amount of time could pass, as closure bridges from call to call.\n\n## Classic Module Variations\n\nChapter 8 explained the classic module pattern, which can look like this:\n\n```js\nvar StudentList = (function defineModule(Student){\n    var elems = [];\n\n    var publicAPI = {\n        renderList() {\n            // ..\n        }\n    };\n\n    return publicAPI;\n\n})(Student);\n```\n\nNotice that we're passing `Student` (another module instance) in as a dependency. But there's lots of useful variations on this module form you may encounter. Some hints for recognizing these variations:\n\n* Does the module know about its own API?\n* Even if we use a fancy module loader, it's just a classic module\n* Some modules need to work universally\n\n### Where's My API?\n\nFirst, most classic modules don't define and use a `publicAPI` the way I have shown in this code. Instead, they typically look like:\n\n```js\nvar StudentList = (function defineModule(Student){\n    var elems = [];\n\n    return {\n        renderList() {\n            // ..\n        }\n    };\n\n})(Student);\n```\n\nThe only difference here is directly returning the object that serves as the public API for the module, as opposed to first saving it to an inner `publicAPI` variable. This is by far how most classic modules are defined.\n\nBut I strongly prefer, and always use myself, the former `publicAPI` form. Two reasons:\n\n* `publicAPI` is a semantic descriptor that aids readability by making it more obvious what the purpose of the object is.\n\n* Storing an inner `publicAPI` variable that references the same external public API object returned, can be useful if you need to access or modify the API during the lifetime of the module.\n\n    For example, you may want to call one of the publicly exposed functions, from inside the module. Or, you may want to add or remove methods depending on certain conditions, or update the value of an exposed property.\n\n    Whatever the case may be, it just seems rather silly to me that we *wouldn't* maintain a reference to access our own API. Right?\n\n### Asynchronous Module Definition (AMD)\n\nAnother variation on the classic module form is AMD-style modules (popular several years back), such as those supported by the RequireJS utility:\n\n```js\ndefine([ \"./Student\" ],function StudentList(Student){\n    var elems = [];\n\n    return {\n        renderList() {\n            // ..\n        }\n    };\n});\n```\n\nIf you look closely at `StudentList(..)`, it's a classic module factory function. Inside the machinery of `define(..)` (provided by RequireJS), the `StudentList(..)` function is executed, passing to it any other module instances declared as dependencies. The return value is an object representing the public API for the module.\n\nThis is based on exactly the same principles (including how the closure works!) as we explored with classic modules.\n\n### Universal Modules (UMD)\n\nThe final variation we'll look at is UMD, which is less a specific, exact format and more a collection of very similar formats. It was designed to create better interop (without any build-tool conversion) for modules that may be loaded in browsers, by AMD-style loaders, or in Node. I personally still publish many of my utility libraries using a form of UMD.\n\nHere's the typical structure of a UMD:\n\n```js\n(function UMD(name,context,definition){\n    // loaded by an AMD-style loader?\n    if (\n        typeof define === \"function\" &&\n        define.amd\n    ) {\n        define(definition);\n    }\n    // in Node?\n    else if (\n        typeof module !== \"undefined\" &&\n        module.exports\n    ) {\n        module.exports = definition(name,context);\n    }\n    // assume standalone browser script\n    else {\n        context[name] = definition(name,context);\n    }\n})(\"StudentList\",this,function DEF(name,context){\n\n    var elems = [];\n\n    return {\n        renderList() {\n            // ..\n        }\n    };\n\n});\n```\n\nThough it may look a bit unusual, UMD is really just an IIFE.\n\nWhat's different is that the main `function` expression part (at the top) of the IIFE contains a series of `if..else if` statements to detect which of the three supported environments the module is being loaded in.\n\nThe final `()` that normally invokes an IIFE is being passed three arguments: `\"StudentsList\"`, `this`, and another `function` expression. If you match those arguments to their parameters, you'll see they are: `name`, `context`, and `definition`, respectively. `\"StudentList\"` (`name`) is the name label for the module, primarily in case it's defined as a global variable. `this` (`context`) is generally the `window` (aka, global object; see Chapter 4) for defining the module by its name.\n\n`definition(..)` is invoked to actually retrieve the definition of the module, and you'll notice that, sure enough, that's just a classic module form!\n\nThere's no question that as of the time of this writing, ESM (ES Modules) are becoming popular and widespread rapidly. But with millions and millions of modules written over the last 20 years, all using some pre-ESM variation of classic modules, they're still very important to be able to read and understand when you come across them.\n\n[^fowlerIOC]: *Inversion of Control*, Martin Fowler, https://martinfowler.com/bliki/InversionOfControl.html, 26 June 2005.\n"
  },
  {
    "path": "scope-closures/apB.md",
    "content": "# You Don't Know JS Yet: Scope & Closures - 2nd Edition\n# Appendix B: Practice\n\nThis appendix aims to give you some challenging and interesting exercises to test and solidify your understanding of the main topics from this book. It's a good idea to try out the exercises yourself—in an actual code editor!—instead of skipping straight to the solutions at the end. No cheating!\n\nThese exercises don't have a specific right answer that you have to get exactly. Your approach may differ some (or a lot!) from the solutions presented, and that's OK.\n\nThere's no judging you on how you write your code. My hope is that you come away from this book feeling confident that you can tackle these sorts of coding tasks built on a strong foundation of knowledge. That's the only objective, here. If you're happy with your code, I am, too!\n\n## Buckets of Marbles\n\nRemember Figure 2 from back in Chapter 2?\n\n<figure>\n    <img src=\"images/fig2.png\" width=\"300\" alt=\"Colored Scope Bubbles\" align=\"center\">\n    <figcaption><em>Fig. 2 (Ch. 2): Colored Scope Bubbles</em></figcaption>\n    <br><br>\n</figure>\n\nThis exercise asks you to write a program—any program!—that contains nested functions and block scopes, which satisfies these constraints:\n\n* If you color all the scopes (including the global scope!) different colors, you need at least six colors. Make sure to add a code comment labeling each scope with its color.\n\n    BONUS: identify any implied scopes your code may have.\n\n* Each scope has at least one identifier.\n\n* Contains at least two function scopes and at least two block scopes.\n\n* At least one variable from an outer scope must be shadowed by a nested scope variable (see Chapter 3).\n\n* At least one variable reference must resolve to a variable declaration at least two levels higher in the scope chain.\n\n| TIP: |\n| :--- |\n| You *can* just write junk foo/bar/baz-type code for this exercise, but I suggest you try to come up with some sort of non-trivial real'ish code that at least does something kind of reasonable. |\n\nTry the exercise for yourself, then check out the suggested solution at the end of this appendix.\n\n## Closure (PART 1)\n\nLet's first practice closure with some common computer-math operations: determining if a value is prime (has no divisors other than 1 and itself), and generating a list of prime factors (divisors) for a given number.\n\nFor example:\n\n```js\nisPrime(11);        // true\nisPrime(12);        // false\n\nfactorize(11);      // [ 11 ]\nfactorize(12);      // [ 3, 2, 2 ] --> 3*2*2=12\n```\n\nHere's an implementation of `isPrime(..)`, adapted from the Math.js library: [^MathJSisPrime]\n\n```js\nfunction isPrime(v) {\n    if (v <= 3) {\n        return v > 1;\n    }\n    if (v % 2 == 0 || v % 3 == 0) {\n        return false;\n    }\n    var vSqrt = Math.sqrt(v);\n    for (let i = 5; i <= vSqrt; i += 6) {\n        if (v % i == 0 || v % (i + 2) == 0) {\n            return false;\n        }\n    }\n    return true;\n}\n```\n\nAnd here's a somewhat basic implementation of `factorize(..)` (not to be confused with `factorial(..)` from Chapter 6):\n\n```js\nfunction factorize(v) {\n    if (!isPrime(v)) {\n        let i = Math.floor(Math.sqrt(v));\n        while (v % i != 0) {\n            i--;\n        }\n        return [\n            ...factorize(i),\n            ...factorize(v / i)\n        ];\n    }\n    return [v];\n}\n```\n\n| NOTE: |\n| :--- |\n| I call this basic because it's not optimized for performance. It's binary-recursive (which isn't tail-call optimizable), and it creates a lot of intermediate array copies. It also doesn't order the discovered factors in any way. There are many, many other algorithms for this task, but I wanted to use something short and roughly understandable for our exercise. |\n\nIf you were to call `isPrime(4327)` multiple times in a program, you can see that it would go through all its dozens of comparison/computation steps every time. If you consider `factorize(..)`, it's calling `isPrime(..)` many times as it computes the list of factors. And there's a good chance most of those calls are repeats. That's a lot of wasted work!\n\nThe first part of this exercise is to use closure to implement a cache to remember the results of `isPrime(..)`, so that the primality (`true` or `false`) of a given number is only ever computed once. Hint: we already showed this sort of caching in Chapter 6 with `factorial(..)`.\n\nIf you look at `factorize(..)`, it's implemented with recursion, meaning it calls itself repeatedly. That again means we may likely see a lot of wasted calls to compute prime factors for the same number. So the second part of the exercise is to use the same closure cache technique for `factorize(..)`.\n\nUse separate closures for caching of `isPrime(..)` and `factorize(..)`, rather than putting them inside a single scope.\n\nTry the exercise for yourself, then check out the suggested solution at the end of this appendix.\n\n### A Word About Memory\n\nI want to share a little quick note about this closure cache technique and the impacts it has on your application's performance.\n\nWe can see that in saving the repeated calls, we improve computation speed (in some cases, by a dramatic amount). But this usage of closure is making an explicit trade-off that you should be very aware of.\n\nThe trade-off is memory. We're essentially growing our cache (in memory) unboundedly. If the functions in question were called many millions of times with mostly unique inputs, we'd be chewing up a lot of memory. This can definitely be worth the expense, but only if we think it's likely we see repetition of common inputs so that we're taking advantage of the cache.\n\nIf most every call will have a unique input, and the cache is essentially never *used* to any benefit, this is an inappropriate technique to employ.\n\nIt also might be a good idea to have a more sophisticated caching approach, such as an LRU (least recently used) cache, that limits its size; as it runs up to the limit, an LRU evicts the values that are... well, least recently used!\n\nThe downside here is that LRU is quite non-trivial in its own right. You'll want to use a highly optimized implementation of LRU, and be keenly aware of all the trade-offs at play.\n\n## Closure (PART 2)\n\nIn this exercise, we're going to again practice closure by defining a `toggle(..)` utility that gives us a value toggler.\n\nYou will pass one or more values (as arguments) into `toggle(..)`, and get back a function. That returned function will alternate/rotate between all the passed-in values in order, one at a time, as it's called repeatedly.\n\n```js\nfunction toggle(/* .. */) {\n    // ..\n}\n\nvar hello = toggle(\"hello\");\nvar onOff = toggle(\"on\",\"off\");\nvar speed = toggle(\"slow\",\"medium\",\"fast\");\n\nhello();      // \"hello\"\nhello();      // \"hello\"\n\nonOff();      // \"on\"\nonOff();      // \"off\"\nonOff();      // \"on\"\n\nspeed();      // \"slow\"\nspeed();      // \"medium\"\nspeed();      // \"fast\"\nspeed();      // \"slow\"\n```\n\nThe corner case of passing in no values to `toggle(..)` is not very important; such a toggler instance could just always return `undefined`.\n\nTry the exercise for yourself, then check out the suggested solution at the end of this appendix.\n\n## Closure (PART 3)\n\nIn this third and final exercise on closure, we're going to implement a basic calculator. The `calculator()` function will produce an instance of a calculator that maintains its own state, in the form of a function (`calc(..)`, below):\n\n```js\nfunction calculator() {\n    // ..\n}\n\nvar calc = calculator();\n```\n\nEach time `calc(..)` is called, you'll pass in a single character that represents a keypress of a calculator button. To keep things more straightforward, we'll restrict our calculator to supporting entering only digits (0-9), arithmetic operations (+, -, \\*, /), and \"=\" to compute the operation. Operations are processed strictly in the order entered; there's no \"( )\" grouping or operator precedence.\n\nWe don't support entering decimals, but the divide operation can result in them. We don't support entering negative numbers, but the \"-\" operation can result in them. So, you should be able to produce any negative or decimal number by first entering an operation to compute it. You can then keep computing with that value.\n\nThe return of `calc(..)` calls should mimic what would be shown on a real calculator, like reflecting what was just pressed, or computing the total when pressing \"=\".\n\nFor example:\n\n```js\ncalc(\"4\");     // 4\ncalc(\"+\");     // +\ncalc(\"7\");     // 7\ncalc(\"3\");     // 3\ncalc(\"-\");     // -\ncalc(\"2\");     // 2\ncalc(\"=\");     // 75\ncalc(\"*\");     // *\ncalc(\"4\");     // 4\ncalc(\"=\");     // 300\ncalc(\"5\");     // 5\ncalc(\"-\");     // -\ncalc(\"5\");     // 5\ncalc(\"=\");     // 0\n```\n\nSince this usage is a bit clumsy, here's a `useCalc(..)` helper, that runs the calculator with characters one at a time from a string, and computes the display each time:\n\n```js\nfunction useCalc(calc,keys) {\n    return [...keys].reduce(\n        function showDisplay(display,key){\n            var ret = String( calc(key) );\n            return (\n                display +\n                (\n                  (ret != \"\" && key == \"=\") ?\n                      \"=\" :\n                      \"\"\n                ) +\n                ret\n            );\n        },\n        \"\"\n    );\n}\n\nuseCalc(calc,\"4+3=\");           // 4+3=7\nuseCalc(calc,\"+9=\");            // +9=16\nuseCalc(calc,\"*8=\");            // *5=128\nuseCalc(calc,\"7*2*3=\");         // 7*2*3=42\nuseCalc(calc,\"1/0=\");           // 1/0=ERR\nuseCalc(calc,\"+3=\");            // +3=ERR\nuseCalc(calc,\"51=\");            // 51\n```\n\nThe most sensible usage of this `useCalc(..)` helper is to always have \"=\" be the last character entered.\n\nSome of the formatting of the totals displayed by the calculator require special handling. I'm providing this `formatTotal(..)` function, which your calculator should use whenever it's going to return a current computed total (after an `\"=\"` is entered):\n\n```js\nfunction formatTotal(display) {\n    if (Number.isFinite(display)) {\n        // constrain display to max 11 chars\n        let maxDigits = 11;\n        // reserve space for \"e+\" notation?\n        if (Math.abs(display) > 99999999999) {\n            maxDigits -= 6;\n        }\n        // reserve space for \"-\"?\n        if (display < 0) {\n            maxDigits--;\n        }\n\n        // whole number?\n        if (Number.isInteger(display)) {\n            display = display\n                .toPrecision(maxDigits)\n                .replace(/\\.0+$/,\"\");\n        }\n        // decimal\n        else {\n            // reserve space for \".\"\n            maxDigits--;\n            // reserve space for leading \"0\"?\n            if (\n                Math.abs(display) >= 0 &&\n                Math.abs(display) < 1\n            ) {\n                maxDigits--;\n            }\n            display = display\n                .toPrecision(maxDigits)\n                .replace(/0+$/,\"\");\n        }\n    }\n    else {\n        display = \"ERR\";\n    }\n    return display;\n}\n```\n\nDon't worry too much about how `formatTotal(..)` works. Most of its logic is a bunch of handling to limit the calculator display to 11 characters max, even if negatives, repeating decimals, or even \"e+\" exponential notation is required.\n\nAgain, don't get too mired in the mud around calculator-specific behavior. Focus on the *memory* of closure.\n\nTry the exercise for yourself, then check out the suggested solution at the end of this appendix.\n\n## Modules\n\nThis exercise is to convert the calculator from Closure (PART 3) into a module.\n\nWe're not adding any additional functionality to the calculator, only changing its interface. Instead of calling a single function `calc(..)`, we'll be calling specific methods on the public API for each \"keypress\" of our calculator. The outputs stay the same.\n\nThis module should be expressed as a classic module factory function called `calculator()`, instead of a singleton IIFE, so that multiple calculators can be created if desired.\n\nThe public API should include the following methods:\n\n* `number(..)` (input: the character/number \"pressed\")\n* `plus()`\n* `minus()`\n* `mult()`\n* `div()`\n* `eq()`\n\nUsage would look like:\n\n```js\nvar calc = calculator();\n\ncalc.number(\"4\");     // 4\ncalc.plus();          // +\ncalc.number(\"7\");     // 7\ncalc.number(\"3\");     // 3\ncalc.minus();         // -\ncalc.number(\"2\");     // 2\ncalc.eq();            // 75\n```\n\n`formatTotal(..)` remains the same from that previous exercise. But the `useCalc(..)` helper needs to be adjusted to work with the module API:\n\n```js\nfunction useCalc(calc,keys) {\n    var keyMappings = {\n        \"+\": \"plus\",\n        \"-\": \"minus\",\n        \"*\": \"mult\",\n        \"/\": \"div\",\n        \"=\": \"eq\"\n    };\n\n    return [...keys].reduce(\n        function showDisplay(display,key){\n            var fn = keyMappings[key] || \"number\";\n            var ret = String( calc[fn](key) );\n            return (\n                display +\n                (\n                  (ret != \"\" && key == \"=\") ?\n                      \"=\" :\n                      \"\"\n                ) +\n                ret\n            );\n        },\n        \"\"\n    );\n}\n\nuseCalc(calc,\"4+3=\");           // 4+3=7\nuseCalc(calc,\"+9=\");            // +9=16\nuseCalc(calc,\"*8=\");            // *5=128\nuseCalc(calc,\"7*2*3=\");         // 7*2*3=42\nuseCalc(calc,\"1/0=\");           // 1/0=ERR\nuseCalc(calc,\"+3=\");            // +3=ERR\nuseCalc(calc,\"51=\");            // 51\n```\n\nTry the exercise for yourself, then check out the suggested solution at the end of this appendix.\n\nAs you work on this exercise, also spend some time considering the pros/cons of representing the calculator as a module as opposed to the closure-function approach from the previous exercise.\n\nBONUS: write out a few sentences explaining your thoughts.\n\nBONUS #2: try converting your module to other module formats, including: UMD, CommonJS, and ESM (ES Modules).\n\n## Suggested Solutions\n\nHopefully you've tried out the exercises before you're reading this far. No cheating!\n\nRemember, each suggested solution is just one of a bunch of different ways to approach the problems. They're not \"the right answer,\" but they do illustrate a reasonable way to approach each exercise.\n\nThe most important benefit you can get from reading these suggested solutions is to compare them to your code and analyze why we each made similar or different choices. Don't get into too much bikeshedding; try to stay focused on the main topic rather than the small details.\n\n### Suggested: Buckets of Marbles\n\nThe *Buckets of Marbles Exercise* can be solved like this:\n\n```js\n// RED(1)\nconst howMany = 100;\n\n// Sieve of Eratosthenes\nfunction findPrimes(howMany) {\n    // BLUE(2)\n    var sieve = Array(howMany).fill(true);\n    var max = Math.sqrt(howMany);\n\n    for (let i = 2; i < max; i++) {\n        // GREEN(3)\n        if (sieve[i]) {\n            // ORANGE(4)\n            let j = Math.pow(i,2);\n            for (let k = j; k < howMany; k += i) {\n                // PURPLE(5)\n                sieve[k] = false;\n            }\n        }\n    }\n\n    return sieve\n        .map(function getPrime(flag,prime){\n            // PINK(6)\n            if (flag) return prime;\n            return flag;\n        })\n        .filter(function onlyPrimes(v){\n            // YELLOW(7)\n            return !!v;\n        })\n        .slice(1);\n}\n\nfindPrimes(howMany);\n// [\n//    2, 3, 5, 7, 11, 13, 17,\n//    19, 23, 29, 31, 37, 41,\n//    43, 47, 53, 59, 61, 67,\n//    71, 73, 79, 83, 89, 97\n// ]\n```\n\n### Suggested: Closure (PART 1)\n\nThe *Closure Exercise (PART 1)* for `isPrime(..)` and `factorize(..)`, can be solved like this:\n\n```js\nvar isPrime = (function isPrime(v){\n    var primes = {};\n\n    return function isPrime(v) {\n        if (v in primes) {\n            return primes[v];\n        }\n        if (v <= 3) {\n            return (primes[v] = v > 1);\n        }\n        if (v % 2 == 0 || v % 3 == 0) {\n            return (primes[v] = false);\n        }\n        let vSqrt = Math.sqrt(v);\n        for (let i = 5; i <= vSqrt; i += 6) {\n            if (v % i == 0 || v % (i + 2) == 0) {\n                return (primes[v] = false);\n            }\n        }\n        return (primes[v] = true);\n    };\n})();\n\nvar factorize = (function factorize(v){\n    var factors = {};\n\n    return function findFactors(v) {\n        if (v in factors) {\n            return factors[v];\n        }\n        if (!isPrime(v)) {\n            let i = Math.floor(Math.sqrt(v));\n            while (v % i != 0) {\n                i--;\n            }\n            return (factors[v] = [\n                ...findFactors(i),\n                ...findFactors(v / i)\n            ]);\n        }\n        return (factors[v] = [v]);\n    };\n})();\n```\n\nThe general steps I used for each utility:\n\n1. Wrap an IIFE to define the scope for the cache variable to reside.\n\n2. In the underlying call, first check the cache, and if a result is already known, return.\n\n3. At each place where a `return` was happening originally, assign to the cache and just return the results of that assignment operation—this is a space savings trick mostly just for brevity in the book.\n\nI also renamed the inner function from `factorize(..)` to `findFactors(..)`. That's not technically necessary, but it helps it make clearer which function the recursive calls invoke.\n\n### Suggested: Closure (PART 2)\n\nThe *Closure Exercise (PART 2)* `toggle(..)` can be solved like this:\n\n```js\nfunction toggle(...vals) {\n    var unset = {};\n    var cur = unset;\n\n    return function next(){\n        // save previous value back at\n        // the end of the list\n        if (cur != unset) {\n            vals.push(cur);\n        }\n        cur = vals.shift();\n        return cur;\n    };\n}\n\nvar hello = toggle(\"hello\");\nvar onOff = toggle(\"on\",\"off\");\nvar speed = toggle(\"slow\",\"medium\",\"fast\");\n\nhello();      // \"hello\"\nhello();      // \"hello\"\n\nonOff();      // \"on\"\nonOff();      // \"off\"\nonOff();      // \"on\"\n\nspeed();      // \"slow\"\nspeed();      // \"medium\"\nspeed();      // \"fast\"\nspeed();      // \"slow\"\n```\n\n### Suggested: Closure (PART 3)\n\nThe *Closure Exercise (PART 3)* `calculator()` can be solved like this:\n\n```js\n// from earlier:\n//\n// function useCalc(..) { .. }\n// function formatTotal(..) { .. }\n\nfunction calculator() {\n    var currentTotal = 0;\n    var currentVal = \"\";\n    var currentOper = \"=\";\n\n    return pressKey;\n\n    // ********************\n\n    function pressKey(key){\n        // number key?\n        if (/\\d/.test(key)) {\n            currentVal += key;\n            return key;\n        }\n        // operator key?\n        else if (/[+*/-]/.test(key)) {\n            // multiple operations in a series?\n            if (\n                currentOper != \"=\" &&\n                currentVal != \"\"\n            ) {\n                // implied '=' keypress\n                pressKey(\"=\");\n            }\n            else if (currentVal != \"\") {\n                currentTotal = Number(currentVal);\n            }\n            currentOper = key;\n            currentVal = \"\";\n            return key;\n        }\n        // = key?\n        else if (\n            key == \"=\" &&\n            currentOper != \"=\"\n        ) {\n            currentTotal = op(\n                currentTotal,\n                currentOper,\n                Number(currentVal)\n            );\n            currentOper = \"=\";\n            currentVal = \"\";\n            return formatTotal(currentTotal);\n        }\n        return \"\";\n    };\n\n    function op(val1,oper,val2) {\n        var ops = {\n            // NOTE: using arrow functions\n            // only for brevity in the book\n            \"+\": (v1,v2) => v1 + v2,\n            \"-\": (v1,v2) => v1 - v2,\n            \"*\": (v1,v2) => v1 * v2,\n            \"/\": (v1,v2) => v1 / v2\n        };\n        return ops[oper](val1,val2);\n    }\n}\n\nvar calc = calculator();\n\nuseCalc(calc,\"4+3=\");           // 4+3=7\nuseCalc(calc,\"+9=\");            // +9=16\nuseCalc(calc,\"*8=\");            // *5=128\nuseCalc(calc,\"7*2*3=\");         // 7*2*3=42\nuseCalc(calc,\"1/0=\");           // 1/0=ERR\nuseCalc(calc,\"+3=\");            // +3=ERR\nuseCalc(calc,\"51=\");            // 51\n```\n\n| NOTE: |\n| :--- |\n| Remember: this exercise is about closure. Don't focus too much on the actual mechanics of a calculator, but rather on whether you are properly *remembering* the calculator state across function calls. |\n\n### Suggested: Modules\n\nThe *Modules Exercise* `calculator()` can be solved like this:\n\n```js\n// from earlier:\n//\n// function useCalc(..) { .. }\n// function formatTotal(..) { .. }\n\nfunction calculator() {\n    var currentTotal = 0;\n    var currentVal = \"\";\n    var currentOper = \"=\";\n\n    var publicAPI = {\n        number,\n        eq,\n        plus() { return operator(\"+\"); },\n        minus() { return operator(\"-\"); },\n        mult() { return operator(\"*\"); },\n        div() { return operator(\"/\"); }\n    };\n\n    return publicAPI;\n\n    // ********************\n\n    function number(key) {\n        // number key?\n        if (/\\d/.test(key)) {\n            currentVal += key;\n            return key;\n        }\n    }\n\n    function eq() {\n        // = key?\n        if (currentOper != \"=\") {\n            currentTotal = op(\n                currentTotal,\n                currentOper,\n                Number(currentVal)\n            );\n            currentOper = \"=\";\n            currentVal = \"\";\n            return formatTotal(currentTotal);\n        }\n        return \"\";\n    }\n\n    function operator(key) {\n        // multiple operations in a series?\n        if (\n            currentOper != \"=\" &&\n            currentVal != \"\"\n        ) {\n            // implied '=' keypress\n            eq();\n        }\n        else if (currentVal != \"\") {\n            currentTotal = Number(currentVal);\n        }\n        currentOper = key;\n        currentVal = \"\";\n        return key;\n    }\n\n    function op(val1,oper,val2) {\n        var ops = {\n            // NOTE: using arrow functions\n            // only for brevity in the book\n            \"+\": (v1,v2) => v1 + v2,\n            \"-\": (v1,v2) => v1 - v2,\n            \"*\": (v1,v2) => v1 * v2,\n            \"/\": (v1,v2) => v1 / v2\n        };\n        return ops[oper](val1,val2);\n    }\n}\n\nvar calc = calculator();\n\nuseCalc(calc,\"4+3=\");           // 4+3=7\nuseCalc(calc,\"+9=\");            // +9=16\nuseCalc(calc,\"*8=\");            // *5=128\nuseCalc(calc,\"7*2*3=\");         // 7*2*3=42\nuseCalc(calc,\"1/0=\");           // 1/0=ERR\nuseCalc(calc,\"+3=\");            // +3=ERR\nuseCalc(calc,\"51=\");            // 51\n```\n\nThat's it for this book, congratulations on your achievement! When you're ready, move on to Book 3, *Objects & Classes*.\n\n[^MathJSisPrime]: *Math.js: isPrime(..)*, https://github.com/josdejong/mathjs/blob/develop/src/function/utils/isPrime.js, 3 March 2020.\n"
  },
  {
    "path": "scope-closures/ch1.md",
    "content": "# You Don't Know JS Yet: Scope & Closures - 2nd Edition\n# Chapter 1: What's the Scope?\n\nBy the time you've written your first few programs, you're likely getting somewhat comfortable with creating variables and storing values in them. Working with variables is one of the most foundational things we do in programming!\n\nBut you may not have considered very closely the underlying mechanisms used by the engine to organize and manage these variables. I don't mean how the memory is allocated on the computer, but rather: how does JS know which variables are accessible by any given statement, and how does it handle two variables of the same name?\n\nThe answers to questions like these take the form of well-defined rules called scope. This book will dig through all aspects of scope—how it works, what it's useful for, gotchas to avoid—and then point toward common scope patterns that guide the structure of programs.\n\nOur first step is to uncover how the JS engine processes our program **before** it runs.\n\n## About This Book\n\nWelcome to book 2 in the *You Don't Know JS Yet* series! If you already finished *Get Started* (the first book), you're in the right spot! If not, before you proceed I encourage you to *start there* for the best foundation.\n\nOur focus will be the first of three pillars in the JS language: the scope system and its function closures, as well as the power of the module design pattern.\n\nJS is typically classified as an interpreted scripting language, so it's assumed by most that JS programs are processed in a single, top-down pass. But JS is in fact parsed/compiled in a separate phase **before execution begins**. The code author's decisions on where to place variables, functions, and blocks with respect to each other are analyzed according to the rules of scope, during the initial parsing/compilation phase. The resulting scope structure is generally unaffected by runtime conditions.\n\nJS functions are themselves first-class values; they can be assigned and passed around just like numbers or strings. But since these functions hold and access variables, they maintain their original scope no matter where in the program the functions are eventually executed. This is called closure.\n\nModules are a code organization pattern characterized by public methods that have privileged access (via closure) to hidden variables and functions in the internal scope of the module.\n\n## Compiled vs. Interpreted\n\nYou may have heard of *code compilation* before, but perhaps it seems like a mysterious black box where source code slides in one end and executable programs pop out the other.\n\nIt's not mysterious or magical, though. Code compilation is a set of steps that process the text of your code and turn it into a list of instructions the computer can understand. Typically, the whole source code is transformed at once, and those resulting instructions are saved as output (usually in a file) that can later be executed.\n\nYou also may have heard that code can be *interpreted*, so how is that different from being *compiled*?\n\nInterpretation performs a similar task to compilation, in that it transforms your program into machine-understandable instructions. But the processing model is different. Unlike a program being compiled all at once, with interpretation the source code is transformed line by line; each line or statement is executed before immediately proceeding to processing the next line of the source code.\n\n<figure>\n    <img src=\"images/fig1.png\" width=\"650\" alt=\"Code Compilation and Code Interpretation\" align=\"center\">\n    <figcaption><em>Fig. 1: Compiled vs. Interpreted Code</em></figcaption>\n    <br><br>\n</figure>\n\nFigure 1 illustrates compilation vs. interpretation of programs.\n\nAre these two processing models mutually exclusive? Generally, yes. However, the issue is more nuanced, because interpretation can actually take other forms than just operating line by line on source code text. Modern JS engines actually employ numerous variations of both compilation and interpretation in the handling of JS programs.\n\nRecall that we surveyed this topic in Chapter 1 of the *Get Started* book. Our conclusion there is that JS is most accurately portrayed as a **compiled language**. For the benefit of readers here, the following sections will revisit and expand on that assertion.\n\n## Compiling Code\n\nBut first, why does it even matter whether JS is compiled or not?\n\nScope is primarily determined during compilation, so understanding how compilation and execution relate is key in mastering scope.\n\nIn classic compiler theory, a program is processed by a compiler in three basic stages:\n\n1. **Tokenizing/Lexing:** breaking up a string of characters into meaningful (to the language) chunks, called tokens. For instance, consider the program: `var a = 2;`. This program would likely be broken up into the following tokens: `var`, `a`, `=`, `2`, and `;`. Whitespace may or may not be persisted as a token, depending on whether it's meaningful or not.\n\n    (The difference between tokenizing and lexing is subtle and academic, but it centers on whether or not these tokens are identified in a *stateless* or *stateful* way. Put simply, if the tokenizer were to invoke stateful parsing rules to figure out whether `a` should be considered a distinct token or just part of another token, *that* would be **lexing**.)\n\n2. **Parsing:** taking a stream (array) of tokens and turning it into a tree of nested elements, which collectively represent the grammatical structure of the program. This is called an Abstract Syntax Tree (AST).\n\n    For example, the tree for `var a = 2;` might start with a top-level node called `VariableDeclaration`, with a child node called `Identifier` (whose value is `a`), and another child called `AssignmentExpression` which itself has a child called `NumericLiteral` (whose value is `2`).\n\n3. **Code Generation:** taking an AST and turning it into executable code. This part varies greatly depending on the language, the platform it's targeting, and other factors.\n\n    The JS engine takes the just described AST for `var a = 2;` and turns it into a set of machine instructions to actually *create* a variable called `a` (including reserving memory, etc.), and then store a value into `a`.\n\n| NOTE: |\n| :--- |\n| The implementation details of a JS engine (utilizing system memory resources, etc.) is much deeper than we will dig here. We'll keep our focus on the observable behavior of our programs and let the JS engine manage those deeper system-level abstractions. |\n\nThe JS engine is vastly more complex than *just* these three stages. In the process of parsing and code generation, there are steps to optimize the performance of the execution (i.e., collapsing redundant elements). In fact, code can even be re-compiled and re-optimized during the progression of execution.\n\nSo, I'm painting only with broad strokes here. But you'll see shortly why *these* details we *do* cover, even at a high level, are relevant.\n\nJS engines don't have the luxury of an abundance of time to perform their work and optimizations, because JS compilation doesn't happen in a build step ahead of time, as with other languages. It usually must happen in mere microseconds (or less!) right before the code is executed. To ensure the fastest performance under these constraints, JS engines use all kinds of tricks (like JITs, which lazy compile and even hot re-compile); these are well beyond the \"scope\" of our discussion here.\n\n### Required: Two Phases\n\nTo state it as simply as possible, the most important observation we can make about processing of JS programs is that it occurs in (at least) two phases: parsing/compilation first, then execution.\n\nThe separation of a parsing/compilation phase from the subsequent execution phase is observable fact, not theory or opinion. While the JS specification does not require \"compilation\" explicitly, it requires behavior that is essentially only practical with a compile-then-execute approach.\n\nThere are three program characteristics you can observe to prove this to yourself: syntax errors, early errors, and hoisting.\n\n#### Syntax Errors from the Start\n\nConsider this program:\n\n```js\nvar greeting = \"Hello\";\n\nconsole.log(greeting);\n\ngreeting = .\"Hi\";\n// SyntaxError: unexpected token .\n```\n\nThis program produces no output (`\"Hello\"` is not printed), but instead throws a `SyntaxError` about the unexpected `.` token right before the `\"Hi\"` string. Since the syntax error happens after the well-formed `console.log(..)` statement, if JS was executing top-down line by line, one would expect the `\"Hello\"` message being printed before the syntax error being thrown. That doesn't happen.\n\nIn fact, the only way the JS engine could know about the syntax error on the third line, before executing the first and second lines, is by the JS engine first parsing the entire program before any of it is executed.\n\n#### Early Errors\n\nNext, consider:\n\n```js\nconsole.log(\"Howdy\");\n\nsaySomething(\"Hello\",\"Hi\");\n// Uncaught SyntaxError: Duplicate parameter name not\n// allowed in this context\n\nfunction saySomething(greeting,greeting) {\n    \"use strict\";\n    console.log(greeting);\n}\n```\n\nThe `\"Howdy\"` message is not printed, despite being a well-formed statement.\n\nInstead, just like the snippet in the previous section, the `SyntaxError` here is thrown before the program is executed. In this case, it's because strict-mode (opted in for only the `saySomething(..)` function here) forbids, among many other things, functions to have duplicate parameter names; this has always been allowed in non-strict-mode.\n\nThe error thrown is not a syntax error in the sense of being a malformed string of tokens (like `.\"Hi\"` prior), but in strict-mode is nonetheless required by the specification to be thrown as an \"early error\" before any execution begins.\n\nBut how does the JS engine know that the `greeting` parameter has been duplicated? How does it know that the `saySomething(..)` function is even in strict-mode while processing the parameter list (the `\"use strict\"` pragma appears only later, in the function body)?\n\nAgain, the only reasonable explanation is that the code must first be *fully* parsed before any execution occurs.\n\n#### Hoisting\n\nFinally, consider:\n\n```js\nfunction saySomething() {\n    var greeting = \"Hello\";\n    {\n        greeting = \"Howdy\";  // error comes from here\n        let greeting = \"Hi\";\n        console.log(greeting);\n    }\n}\n\nsaySomething();\n// ReferenceError: Cannot access 'greeting' before\n// initialization\n```\n\nThe noted `ReferenceError` occurs from the line with the statement `greeting = \"Howdy\"`. What's happening is that the `greeting` variable for that statement belongs to the declaration on the next line, `let greeting = \"Hi\"`, rather than to the previous `var greeting = \"Hello\"` statement.\n\nThe only way the JS engine could know, at the line where the error is thrown, that the *next statement* would declare a block-scoped variable of the same name (`greeting`) is if the JS engine had already processed this code in an earlier pass, and already set up all the scopes and their variable associations. This processing of scopes and declarations can only accurately be accomplished by parsing the program before execution.\n\nThe `ReferenceError` here technically comes from `greeting = \"Howdy\"` accessing the `greeting` variable **too early**, a conflict referred to as the Temporal Dead Zone (TDZ). Chapter 5 will cover this in more detail.\n\n| WARNING: |\n| :--- |\n| It's often asserted that `let` and `const` declarations are not hoisted, as an explanation of the TDZ behavior just illustrated. But this is not accurate. We'll come back and explain both the hoisting and TDZ of `let`/`const` in Chapter 5. |\n\nHopefully you're now convinced that JS programs are parsed before any execution begins. But does it prove they are compiled?\n\nThis is an interesting question to ponder. Could JS parse a program, but then execute that program by *interpreting* operations represented in the AST **without** first compiling the program? Yes, that is *possible*. But it's extremely unlikely, mostly because it would be extremely inefficient performance wise.\n\nIt's hard to imagine a production-quality JS engine going to all the trouble of parsing a program into an AST, but not then converting (aka, \"compiling\") that AST into the most efficient (binary) representation for the engine to then execute.\n\nMany have endeavored to split hairs with this terminology, as there's plenty of nuance and \"well, actually...\" interjections floating around. But in spirit and in practice, what the engine is doing in processing JS programs is **much more alike compilation** than not.\n\nClassifying JS as a compiled language is not concerned with the distribution model for its binary (or byte-code) executable representations, but rather in keeping a clear distinction in our minds about the phase where JS code is processed and analyzed; this phase observably and indisputedly happens *before* the code starts to be executed.\n\nWe need proper mental models of how the JS engine treats our code if we want to understand JS and scope effectively.\n\n## Compiler Speak\n\nWith awareness of the two-phase processing of a JS program (compile, then execute), let's turn our attention to how the JS engine identifies variables and determines the scopes of a program as it is compiled.\n\nFirst, let's examine a simple JS program to use for analysis over the next several chapters:\n\n```js\nvar students = [\n    { id: 14, name: \"Kyle\" },\n    { id: 73, name: \"Suzy\" },\n    { id: 112, name: \"Frank\" },\n    { id: 6, name: \"Sarah\" }\n];\n\nfunction getStudentName(studentID) {\n    for (let student of students) {\n        if (student.id == studentID) {\n            return student.name;\n        }\n    }\n}\n\nvar nextStudent = getStudentName(73);\n\nconsole.log(nextStudent);\n// Suzy\n```\n\nOther than declarations, all occurrences of variables/identifiers in a program serve in one of two \"roles\": either they're the *target* of an assignment or they're the *source* of a value.\n\n(When I first learned compiler theory while earning my computer science degree, we were taught the terms \"LHS\" (aka, *target*) and \"RHS\" (aka, *source*) for these roles, respectively. As you might guess from the \"L\" and the \"R\", the acronyms mean \"Left-Hand Side\" and \"Right-Hand Side\", as in left and right sides of an `=` assignment operator. However, assignment targets and sources don't always literally appear on the left or right of an `=`, so it's probably clearer to think in terms of *target* / *source* rather than *left* / *right*.)\n\nHow do you know if a variable is a *target*? Check if there is a value that is being assigned to it; if so, it's a *target*. If not, then the variable is a *source*.\n\nFor the JS engine to properly handle a program's variables, it must first label each occurrence of a variable as *target* or *source*. We'll dig in now to how each role is determined.\n\n### Targets\n\nWhat makes a variable a *target*? Consider:\n\n```js\nstudents = [ // ..\n```\n\nThis statement is clearly an assignment operation; remember, the `var students` part is handled entirely as a declaration at compile time, and is thus irrelevant during execution; we left it out for clarity and focus. Same with the `nextStudent = getStudentName(73)` statement.\n\nBut there are three other *target* assignment operations in the code that are perhaps less obvious. One of them:\n\n```js\nfor (let student of students) {\n```\n\nThat statement assigns a value to `student` for each iteration of the loop. Another *target* reference:\n\n```js\ngetStudentName(73)\n```\n\nBut how is that an assignment to a *target*? Look closely: the argument `73` is assigned to the parameter `studentID`.\n\nAnd there's one last (subtle) *target* reference in our program. Can you spot it?\n\n..\n\n..\n\n..\n\nDid you identify this one?\n\n```js\nfunction getStudentName(studentID) {\n```\n\nA `function` declaration is a special case of a *target* reference. You can think of it sort of like `var getStudentName = function(studentID)`, but that's not exactly accurate. An identifier `getStudentName` is declared (at compile time), but the `= function(studentID)` part is also handled at compilation; the association between `getStudentName` and the function is automatically set up at the beginning of the scope rather than waiting for an `=` assignment statement to be executed.\n\n| NOTE: |\n| :--- |\n| This automatic association of function and variable is referred to as \"function hoisting\", and is covered in detail in Chapter 5. |\n\n### Sources\n\nSo we've identified all five *target* references in the program. The other variable references must then be *source* references (because that's the only other option!).\n\nIn `for (let student of students)`, we said that `student` is a *target*, but `students` is a *source* reference. In the statement `if (student.id == studentID)`, both `student` and `studentID` are *source* references. `student` is also a *source* reference in `return student.name`.\n\nIn `getStudentName(73)`, `getStudentName` is a *source* reference (which we hope resolves to a function reference value). In `console.log(nextStudent)`, `console` is a *source* reference, as is `nextStudent`.\n\n| NOTE: |\n| :--- |\n| In case you were wondering, `id`, `name`, and `log` are all properties, not variable references. |\n\nWhat's the practical importance of understanding *targets* vs. *sources*? In Chapter 2, we'll revisit this topic and cover how a variable's role impacts its lookup (specifically, if the lookup fails).\n\n## Cheating: Runtime Scope Modifications\n\nIt should be clear by now that scope is determined as the program is compiled, and should not generally be affected by runtime conditions. However, in non-strict-mode, there are technically still two ways to cheat this rule, modifying a program's scopes during runtime.\n\nNeither of these techniques *should* be used—they're both dangerous and confusing, and you should be using strict-mode (where they're disallowed) anyway. But it's important to be aware of them in case you run across them in some programs.\n\nThe `eval(..)` function receives a string of code to compile and execute on the fly during the program runtime. If that string of code has a `var` or `function` declaration in it, those declarations will modify the current scope that the `eval(..)` is currently executing in:\n\n```js\nfunction badIdea() {\n    eval(\"var oops = 'Ugh!';\");\n    console.log(oops);\n}\nbadIdea();   // Ugh!\n```\n\nIf the `eval(..)` had not been present, the `oops` variable in `console.log(oops)` would not exist, and would throw a `ReferenceError`. But `eval(..)` modifies the scope of the `badIdea()` function at runtime. This is bad for many reasons, including the performance hit of modifying the already compiled and optimized scope, every time `badIdea()` runs.\n\nThe second cheat is the `with` keyword, which essentially dynamically turns an object into a local scope—its properties are treated as identifiers in that new scope's block:\n\n```js\nvar badIdea = { oops: \"Ugh!\" };\n\nwith (badIdea) {\n    console.log(oops);   // Ugh!\n}\n```\n\nThe global scope was not modified here, but `badIdea` was turned into a scope at runtime rather than compile time, and its property `oops` becomes a variable in that scope. Again, this is a terrible idea, for performance and readability reasons.\n\nAt all costs, avoid `eval(..)` (at least, `eval(..)` creating declarations) and `with`. Again, neither of these cheats is available in strict-mode, so if you just use strict-mode (you should!) then the temptation goes away!\n\n## Lexical Scope\n\nWe've demonstrated that JS's scope is determined at compile time; the term for this kind of scope is \"lexical scope\". \"Lexical\" is associated with the \"lexing\" stage of compilation, as discussed earlier in this chapter.\n\nTo narrow this chapter down to a useful conclusion, the key idea of \"lexical scope\" is that it's controlled entirely by the placement of functions, blocks, and variable declarations, in relation to one another.\n\nIf you place a variable declaration inside a function, the compiler handles this declaration as it's parsing the function, and associates that declaration with the function's scope. If a variable is block-scope declared (`let` / `const`), then it's associated with the nearest enclosing `{ .. }` block, rather than its enclosing function (as with `var`).\n\nFurthermore, a reference (*target* or *source* role) for a variable must be resolved as coming from one of the scopes that are *lexically available* to it; otherwise the variable is said to be \"undeclared\" (which usually results in an error!). If the variable is not declared in the current scope, the next outer/enclosing scope will be consulted. This process of stepping out one level of scope nesting continues until either a matching variable declaration can be found, or the global scope is reached and there's nowhere else to go.\n\nIt's important to note that compilation doesn't actually *do anything* in terms of reserving memory for scopes and variables. None of the program has been executed yet.\n\nInstead, compilation creates a map of all the lexical scopes that lays out what the program will need while it executes. You can think of this plan as inserted code for use at runtime, which defines all the scopes (aka, \"lexical environments\") and registers all the identifiers (variables) for each scope.\n\nIn other words, while scopes are identified during compilation, they're not actually created until runtime, each time a scope needs to run. In the next chapter, we'll sketch out the conceptual foundations for lexical scope.\n"
  },
  {
    "path": "scope-closures/ch2.md",
    "content": "# You Don't Know JS Yet: Scope & Closures - 2nd Edition\n# Chapter 2: Illustrating Lexical Scope\n\nIn Chapter 1, we explored how scope is determined during code compilation, a model called \"lexical scope.\" The term \"lexical\" refers to the first stage of compilation (lexing/parsing).\n\nTo properly *reason* about our programs, it's important to have a solid conceptual foundation of how scope works. If we rely on guesses and intuition, we may accidentally get the right answers some of the time, but many other times we're far off. This isn't a recipe for success.\n\nLike way back in grade school math class, getting the right answer isn't enough if we don't show the correct steps to get there! We need to build accurate and helpful mental models as foundation moving forward.\n\nThis chapter will illustrate *scope* with several metaphors. The goal here is to *think* about how your program is handled by the JS engine in ways that more closely align with how the JS engine actually works.\n\n## Marbles, and Buckets, and Bubbles... Oh My!\n\nOne metaphor I've found effective in understanding scope is sorting colored marbles into buckets of their matching color.\n\nImagine you come across a pile of marbles, and notice that all the marbles are colored red, blue, or green. Let's sort all the marbles, dropping the red ones into a red bucket, green into a green bucket, and blue into a blue bucket. After sorting, when you later need a green marble, you already know the green bucket is where to go to get it.\n\nIn this metaphor, the marbles are the variables in our program. The buckets are scopes (functions and blocks), which we just conceptually assign individual colors for our discussion purposes. The color of each marble is thus determined by which *color* scope we find the marble originally created in.\n\nLet's annotate the running program example from Chapter 1 with scope color labels:\n\n```js\n// outer/global scope: RED\n\nvar students = [\n    { id: 14, name: \"Kyle\" },\n    { id: 73, name: \"Suzy\" },\n    { id: 112, name: \"Frank\" },\n    { id: 6, name: \"Sarah\" }\n];\n\nfunction getStudentName(studentID) {\n    // function scope: BLUE\n\n    for (let student of students) {\n        // loop scope: GREEN\n\n        if (student.id == studentID) {\n            return student.name;\n        }\n    }\n}\n\nvar nextStudent = getStudentName(73);\nconsole.log(nextStudent);   // Suzy\n```\n\nWe've designated three scope colors with code comments: RED (outermost global scope), BLUE (scope of function `getStudentName(..)`), and GREEN (scope of/inside the `for` loop). But it still may be difficult to recognize the boundaries of these scope buckets when looking at a code listing.\n\nFigure 2 helps visualize the boundaries of the scopes by drawing colored bubbles (aka, buckets) around each:\n\n<figure>\n    <img src=\"images/fig2.png\" width=\"500\" alt=\"Colored Scope Bubbles\" align=\"center\">\n    <figcaption><em>Fig. 2: Colored Scope Bubbles</em></figcaption>\n</figure>\n\n1. **Bubble 1** (RED) encompasses the global scope, which holds three identifiers/variables: `students` (line 1), `getStudentName` (line 8), and `nextStudent` (line 16).\n\n2. **Bubble 2** (BLUE) encompasses the scope of the function `getStudentName(..)` (line 8), which holds just one identifier/variable: the parameter `studentID` (line 8).\n\n3. **Bubble 3** (GREEN) encompasses the scope of the `for`-loop (line 9), which holds just one identifier/variable: `student` (line 9).\n\n| NOTE: |\n| :--- |\n| Technically, the parameter `studentID` is not exactly in the BLUE(2) scope. We'll unwind that confusion in \"Implied Scopes\" in Appendix A. For now, it's close enough to label `studentID` a BLUE(2) marble. |\n\nScope bubbles are determined during compilation based on where the functions/blocks of scope are written, the nesting inside each other, and so on. Each scope bubble is entirely contained within its parent scope bubble—a scope is never partially in two different outer scopes.\n\nEach marble (variable/identifier) is colored based on which bubble (bucket) it's declared in, not the color of the scope it may be accessed from (e.g., `students` on line 9 and `studentID` on line 10).\n\n| NOTE: |\n| :--- |\n| Remember we asserted in Chapter 1 that `id`, `name`, and `log` are all properties, not variables; in other words, they're not marbles in buckets, so they don't get colored based on any the rules we're discussing in this book. To understand how such property accesses are handled, see the third book in the series, *Objects & Classes*. |\n\nAs the JS engine processes a program (during compilation), and finds a declaration for a variable, it essentially asks, \"Which *color* scope (bubble or bucket) am I currently in?\" The variable is designated as that same *color*, meaning it belongs to that bucket/bubble.\n\nThe GREEN(3) bucket is wholly nested inside of the BLUE(2) bucket, and similarly the BLUE(2) bucket is wholly nested inside the RED(1) bucket. Scopes can nest inside each other as shown, to any depth of nesting as your program needs.\n\nReferences (non-declarations) to variables/identifiers are allowed if there's a matching declaration either in the current scope, or any scope above/outside the current scope, but not with declarations from lower/nested scopes.\n\nAn expression in the RED(1) bucket only has access to RED(1) marbles, **not** BLUE(2) or GREEN(3). An expression in the BLUE(2) bucket can reference either BLUE(2) or RED(1) marbles, **not** GREEN(3). And an expression in the GREEN(3) bucket has access to RED(1), BLUE(2), and GREEN(3) marbles.\n\nWe can conceptualize the process of determining these non-declaration marble colors during runtime as a lookup. Since the `students` variable reference in the `for`-loop statement on line 9 is not a declaration, it has no color. So we ask the current BLUE(2) scope bucket if it has a marble matching that name. Since it doesn't, the lookup continues with the next outer/containing scope: RED(1). The RED(1) bucket has a marble of the name `students`, so the loop-statement's `students` variable reference is determined to be a RED(1) marble.\n\nThe `if (student.id == studentID)` statement on line 10 is similarly determined to reference a GREEN(3) marble named `student` and a BLUE(2) marble `studentID`.\n\n| NOTE: |\n| :--- |\n| The JS engine doesn't generally determine these marble colors during runtime; the \"lookup\" here is a rhetorical device to help you understand the concepts. During compilation, most or all variable references will match already-known scope buckets, so their color is already determined, and stored with each marble reference to avoid unnecessary lookups as the program runs. More on this nuance in Chapter 3. |\n\nThe key take-aways from marbles & buckets (and bubbles!):\n\n* Variables are declared in specific scopes, which can be thought of as colored marbles from matching-color buckets.\n\n* Any variable reference that appears in the scope where it was declared, or appears in any deeper nested scopes, will be labeled a marble of that same color—unless an intervening scope \"shadows\" the variable declaration; see \"Shadowing\" in Chapter 3.\n\n* The determination of colored buckets, and the marbles they contain, happens during compilation. This information is used for variable (marble color) \"lookups\" during code execution.\n\n## A Conversation Among Friends\n\nAnother useful metaphor for the process of analyzing variables and the scopes they come from is to imagine various conversations that occur inside the engine as code is processed and then executed. We can \"listen in\" on these conversations to get a better conceptual foundation for how scopes work.\n\nLet's now meet the members of the JS engine that will have conversations as they process our program:\n\n* *Engine*: responsible for start-to-finish compilation and execution of our JavaScript program.\n\n* *Compiler*: one of *Engine*'s friends; handles all the dirty work of parsing and code-generation (see previous section).\n\n* *Scope Manager*: another friend of *Engine*; collects and maintains a lookup list of all the declared variables/identifiers, and enforces a set of rules as to how these are accessible to currently executing code.\n\nFor you to *fully understand* how JavaScript works, you need to begin to *think* like *Engine* (and friends) think, ask the questions they ask, and answer their questions likewise.\n\nTo explore these conversations, recall again our running program example:\n\n```js\nvar students = [\n    { id: 14, name: \"Kyle\" },\n    { id: 73, name: \"Suzy\" },\n    { id: 112, name: \"Frank\" },\n    { id: 6, name: \"Sarah\" }\n];\n\nfunction getStudentName(studentID) {\n    for (let student of students) {\n        if (student.id == studentID) {\n            return student.name;\n        }\n    }\n}\n\nvar nextStudent = getStudentName(73);\n\nconsole.log(nextStudent);\n// Suzy\n```\n\nLet's examine how JS is going to process that program, specifically starting with the first statement. The array and its contents are just basic JS value literals (and thus unaffected by any scoping concerns), so our focus here will be on the `var students = [ .. ]` declaration and initialization-assignment parts.\n\nWe typically think of that as a single statement, but that's not how our friend *Engine* sees it. In fact, JS treats these as two distinct operations, one which *Compiler* will handle during compilation, and the other which *Engine* will handle during execution.\n\nThe first thing *Compiler* will do with this program is perform lexing to break it down into tokens, which it will then parse into a tree (AST).\n\nOnce *Compiler* gets to code generation, there's more detail to consider than may be obvious. A reasonable assumption would be that *Compiler* will produce code for the first statement such as: \"Allocate memory for a variable, label it `students`, then stick a reference to the array into that variable.\" But that's not the whole story.\n\nHere's the steps *Compiler* will follow to handle that statement:\n\n1. Encountering `var students`, *Compiler* will ask *Scope Manager* to see if a variable named `students` already exists for that particular scope bucket. If so, *Compiler* would ignore this declaration and move on. Otherwise, *Compiler* will produce code that (at execution time) asks *Scope Manager* to create a new variable called `students` in that scope bucket.\n\n2. *Compiler* then produces code for *Engine* to later execute, to handle the `students = []` assignment. The code *Engine* runs will first ask *Scope Manager* if there is a variable called `students` accessible in the current scope bucket. If not, *Engine* keeps looking elsewhere (see \"Nested Scope\" below). Once *Engine* finds a variable, it assigns the reference of the `[ .. ]` array to it.\n\nIn conversational form, the first phase of compilation for the program might play out between *Compiler* and *Scope Manager* like this:\n\n> ***Compiler***: Hey, *Scope Manager* (of the global scope), I found a formal declaration for an identifier called `students`, ever heard of it?\n\n> ***(Global) Scope Manager***: Nope, never heard of it, so I just created it for you.\n\n> ***Compiler***: Hey, *Scope Manager*, I found a formal declaration for an identifier called `getStudentName`, ever heard of it?\n\n> ***(Global) Scope Manager***: Nope, but I just created it for you.\n\n> ***Compiler***: Hey, *Scope Manager*, `getStudentName` points to a function, so we need a new scope bucket.\n\n> ***(Function) Scope Manager***: Got it, here's the scope bucket.\n\n> ***Compiler***: Hey, *Scope Manager* (of the function), I found a formal parameter declaration for `studentID`, ever heard of it?\n\n> ***(Function) Scope Manager***: Nope, but now it's created in this scope.\n\n> ***Compiler***: Hey, *Scope Manager* (of the function), I found a `for`-loop that will need its own scope bucket.\n\n> ...\n\nThe conversation is a question-and-answer exchange, where **Compiler** asks the current *Scope Manager* if an encountered identifier declaration has already been encountered. If \"no,\" *Scope Manager* creates that variable in that scope. If the answer is \"yes,\" then it's effectively skipped over since there's nothing more for that *Scope Manager* to do.\n\n*Compiler* also signals when it runs across functions or block scopes, so that a new scope bucket and *Scope Manager* can be instantiated.\n\nLater, when it comes to execution of the program, the conversation will shift to *Engine* and *Scope Manager*, and might play out like this:\n\n> ***Engine***: Hey, *Scope Manager* (of the global scope), before we begin, can you look up the identifier `getStudentName` so I can assign this function to it?\n\n> ***(Global) Scope Manager***: Yep, here's the variable.\n\n> ***Engine***: Hey, *Scope Manager*, I found a *target* reference for `students`, ever heard of it?\n\n> ***(Global) Scope Manager***: Yes, it was formally declared for this scope, so here it is.\n\n> ***Engine***: Thanks, I'm initializing `students` to `undefined`, so it's ready to use.\n\n> Hey, *Scope Manager* (of the global scope), I found a *target* reference for `nextStudent`, ever heard of it?\n\n> ***(Global) Scope Manager***: Yes, it was formally declared for this scope, so here it is.\n\n> ***Engine***: Thanks, I'm initializing `nextStudent` to `undefined`, so it's ready to use.\n\n> Hey, *Scope Manager* (of the global scope), I found a *source* reference for `getStudentName`, ever heard of it?\n\n> ***(Global) Scope Manager***: Yes, it was formally declared for this scope. Here it is.\n\n> ***Engine***: Great, the value in `getStudentName` is a function, so I'm going to execute it.\n\n> ***Engine***: Hey, *Scope Manager*, now we need to instantiate the function's scope.\n\n> ...\n\nThis conversation is another question-and-answer exchange, where *Engine* first asks the current *Scope Manager* to look up the hoisted `getStudentName` identifier, so as to associate the function with it. *Engine* then proceeds to ask *Scope Manager* about the *target* reference for `students`, and so on.\n\nTo review and summarize how a statement like `var students = [ .. ]` is processed, in two distinct steps:\n\n1. *Compiler* sets up the declaration of the scope variable (since it wasn't previously declared in the current scope).\n\n2. While *Engine* is executing, to process the assignment part of the statement, *Engine* asks *Scope Manager* to look up the variable, initializes it to `undefined` so it's ready to use, and then assigns the array value to it.\n\n## Nested Scope\n\nWhen it comes time to execute the `getStudentName()` function, *Engine* asks for a *Scope Manager* instance for that function's scope, and it will then proceed to look up the parameter (`studentID`) to assign the `73` argument value to, and so on.\n\nThe function scope for `getStudentName(..)` is nested inside the global scope. The block scope of the `for`-loop is similarly nested inside that function scope. Scopes can be lexically nested to any arbitrary depth as the program defines.\n\nEach scope gets its own *Scope Manager* instance each time that scope is executed (one or more times). Each scope automatically has all its identifiers registered at the start of the scope being executed (this is called \"variable hoisting\"; see Chapter 5).\n\nAt the beginning of a scope, if any identifier came from a `function` declaration, that variable is automatically initialized to its associated function reference. And if any identifier came from a `var` declaration (as opposed to `let`/`const`), that variable is automatically initialized to `undefined` so that it can be used; otherwise, the variable remains uninitialized (aka, in its \"TDZ,\" see Chapter 5) and cannot be used until its full declaration-and-initialization are executed.\n\nIn the `for (let student of students) {` statement, `students` is a *source* reference that must be looked up. But how will that lookup be handled, since the scope of the function will not find such an identifier?\n\nTo explain, let's imagine that bit of conversation playing out like this:\n\n> ***Engine***: Hey, *Scope Manager* (for the function), I have a *source* reference for `students`, ever heard of it?\n\n> ***(Function) Scope Manager***: Nope, never heard of it. Try the next outer scope.\n\n> ***Engine***: Hey, *Scope Manager* (for the global scope), I have a *source* reference for `students`, ever heard of it?\n\n> ***(Global) Scope Manager***: Yep, it was formally declared, here it is.\n\n> ...\n\nOne of the key aspects of lexical scope is that any time an identifier reference cannot be found in the current scope, the next outer scope in the nesting is consulted; that process is repeated until an answer is found or there are no more scopes to consult.\n\n### Lookup Failures\n\nWhen *Engine* exhausts all *lexically available* scopes (moving outward) and still cannot resolve the lookup of an identifier, an error condition then exists. However, depending on the mode of the program (strict-mode or not) and the role of the variable (i.e., *target* vs. *source*; see Chapter 1), this error condition will be handled differently.\n\n#### Undefined Mess\n\nIf the variable is a *source*, an unresolved identifier lookup is considered an undeclared (unknown, missing) variable, which always results in a `ReferenceError` being thrown. Also, if the variable is a *target*, and the code at that moment is running in strict-mode, the variable is considered undeclared and similarly throws a `ReferenceError`.\n\nThe error message for an undeclared variable condition, in most JS environments, will look like, \"Reference Error: XYZ is not defined.\" The phrase \"not defined\" seems almost identical to the word \"undefined,\" as far as the English language goes. But these two are very different in JS, and this error message unfortunately creates a persistent confusion.\n\n\"Not defined\" really means \"not declared\"—or, rather, \"undeclared,\" as in a variable that has no matching formal declaration in any *lexically available* scope. By contrast, \"undefined\" really means a variable was found (declared), but the variable otherwise has no other value in it at the moment, so it defaults to the `undefined` value.\n\nTo perpetuate the confusion even further, JS's `typeof` operator returns the string `\"undefined\"` for variable references in either state:\n\n```js\nvar studentName;\ntypeof studentName;     // \"undefined\"\n\ntypeof doesntExist;     // \"undefined\"\n```\n\nThese two variable references are in very different conditions, but JS sure does muddy the waters. The terminology mess is confusing and terribly unfortunate. Unfortunately, JS developers just have to pay close attention to not mix up *which kind* of \"undefined\" they're dealing with!\n\n#### Global... What!?\n\nIf the variable is a *target* and strict-mode is not in effect, a confusing and surprising legacy behavior kicks in. The troublesome outcome is that the global scope's *Scope Manager* will just create an **accidental global variable** to fulfill that target assignment!\n\nConsider:\n\n```js\nfunction getStudentName() {\n    // assignment to an undeclared variable :(\n    nextStudent = \"Suzy\";\n}\n\ngetStudentName();\n\nconsole.log(nextStudent);\n// \"Suzy\" -- oops, an accidental-global variable!\n```\n\nHere's how that *conversation* will proceed:\n\n> ***Engine***: Hey, *Scope Manager* (for the function), I have a *target* reference for `nextStudent`, ever heard of it?\n\n> ***(Function) Scope Manager***: Nope, never heard of it. Try the next outer scope.\n\n> ***Engine***: Hey, *Scope Manager* (for the global scope), I have a *target* reference for `nextStudent`, ever heard of it?\n\n> ***(Global) Scope Manager***: Nope, but since we're in non-strict-mode, I helped you out and just created a global variable for you, here it is!\n\nYuck.\n\nThis sort of accident (almost certain to lead to bugs eventually) is a great example of the beneficial protections offered by strict-mode, and why it's such a bad idea *not* to be using strict-mode. In strict-mode, the ***Global Scope Manager*** would instead have responded:\n\n> ***(Global) Scope Manager***: Nope, never heard of it. Sorry, I've got to throw a `ReferenceError`.\n\nAssigning to a never-declared variable *is* an error, so it's right that we would receive a `ReferenceError` here.\n\nNever rely on accidental global variables. Always use strict-mode, and always formally declare your variables. You'll then get a helpful `ReferenceError` if you ever mistakenly try to assign to a not-declared variable.\n\n### Building On Metaphors\n\nTo visualize nested scope resolution, I prefer yet another metaphor, an office building, as in Figure 3:\n\n<figure>\n    <img src=\"images/fig3.png\" width=\"250\" alt=\"Scope &quot;Building&quot;\" align=\"center\">\n    <figcaption><em>Fig. 3: Scope \"Building\"</em></figcaption>\n    <br><br>\n</figure>\n\nThe building represents our program's nested scope collection. The first floor of the building represents the currently executing scope. The top level of the building is the global scope.\n\nYou resolve a *target* or *source* variable reference by first looking on the current floor, and if you don't find it, taking the elevator to the next floor (i.e., an outer scope), looking there, then the next, and so on. Once you get to the top floor (the global scope), you either find what you're looking for, or you don't. But you have to stop regardless.\n\n## Continue the Conversation\n\nBy this point, you should be developing richer mental models for what scope is and how the JS engine determines and uses it from your code.\n\nBefore *continuing*, go find some code in one of your projects and run through these conversations. Seriously, actually speak out loud. Find a friend and practice each role with them. If either of you find yourself confused or tripped up, spend more time reviewing this material.\n\nAs we move (up) to the next (outer) chapter, we'll explore how the lexical scopes of a program are connected in a chain.\n"
  },
  {
    "path": "scope-closures/ch3.md",
    "content": "# You Don't Know JS Yet: Scope & Closures - 2nd Edition\n# Chapter 3: The Scope Chain\n\nChapters 1 and 2 laid down a concrete definition of *lexical scope* (and its parts) and illustrated helpful metaphors for its conceptual foundation. Before proceeding with this chapter, find someone else to explain (written or aloud), in your own words, what lexical scope is and why it's useful to understand.\n\nThat seems like a step you might skip, but I've found it really does help to take the time to reformulate these ideas as explanations to others. That helps our brains digest what we're learning!\n\nNow it's time to dig into the nuts and bolts, so expect that things will get a lot more detailed from here forward. Stick with it, though, because these discussions really hammer home just how much we all *don't know* about scope, yet. Make sure to take your time with the text and all the code snippets provided.\n\nTo refresh the context of our running example, let's recall the color-coded illustration of the nested scope bubbles, from Chapter 2, Figure 2:\n\n<figure>\n    <img src=\"images/fig2.png\" width=\"500\" alt=\"Colored Scope Bubbles\" align=\"center\">\n    <figcaption><em>Fig. 2 (Ch. 2): Colored Scope Bubbles</em></figcaption>\n    <br><br>\n</figure>\n\nThe connections between scopes that are nested within other scopes is called the scope chain, which determines the path along which variables can be accessed. The chain is directed, meaning the lookup moves upward/outward only.\n\n## \"Lookup\" Is (Mostly) Conceptual\n\nIn Figure 2, notice the color of the `students` variable reference in the `for`-loop. How exactly did we determine that it's a RED(1) marble?\n\nIn Chapter 2, we described the runtime access of a variable as a \"lookup,\" where the *Engine* has to start by asking the current scope's *Scope Manager* if it knows about an identifier/variable, and proceeding upward/outward back through the chain of nested scopes (toward the global scope) until found, if ever. The lookup stops as soon as the first matching named declaration in a scope bucket is found.\n\nThe lookup process thus determined that `students` is a RED(1) marble, because we had not yet found a matching variable name as we traversed the scope chain, until we arrived at the final RED(1) global scope.\n\nSimilarly, `studentID` in the `if`-statement is determined to be a BLUE(2) marble.\n\nThis suggestion of a runtime lookup process works well for conceptual understanding, but it's not actually how things usually work in practice.\n\nThe color of a marble's bucket (aka, meta information of what scope a variable originates from) is *usually determined* during the initial compilation processing. Because lexical scope is pretty much finalized at that point, a marble's color will not change based on anything that can happen later during runtime.\n\nSince the marble's color is known from compilation, and it's immutable, this information would likely be stored with (or at least accessible from) each variable's entry in the AST; that information is then used explicitly by the executable instructions that constitute the program's runtime.\n\nIn other words, *Engine* (from Chapter 2) doesn't need to lookup through a bunch of scopes to figure out which scope bucket a variable comes from. That information is already known! Avoiding the need for a runtime lookup is a key optimization benefit of lexical scope. The runtime operates more performantly without spending time on all these lookups.\n\nBut I said \"...usually determined...\" just a moment ago, with respect to figuring out a marble's color during compilation. So in what case would it ever *not* be known during compilation?\n\nConsider a reference to a variable that isn't declared in any lexically available scopes in the current file—see *Get Started*, Chapter 1, which asserts that each file is its own separate program from the perspective of JS compilation. If no declaration is found, that's not *necessarily* an error. Another file (program) in the runtime may indeed declare that variable in the shared global scope.\n\nSo the ultimate determination of whether the variable was ever appropriately declared in some accessible bucket may need to be deferred to the runtime.\n\nAny reference to a variable that's initially *undeclared* is left as an uncolored marble during that file's compilation; this color cannot be determined until other relevant file(s) have been compiled and the application runtime commences. That deferred lookup will eventually resolve the color to whichever scope the variable is found in (likely the global scope).\n\nHowever, this lookup would only be needed once per variable at most, since nothing else during runtime could later change that marble's color.\n\nThe \"Lookup Failures\" section in Chapter 2 covers what happens if a marble is ultimately still uncolored at the moment its reference is runtime executed.\n\n## Shadowing\n\n\"Shadowing\" might sound mysterious and a little bit sketchy. But don't worry, it's completely legit!\n\nOur running example for these chapters uses different variable names across the scope boundaries. Since they all have unique names, in a way it wouldn't matter if all of them were just stored in one bucket (like RED(1)).\n\nWhere having different lexical scope buckets starts to matter more is when you have two or more variables, each in different scopes, with the same lexical names. A single scope cannot have two or more variables with the same name; such multiple references would be assumed as just one variable.\n\nSo if you need to maintain two or more variables of the same name, you must use separate (often nested) scopes. And in that case, it's very relevant how the different scope buckets are laid out.\n\nConsider:\n\n```js\nvar studentName = \"Suzy\";\n\nfunction printStudent(studentName) {\n    studentName = studentName.toUpperCase();\n    console.log(studentName);\n}\n\nprintStudent(\"Frank\");\n// FRANK\n\nprintStudent(studentName);\n// SUZY\n\nconsole.log(studentName);\n// Suzy\n```\n\n| TIP: |\n| :--- |\n| Before you move on, take some time to analyze this code using the various techniques/metaphors we've covered in the book. In particular, make sure to identify the marble/bubble colors in this snippet. It's good practice! |\n\nThe `studentName` variable on line 1 (the `var studentName = ..` statement) creates a RED(1) marble. The same named variable is declared as a BLUE(2) marble on line 3, the parameter in the `printStudent(..)` function definition.\n\nWhat color marble will `studentName` be in the `studentName = studentName.toUpperCase()` assignment statement and the `console.log(studentName)` statement? All three `studentName` references will be BLUE(2).\n\nWith the conceptual notion of the \"lookup,\" we asserted that it starts with the current scope and works its way outward/upward, stopping as soon as a matching variable is found. The BLUE(2) `studentName` is found right away. The RED(1) `studentName` is never even considered.\n\nThis is a key aspect of lexical scope behavior, called *shadowing*. The BLUE(2) `studentName` variable (parameter) shadows the RED(1) `studentName`. So, the parameter is shadowing the (shadowed) global variable. Repeat that sentence to yourself a few times to make sure you have the terminology straight!\n\nThat's why the re-assignment of `studentName` affects only the inner (parameter) variable: the BLUE(2) `studentName`, not the global RED(1) `studentName`.\n\nWhen you choose to shadow a variable from an outer scope, one direct impact is that from that scope inward/downward (through any nested scopes) it's now impossible for any marble to be colored as the shadowed variable—(RED(1), in this case). In other words, any `studentName` identifier reference will correspond to that parameter variable, never the global `studentName` variable. It's lexically impossible to reference the global `studentName` anywhere inside of the `printStudent(..)` function (or from any nested scopes).\n\n### Global Unshadowing Trick\n\nPlease beware: leveraging the technique I'm about to describe is not very good practice, as it's limited in utility, confusing for readers of your code, and likely to invite bugs to your program. I'm covering it only because you may run across this behavior in existing programs, and understanding what's happening is critical to not getting tripped up.\n\nIt *is* possible to access a global variable from a scope where that variable has been shadowed, but not through a typical lexical identifier reference.\n\nIn the global scope (RED(1)), `var` declarations and `function` declarations also expose themselves as properties (of the same name as the identifier) on the *global object*—essentially an object representation of the global scope. If you've written JS for a browser environment, you probably recognize the global object as `window`. That's not *entirely* accurate, but it's good enough for our discussion. In the next chapter, we'll explore the global scope/object topic more.\n\nConsider this program, specifically executed as a standalone .js file in a browser environment:\n\n```js\nvar studentName = \"Suzy\";\n\nfunction printStudent(studentName) {\n    console.log(studentName);\n    console.log(window.studentName);\n}\n\nprintStudent(\"Frank\");\n// \"Frank\"\n// \"Suzy\"\n```\n\nNotice the `window.studentName` reference? This expression is accessing the global variable `studentName` as a property on `window` (which we're pretending for now is synonymous with the global object). That's the only way to access a shadowed variable from inside a scope where the shadowing variable is present.\n\nThe `window.studentName` is a mirror of the global `studentName` variable, not a separate snapshot copy. Changes to one are still seen from the other, in either direction. You can think of `window.studentName` as a getter/setter that accesses the actual `studentName` variable. As a matter of fact, you can even *add* a variable to the global scope by creating/setting a property on the global object.\n\n| WARNING: |\n| :--- |\n| Remember: just because you *can* doesn't mean you *should*. Don't shadow a global variable that you need to access, and conversely, avoid using this trick to access a global variable that you've shadowed. And definitely don't confuse readers of your code by creating global variables as `window` properties instead of with formal declarations! |\n\nThis little \"trick\" only works for accessing a global scope variable (not a shadowed variable from a nested scope), and even then, only one that was declared with `var` or `function`.\n\nOther forms of global scope declarations do not create mirrored global object properties:\n\n```js\nvar one = 1;\nlet notOne = 2;\nconst notTwo = 3;\nclass notThree {}\n\nconsole.log(window.one);       // 1\nconsole.log(window.notOne);    // undefined\nconsole.log(window.notTwo);    // undefined\nconsole.log(window.notThree);  // undefined\n```\n\nVariables (no matter how they're declared!) that exist in any other scope than the global scope are completely inaccessible from a scope where they've been shadowed:\n\n```js\nvar special = 42;\n\nfunction lookingFor(special) {\n    // The identifier `special` (parameter) in this\n    // scope is shadowed inside keepLooking(), and\n    // is thus inaccessible from that scope.\n\n    function keepLooking() {\n        var special = 3.141592;\n        console.log(special);\n        console.log(window.special);\n    }\n\n    keepLooking();\n}\n\nlookingFor(112358132134);\n// 3.141592\n// 42\n```\n\nThe global RED(1) `special` is shadowed by the BLUE(2) `special` (parameter), and the BLUE(2) `special` is itself shadowed by the GREEN(3) `special` inside `keepLooking()`. We can still access the RED(1) `special` using the indirect reference `window.special`. But there's no way for `keepLooking()` to access the BLUE(2) `special` that holds the number `112358132134`.\n\n### Copying Is Not Accessing\n\nI've been asked the following \"But what about...?\" question dozens of times. Consider:\n\n```js\nvar special = 42;\n\nfunction lookingFor(special) {\n    var another = {\n        special: special\n    };\n\n    function keepLooking() {\n        var special = 3.141592;\n        console.log(special);\n        console.log(another.special);  // Ooo, tricky!\n        console.log(window.special);\n    }\n\n    keepLooking();\n}\n\nlookingFor(112358132134);\n// 3.141592\n// 112358132134\n// 42\n```\n\nOh! So does this `another` object technique disprove my claim that the `special` parameter is \"completely inaccessible\" from inside `keepLooking()`? No, the claim is still correct.\n\n`special: special` is copying the value of the `special` parameter variable into another container (a property of the same name). Of course, if you put a value in another container, shadowing no longer applies (unless `another` was shadowed, too!). But that doesn't mean we're accessing the parameter `special`; it means we're accessing the copy of the value it had at that moment, by way of *another* container (object property). We cannot reassign the BLUE(2) `special` parameter to a different value from inside `keepLooking()`.\n\nAnother \"But...!?\" you may be about to raise: what if I'd used objects or arrays as the values instead of the numbers (`112358132134`, etc.)? Would us having references to objects instead of copies of primitive values \"fix\" the inaccessibility?\n\nNo. Mutating the contents of the object value via a reference copy is **not** the same thing as lexically accessing the variable itself. We still can't reassign the BLUE(2) `special` parameter.\n\n### Illegal Shadowing\n\nNot all combinations of declaration shadowing are allowed. `let` can shadow `var`, but `var` cannot shadow `let`:\n\n```js\nfunction something() {\n    var special = \"JavaScript\";\n\n    {\n        let special = 42;   // totally fine shadowing\n\n        // ..\n    }\n}\n\nfunction another() {\n    // ..\n\n    {\n        let special = \"JavaScript\";\n\n        {\n            var special = \"JavaScript\";\n            // ^^^ Syntax Error\n\n            // ..\n        }\n    }\n}\n```\n\nNotice in the `another()` function, the inner `var special` declaration is attempting to declare a function-wide `special`, which in and of itself is fine (as shown by the `something()` function).\n\nThe syntax error description in this case indicates that `special` has already been defined, but that error message is a little misleading—again, no such error happens in `something()`, as shadowing is generally allowed just fine.\n\nThe real reason it's raised as a `SyntaxError` is because the `var` is basically trying to \"cross the boundary\" of (or hop over) the `let` declaration of the same name, which is not allowed.\n\nThat boundary-crossing prohibition effectively stops at each function boundary, so this variant raises no exception:\n\n```js\nfunction another() {\n    // ..\n\n    {\n        let special = \"JavaScript\";\n\n        ajax(\"https://some.url\",function callback(){\n            // totally fine shadowing\n            var special = \"JavaScript\";\n\n            // ..\n        });\n    }\n}\n```\n\nSummary: `let` (in an inner scope) can always shadow an outer scope's `var`. `var` (in an inner scope) can only shadow an outer scope's `let` if there is a function boundary in between.\n\n## Function Name Scope\n\nAs you've seen by now, a `function` declaration looks like this:\n\n```js\nfunction askQuestion() {\n    // ..\n}\n```\n\nAnd as discussed in Chapters 1 and 2, such a `function` declaration will create an identifier in the enclosing scope (in this case, the global scope) named `askQuestion`.\n\nWhat about this program?\n\n```js\nvar askQuestion = function(){\n    // ..\n};\n```\n\nThe same is true for the variable `askQuestion` being created. But since it's a `function` expression—a function definition used as value instead of a standalone declaration—the function itself will not \"hoist\" (see Chapter 5).\n\nOne major difference between `function` declarations and `function` expressions is what happens to the name identifier of the function. Consider a named `function` expression:\n\n```js\nvar askQuestion = function ofTheTeacher(){\n    // ..\n};\n```\n\nWe know `askQuestion` ends up in the outer scope. But what about the `ofTheTeacher` identifier? For formal `function` declarations, the name identifier ends up in the outer/enclosing scope, so it may be reasonable to assume that's the case here. But `ofTheTeacher` is declared as an identifier **inside the function itself**:\n\n```js\nvar askQuestion = function ofTheTeacher() {\n    console.log(ofTheTeacher);\n};\n\naskQuestion();\n// function ofTheTeacher()...\n\nconsole.log(ofTheTeacher);\n// ReferenceError: ofTheTeacher is not defined\n```\n\n| NOTE: |\n| :--- |\n| Actually, `ofTheTeacher` is not exactly *in the scope of the function*. Appendix A, \"Implied Scopes\" will explain further. |\n\nNot only is `ofTheTeacher` declared inside the function rather than outside, but it's also defined as read-only:\n\n```js\nvar askQuestion = function ofTheTeacher() {\n    \"use strict\";\n    ofTheTeacher = 42;   // TypeError\n\n    //..\n};\n\naskQuestion();\n// TypeError\n```\n\nBecause we used strict-mode, the assignment failure is reported as a `TypeError`; in non-strict-mode, such an assignment fails silently with no exception.\n\nWhat about when a `function` expression has no name identifier?\n\n```js\nvar askQuestion = function(){\n   // ..\n};\n```\n\nA `function` expression with a name identifier is referred to as a \"named function expression,\" but one without a name identifier is referred to as an \"anonymous function expression.\" Anonymous function expressions clearly have no name identifier that affects either scope.\n\n| NOTE: |\n| :--- |\n| We'll discuss named vs. anonymous `function` expressions in much more detail, including what factors affect the decision to use one or the other, in Appendix A. |\n\n## Arrow Functions\n\nES6 added an additional `function` expression form to the language, called \"arrow functions\":\n\n```js\nvar askQuestion = () => {\n    // ..\n};\n```\n\nThe `=>` arrow function doesn't require the word `function` to define it. Also, the `( .. )` around the parameter list is optional in some simple cases. Likewise, the `{ .. }` around the function body is optional in some cases. And when the `{ .. }` are omitted, a return value is sent out without using a `return` keyword.\n\n| NOTE: |\n| :--- |\n| The attractiveness of `=>` arrow functions is often sold as \"shorter syntax,\" and that's claimed to equate to objectively more readable code. This claim is dubious at best, and I believe outright misguided. We'll dig into the \"readability\" of various function forms in Appendix A. |\n\nArrow functions are lexically anonymous, meaning they have no directly related identifier that references the function. The assignment to `askQuestion` creates an inferred name of \"askQuestion\", but that's **not the same thing as being non-anonymous**:\n\n```js\nvar askQuestion = () => {\n    // ..\n};\n\naskQuestion.name;   // askQuestion\n```\n\nArrow functions achieve their syntactic brevity at the expense of having to mentally juggle a bunch of variations for different forms/conditions. Just a few, for example:\n\n```js\n() => 42;\n\nid => id.toUpperCase();\n\n(id,name) => ({ id, name });\n\n(...args) => {\n    return args[args.length - 1];\n};\n```\n\nThe real reason I bring up arrow functions is because of the common but incorrect claim that arrow functions somehow behave differently with respect to lexical scope from standard `function` functions.\n\nThis is incorrect.\n\nOther than being anonymous (and having no declarative form), `=>` arrow functions have the same lexical scope rules as `function` functions do. An arrow function, with or without `{ .. }` around its body, still creates a separate, inner nested bucket of scope. Variable declarations inside this nested scope bucket behave the same as in a `function` scope.\n\n## Backing Out\n\nWhen a function (declaration or expression) is defined, a new scope is created. The positioning of scopes nested inside one another creates a natural scope hierarchy throughout the program, called the scope chain. The scope chain controls variable access, directionally oriented upward and outward.\n\nEach new scope offers a clean slate, a space to hold its own set of variables. When a variable name is repeated at different levels of the scope chain, shadowing occurs, which prevents access to the outer variable from that point inward.\n\nAs we step back out from these finer details, the next chapter shifts focus to the primary scope all JS programs include: the global scope.\n"
  },
  {
    "path": "scope-closures/ch4.md",
    "content": "# You Don't Know JS Yet: Scope & Closures - 2nd Edition\n# Chapter 4: Around the Global Scope\n\nChapter 3 mentioned the \"global scope\" several times, but you may still be wondering why a program's outermost scope is all that important in modern JS. The vast majority of work is now done inside of functions and modules rather than globally.\n\nIs it good enough to just assert, \"Avoid using the global scope,\" and be done with it?\n\nThe global scope of a JS program is a rich topic, with much more utility and nuance than you would likely assume. This chapter first explores how the global scope is (still) useful and relevant to writing JS programs today, then looks at differences in where and *how to access* the global scope in different JS environments.\n\nFully understanding the global scope is critical in your mastery of using lexical scope to structure your programs.\n\n## Why Global Scope?\n\nIt's likely no surprise to readers that most applications are composed of multiple (sometimes many!) individual JS files. So how exactly do all those separate files get stitched together in a single runtime context by the JS engine?\n\nWith respect to browser-executed applications, there are three main ways.\n\nFirst, if you're directly using ES modules (not transpiling them into some other module-bundle format), these files are loaded individually by the JS environment. Each module then `import`s references to whichever other modules it needs to access. The separate module files cooperate with each other exclusively through these shared imports, without needing any shared outer scope.\n\nSecond, if you're using a bundler in your build process, all the files are typically concatenated together before delivery to the browser and JS engine, which then only processes one big file. Even with all the pieces of the application co-located in a single file, some mechanism is necessary for each piece to register a *name* to be referred to by other pieces, as well as some facility for that access to occur.\n\nIn some build setups, the entire contents of the file are wrapped in a single enclosing scope, such as a wrapper function, universal module (UMD—see Appendix A), etc. Each piece can register itself for access from other pieces by way of local variables in that shared scope. For example:\n\n```js\n(function wrappingOuterScope(){\n    var moduleOne = (function one(){\n        // ..\n    })();\n\n    var moduleTwo = (function two(){\n        // ..\n\n        function callModuleOne() {\n            moduleOne.someMethod();\n        }\n\n        // ..\n    })();\n})();\n```\n\nAs shown, the `moduleOne` and `moduleTwo` local variables inside the `wrappingOuterScope()` function scope are declared so that these modules can access each other for their cooperation.\n\nWhile the scope of `wrappingOuterScope()` is a function and not the full environment global scope, it does act as a sort of \"application-wide scope,\" a bucket where all the top-level identifiers can be stored, though not in the real global scope. It's kind of like a stand-in for the global scope in that respect.\n\nAnd finally, the third way: whether a bundler tool is used for an application, or whether the (non-ES module) files are simply loaded in the browser individually (via `<script>` tags or other dynamic JS resource loading), if there is no single surrounding scope encompassing all these pieces, the **global scope** is the only way for them to cooperate with each other:\n\nA bundled file of this sort often looks something like this:\n\n```js\nvar moduleOne = (function one(){\n    // ..\n})();\nvar moduleTwo = (function two(){\n    // ..\n\n    function callModuleOne() {\n        moduleOne.someMethod();\n    }\n\n    // ..\n})();\n```\n\nHere, since there is no surrounding function scope, these `moduleOne` and `moduleTwo` declarations are simply dropped into the global scope. This is effectively the same as if the files hadn't been concatenated, but loaded separately:\n\nmodule1.js:\n\n```js\nvar moduleOne = (function one(){\n    // ..\n})();\n```\n\nmodule2.js:\n\n```js\nvar moduleTwo = (function two(){\n    // ..\n\n    function callModuleOne() {\n        moduleOne.someMethod();\n    }\n\n    // ..\n})();\n```\n\nIf these files are loaded separately as normal standalone .js files in a browser environment, each top-level variable declaration will end up as a global variable, since the global scope is the only shared resource between these two separate files—they're independent programs, from the perspective of the JS engine.\n\nIn addition to (potentially) accounting for where an application's code resides during runtime, and how each piece is able to access the other pieces to cooperate, the global scope is also where:\n\n* JS exposes its built-ins:\n\n    - primitives: `undefined`, `null`, `Infinity`, `NaN`\n    - natives: `Date()`, `Object()`, `String()`, etc.\n    - global functions: `eval()`, `parseInt()`, etc.\n    - namespaces: `Math`, `Atomics`, `JSON`\n    - friends of JS: `Intl`, `WebAssembly`\n\n* The environment hosting the JS engine exposes its own built-ins:\n\n    - `console` (and its methods)\n    - the DOM (`window`, `document`, etc)\n    - timers (`setTimeout(..)`, etc)\n    - web platform APIs: `navigator`, `history`, geolocation, WebRTC, etc.\n\nThese are just some of the many *globals* your programs will interact with.\n\n| NOTE: |\n| :--- |\n| Node also exposes several elements \"globally,\" but they're technically not in the `global` scope: `require()`, `__dirname`, `module`, `URL`, and so on. |\n\nMost developers agree that the global scope shouldn't just be a dumping ground for every variable in your application. That's a mess of bugs just waiting to happen. But it's also undeniable that the global scope is an important *glue* for practically every JS application.\n\n## Where Exactly is this Global Scope?\n\nIt might seem obvious that the global scope is located in the outermost portion of a file; that is, not inside any function or other block. But it's not quite as simple as that.\n\nDifferent JS environments handle the scopes of your programs, especially the global scope, differently. It's quite common for JS developers to harbor misconceptions without even realizing it.\n\n### Browser \"Window\"\n\nWith respect to treatment of the global scope, the most *pure* environment JS can be run in is as a standalone .js file loaded in a web page environment in a browser. I don't mean \"pure\" as in nothing automatically added—lots may be added!—but rather in terms of minimal intrusion on the code or interference with its expected global scope behavior.\n\nConsider this .js file:\n\n```js\nvar studentName = \"Kyle\";\n\nfunction hello() {\n    console.log(`Hello, ${ studentName }!`);\n}\n\nhello();\n// Hello, Kyle!\n```\n\nThis code may be loaded in a web page environment using an inline `<script>` tag, a `<script src=..>` script tag in the markup, or even a dynamically created `<script>` DOM element. In all three cases, the `studentName` and `hello` identifiers are declared in the global scope.\n\nThat means if you access the global object (commonly, `window` in the browser), you'll find properties of those same names there:\n\n```js\nvar studentName = \"Kyle\";\n\nfunction hello() {\n    console.log(`Hello, ${ window.studentName }!`);\n}\n\nwindow.hello();\n// Hello, Kyle!\n```\n\nThat's the default behavior one would expect from a reading of the JS specification: the outer scope *is* the global scope and `studentName` is legitimately created as global variable.\n\nThat's what I mean by *pure*. But unfortunately, that won't always be true of all JS environments you encounter, and that's often surprising to JS developers.\n\n#### Globals Shadowing Globals\n\nRecall the discussion of shadowing (and global unshadowing) from Chapter 3, where one variable declaration can override and prevent access to a declaration of the same name from an outer scope.\n\nAn unusual consequence of the difference between a global variable and a global property of the same name is that, within just the global scope itself, a global object property can be shadowed by a global variable:\n\n```js\nwindow.something = 42;\n\nlet something = \"Kyle\";\n\nconsole.log(something);\n// Kyle\n\nconsole.log(window.something);\n// 42\n```\n\nThe `let` declaration adds a `something` global variable but not a global object property (see Chapter 3). The effect then is that the `something` lexical identifier shadows the `something` global object property.\n\nIt's almost certainly a bad idea to create a divergence between the global object and the global scope. Readers of your code will almost certainly be tripped up.\n\nA simple way to avoid this gotcha with global declarations: always use `var` for globals. Reserve `let` and `const` for block scopes (see \"Scoping with Blocks\" in Chapter 6).\n\n#### DOM Globals\n\nI asserted that a browser-hosted JS environment has the most *pure* global scope behavior we'll see. However, it's not entirely *pure*.\n\nOne surprising behavior in the global scope you may encounter with browser-based JS applications: a DOM element with an `id` attribute automatically creates a global variable that references it.\n\nConsider this markup:\n\n```text\n<ul id=\"my-todo-list\">\n   <li id=\"first\">Write a book</li>\n   ..\n</ul>\n```\n\nAnd the JS for that page could include:\n\n```js\nfirst;\n// <li id=\"first\">..</li>\n\nwindow[\"my-todo-list\"];\n// <ul id=\"my-todo-list\">..</ul>\n```\n\nIf the `id` value is a valid lexical name (like `first`), the lexical variable is created. If not, the only way to access that global is through the global object (`window[..]`).\n\nThe auto-registration of all `id`-bearing DOM elements as global variables is an old legacy browser behavior that nevertheless must remain because so many old sites still rely on it. My advice is never to use these global variables, even though they will always be silently created.\n\n#### What's in a (Window) Name?\n\nAnother global scope oddity in browser-based JS:\n\n```js\nvar name = 42;\n\nconsole.log(name, typeof name);\n// \"42\" string\n```\n\n`window.name` is a pre-defined \"global\" in a browser context; it's a property on the global object, so it seems like a normal global variable (yet it's anything but \"normal\").\n\nWe used `var` for our declaration, which **does not** shadow the pre-defined `name` global property. That means, effectively, the `var` declaration is ignored, since there's already a global scope object property of that name. As we discussed earlier, had we used `let name`, we would have shadowed `window.name` with a separate global `name` variable.\n\nBut the truly surprising behavior is that even though we assigned the number `42` to `name` (and thus `window.name`), when we then retrieve its value, it's a string `\"42\"`! In this case, the weirdness is because `name` is actually a pre-defined getter/setter on the `window` object, which insists on its value being a string value. Yikes!\n\nWith the exception of some rare corner cases like DOM element ID's and `window.name`, JS running as a standalone file in a browser page has some of the most *pure* global scope behavior we will encounter.\n\n### Web Workers\n\nWeb Workers are a web platform extension on top of browser-JS behavior, which allows a JS file to run in a completely separate thread (operating system wise) from the thread that's running the main JS program.\n\nSince these Web Worker programs run on a separate thread, they're restricted in their communications with the main application thread, to avoid/limit race conditions and other complications. Web Worker code does not have access to the DOM, for example. Some web APIs are, however, made available to the worker, such as `navigator`.\n\nSince a Web Worker is treated as a wholly separate program, it does not share the global scope with the main JS program. However, the browser's JS engine is still running the code, so we can expect similar *purity* of its global scope behavior. Since there is no DOM access, the `window` alias for the global scope doesn't exist.\n\nIn a Web Worker, the global object reference is typically made using `self`:\n\n```js\nvar studentName = \"Kyle\";\nlet studentID = 42;\n\nfunction hello() {\n    console.log(`Hello, ${ self.studentName }!`);\n}\n\nself.hello();\n// Hello, Kyle!\n\nself.studentID;\n// undefined\n```\n\nJust as with main JS programs, `var` and `function` declarations create mirrored properties on the global object (aka, `self`), where other declarations (`let`, etc) do not.\n\nSo again, the global scope behavior we're seeing here is about as *pure* as it gets for running JS programs; perhaps it's even more *pure* since there's no DOM to muck things up!\n\n### Developer Tools Console/REPL\n\nRecall from Chapter 1 in *Get Started* that Developer Tools don't create a completely adherent JS environment. They do process JS code, but they also lean in favor of the UX interaction being most friendly to developers (aka, developer experience, or DX).\n\nIn some cases, favoring DX when typing in short JS snippets, over the normal strict steps expected for processing a full JS program, produces observable differences in code behavior between programs and tools. For example, certain error conditions applicable to a JS program may be relaxed and not displayed when the code is entered into a developer tool.\n\nWith respect to our discussions here about scope, such observable differences in behavior may include:\n\n* The behavior of the global scope\n\n* Hoisting (see Chapter 5)\n\n* Block-scoping declarators (`let` / `const`, see Chapter 6) when used in the outermost scope\n\nAlthough it might seem, while using the console/REPL, that statements entered in the outermost scope are being processed in the real global scope, that's not quite accurate. Such tools typically emulate the global scope position to an extent; it's emulation, not strict adherence. These tool environments prioritize developer convenience, which means that at times (such as with our current discussions regarding scope), observed behavior may deviate from the JS specification.\n\nThe take-away is that Developer Tools, while optimized to be convenient and useful for a variety of developer activities, are **not** suitable environments to determine or verify explicit and nuanced behaviors of an actual JS program context.\n\n### ES Modules (ESM)\n\nES6 introduced first-class support for the module pattern (covered in Chapter 8). One of the most obvious impacts of using ESM is how it changes the behavior of the observably top-level scope in a file.\n\nRecall this code snippet from earlier (which we'll adjust to ESM format by using the `export` keyword):\n\n```js\nvar studentName = \"Kyle\";\n\nfunction hello() {\n    console.log(`Hello, ${ studentName }!`);\n}\n\nhello();\n// Hello, Kyle!\n\nexport hello;\n```\n\nIf that code is in a file that's loaded as an ES module, it will still run exactly the same. However, the observable effects, from the overall application perspective, will be different.\n\nDespite being declared at the top level of the (module) file, in the outermost obvious scope, `studentName` and `hello` are not global variables. Instead, they are module-wide, or if you prefer, \"module-global.\"\n\nHowever, in a module there's no implicit \"module-wide scope object\" for these top-level declarations to be added to as properties, as there is when declarations appear in the top-level of non-module JS files. This is not to say that global variables cannot exist or be accessed in such programs. It's just that global variables don't get *created* by declaring variables in the top-level scope of a module.\n\nThe module's top-level scope is descended from the global scope, almost as if the entire contents of the module were wrapped in a function. Thus, all variables that exist in the global scope (whether they're on the global object or not!) are available as lexical identifiers from inside the module's scope.\n\nESM encourages a minimization of reliance on the global scope, where you import whatever modules you may need for the current module to operate. As such, you less often see usage of the global scope or its global object.\n\nHowever, as noted earlier, there are still plenty of JS and web globals that you will continue to access from the global scope, whether you realize it or not!\n\n### Node\n\nOne aspect of Node that often catches JS developers off-guard is that Node treats every single .js file that it loads, including the main one you start the Node process with, as a *module* (ES module or CommonJS module, see Chapter 8). The practical effect is that the top level of your Node programs **is never actually the global scope**, the way it is when loading a non-module file in the browser.\n\nAs of time of this writing, Node has recently added support for ES modules. But additionally, Node has from its beginning supported a module format referred to as \"CommonJS\", which looks like this:\n\n```js\nvar studentName = \"Kyle\";\n\nfunction hello() {\n    console.log(`Hello, ${ studentName }!`);\n}\n\nhello();\n// Hello, Kyle!\n\nmodule.exports.hello = hello;\n```\n\nBefore processing, Node effectively wraps such code in a function, so that the `var` and `function` declarations are contained in that wrapping function's scope, **not** treated as global variables.\n\nEnvision the preceding code as being seen by Node as this (illustrative, not actual):\n\n```js\nfunction Module(module,require,__dirname,...) {\n    var studentName = \"Kyle\";\n\n    function hello() {\n        console.log(`Hello, ${ studentName }!`);\n    }\n\n    hello();\n    // Hello, Kyle!\n\n    module.exports.hello = hello;\n}\n```\n\nNode then essentially invokes the added `Module(..)` function to run your module. You can clearly see here why `studentName` and `hello` identifiers are not global, but rather declared in the module scope.\n\nAs noted earlier, Node defines a number of \"globals\" like `require()`, but they're not actually identifiers in the global scope (nor properties of the global object). They're injected in the scope of every module, essentially a bit like the parameters listed in the `Module(..)` function declaration.\n\nSo how do you define actual global variables in Node? The only way to do so is to add properties to another of Node's automatically provided \"globals,\" which is ironically called `global`. `global` is a reference to the real global scope object, somewhat like using `window` in a browser JS environment.\n\nConsider:\n\n```js\nglobal.studentName = \"Kyle\";\n\nfunction hello() {\n    console.log(`Hello, ${ studentName }!`);\n}\n\nhello();\n// Hello, Kyle!\n\nmodule.exports.hello = hello;\n```\n\nHere we add `studentName` as a property on the `global` object, and then in the `console.log(..)` statement we're able to access `studentName` as a normal global variable.\n\nRemember, the identifier `global` is not defined by JS; it's specifically defined by Node.\n\n## Global This\n\nReviewing the JS environments we've looked at so far, a program may or may not:\n\n* Declare a global variable in the top-level scope with `var` or `function` declarations—or `let`, `const`, and `class`.\n\n* Also add global variables declarations as properties of the global scope object if `var` or `function` are used for the declaration.\n\n* Refer to the global scope object (for adding or retrieving global variables, as properties) with `window`, `self`, or `global`.\n\nI think it's fair to say that global scope access and behavior is more complicated than most developers assume, as the preceding sections have illustrated. But the complexity is never more obvious than in trying to nail down a universally applicable reference to the global scope object.\n\nYet another \"trick\" for obtaining a reference to the global scope object looks like:\n\n```js\nconst theGlobalScopeObject =\n    (new Function(\"return this\"))();\n```\n\n| NOTE: |\n| :--- |\n| A function can be dynamically constructed from code stored in a string value with the `Function()` constructor, similar to `eval(..)` (see \"Cheating: Runtime Scope Modifications\" in Chapter 1). Such a function will automatically be run in non-strict-mode (for legacy reasons) when invoked with the normal `()` function invocation as shown; its `this` will point at the global object. See the third book in the series, *Objects & Classes*, for more information on determining `this` bindings. |\n\nSo, we have `window`, `self`, `global`, and this ugly `new Function(..)` trick. That's a lot of different ways to try to get at this global object. Each has its pros and cons.\n\nWhy not introduce yet another!?!?\n\nAs of ES2020, JS has finally defined a standardized reference to the global scope object, called `globalThis`. So, subject to the recency of the JS engines your code runs in, you can use `globalThis` in place of any of those other approaches.\n\nWe could even attempt to define a cross-environment polyfill that's safer across pre-`globalThis` JS environments, such as:\n\n```js\nconst theGlobalScopeObject =\n    (typeof globalThis != \"undefined\") ? globalThis :\n    (typeof global != \"undefined\") ? global :\n    (typeof window != \"undefined\") ? window :\n    (typeof self != \"undefined\") ? self :\n    (new Function(\"return this\"))();\n```\n\nPhew! That's certainly not ideal, but it works if you find yourself needing a reliable global scope reference.\n\n(The proposed name `globalThis` was fairly controversial while the feature was being added to JS. Specifically, I and many others felt the \"this\" reference in its name was misleading, since the reason you reference this object is to access to the global scope, never to access some sort of global/default `this` binding. There were many other names considered, but for a variety of reasons ruled out. Unfortunately, the name chosen ended up as a last resort. If you plan to interact with the global scope object in your programs, to reduce confusion, I strongly recommend choosing a better name, such as (the laughably long but accurate!) `theGlobalScopeObject` used here.)\n\n## Globally Aware\n\nThe global scope is present and relevant in every JS program, even though modern patterns for organizing code into modules de-emphasizes much of the reliance on storing identifiers in that namespace.\n\nStill, as our code proliferates more and more beyond the confines of the browser, it's especially important we have a solid grasp on the differences in how the global scope (and global scope object!) behave across different JS environments.\n\nWith the big picture of global scope now sharper in focus, the next chapter again descends into the deeper details of lexical scope, examining how and when variables can be used.\n"
  },
  {
    "path": "scope-closures/ch5.md",
    "content": "# You Don't Know JS Yet: Scope & Closures - 2nd Edition\n# Chapter 5: The (Not So) Secret Lifecycle of Variables\n\nBy now you should have a decent grasp of the nesting of scopes, from the global scope downward—called a program's scope chain.\n\nBut just knowing which scope a variable comes from is only part of the story. If a variable declaration appears past the first statement of a scope, how will any references to that identifier *before* the declaration behave? What happens if you try to declare the same variable twice in a scope?\n\nJS's particular flavor of lexical scope is rich with nuance in how and when variables come into existence and become available to the program.\n\n## When Can I Use a Variable?\n\nAt what point does a variable become available to use within its scope? There may seem to be an obvious answer: *after* the variable has been declared/created. Right? Not quite.\n\nConsider:\n\n```js\ngreeting();\n// Hello!\n\nfunction greeting() {\n    console.log(\"Hello!\");\n}\n```\n\nThis code works fine. You may have seen or even written code like it before. But did you ever wonder how or why it works? Specifically, why can you access the identifier `greeting` from line 1 (to retrieve and execute a function reference), even though the `greeting()` function declaration doesn't occur until line 4?\n\nRecall Chapter 1 points out that all identifiers are registered to their respective scopes during compile time. Moreover, every identifier is *created* at the beginning of the scope it belongs to, **every time that scope is entered**.\n\nThe term most commonly used for a variable being visible from the beginning of its enclosing scope, even though its declaration may appear further down in the scope, is called **hoisting**.\n\nBut hoisting alone doesn't fully answer the question. We can see an identifier called `greeting` from the beginning of the scope, but why can we **call** the `greeting()` function before it's been declared?\n\nIn other words, how does the variable `greeting` have any value (the function reference) assigned to it, from the moment the scope starts running? The answer is a special characteristic of formal `function` declarations, called *function hoisting*. When a `function` declaration's name identifier is registered at the top of its scope, it's additionally auto-initialized to that function's reference. That's why the function can be called throughout the entire scope!\n\nOne key detail is that both *function hoisting* and `var`-flavored *variable hoisting* attach their name identifiers to the nearest enclosing **function scope** (or, if none, the global scope), not a block scope.\n\n| NOTE: |\n| :--- |\n| Declarations with `let` and `const` still hoist (see the TDZ discussion later in this chapter). But these two declaration forms attach to their enclosing block rather than just an enclosing function as with `var` and `function` declarations. See \"Scoping with Blocks\" in Chapter 6 for more information. |\n\n### Hoisting: Declaration vs. Expression\n\n*Function hoisting* only applies to formal `function` declarations (specifically those which appear outside of blocks—see \"FiB\" in Chapter 6), not to `function` expression assignments. Consider:\n\n```js\ngreeting();\n// TypeError\n\nvar greeting = function greeting() {\n    console.log(\"Hello!\");\n};\n```\n\nLine 1 (`greeting();`) throws an error. But the *kind* of error thrown is very important to notice. A `TypeError` means we're trying to do something with a value that is not allowed. Depending on your JS environment, the error message would say something like, \"'undefined' is not a function,\" or more helpfully, \"'greeting' is not a function.\"\n\nNotice that the error is **not** a `ReferenceError`. JS isn't telling us that it couldn't find `greeting` as an identifier in the scope. It's telling us that `greeting` was found but doesn't hold a function reference at that moment. Only functions can be invoked, so attempting to invoke some non-function value results in an error.\n\nBut what does `greeting` hold, if not the function reference?\n\nIn addition to being hoisted, variables declared with `var` are also automatically initialized to `undefined` at the beginning of their scope—again, the nearest enclosing function, or the global. Once initialized, they're available to be used (assigned to, retrieved from, etc.) throughout the whole scope.\n\nSo on that first line, `greeting` exists, but it holds only the default `undefined` value. It's not until line 4 that `greeting` gets assigned the function reference.\n\nPay close attention to the distinction here. A `function` declaration is hoisted **and initialized to its function value** (again, called *function hoisting*). A `var` variable is also hoisted, and then auto-initialized to `undefined`. Any subsequent `function` expression assignments to that variable don't happen until that assignment is processed during runtime execution.\n\nIn both cases, the name of the identifier is hoisted. But the function reference association isn't handled at initialization time (beginning of the scope) unless the identifier was created in a formal `function` declaration.\n\n### Variable Hoisting\n\nLet's look at another example of *variable hoisting*:\n\n```js\ngreeting = \"Hello!\";\nconsole.log(greeting);\n// Hello!\n\nvar greeting = \"Howdy!\";\n```\n\nThough `greeting` isn't declared until line 5, it's available to be assigned to as early as line 1. Why?\n\nThere's two necessary parts to the explanation:\n\n* the identifier is hoisted,\n* **and** it's automatically initialized to the value `undefined` from the top of the scope.\n\n| NOTE: |\n| :--- |\n| Using *variable hoisting* of this sort probably feels unnatural, and many readers might rightly want to avoid relying on it in their programs. But should all hoisting (including *function hoisting*) be avoided? We'll explore these different perspectives on hoisting in more detail in Appendix A. |\n\n## Hoisting: Yet Another Metaphor\n\nChapter 2 was full of metaphors (to illustrate scope), but here we are faced with yet another: hoisting itself. Rather than hoisting being a concrete execution step the JS engine performs, it's more useful to think of hoisting as a visualization of various actions JS takes in setting up the program **before execution**.\n\nThe typical assertion of what hoisting means: *lifting*—like lifting a heavy weight upward—any identifiers all the way to the top of a scope. The explanation often asserted is that the JS engine will actually *rewrite* that program before execution, so that it looks more like this:\n\n```js\nvar greeting;           // hoisted declaration\ngreeting = \"Hello!\";    // the original line 1\nconsole.log(greeting);  // Hello!\ngreeting = \"Howdy!\";    // `var` is gone!\n```\n\nThe hoisting (metaphor) proposes that JS pre-processes the original program and re-arranges it a bit, so that all the declarations have been moved to the top of their respective scopes, before execution. Moreover, the hoisting metaphor asserts that `function` declarations are, in their entirety, hoisted to the top of each scope. Consider:\n\n```js\nstudentName = \"Suzy\";\ngreeting();\n// Hello Suzy!\n\nfunction greeting() {\n    console.log(`Hello ${ studentName }!`);\n}\nvar studentName;\n```\n\nThe \"rule\" of the hoisting metaphor is that function declarations are hoisted first, then variables are hoisted immediately after all the functions. Thus, the hoisting story suggests that program is *re-arranged* by the JS engine to look like this:\n\n```js\nfunction greeting() {\n    console.log(`Hello ${ studentName }!`);\n}\nvar studentName;\n\nstudentName = \"Suzy\";\ngreeting();\n// Hello Suzy!\n```\n\nThis hoisting metaphor is convenient. Its benefit is allowing us to hand wave over the magical look-ahead pre-processing necessary to find all these declarations buried deep in scopes and somehow move (hoist) them to the top; we can just think about the program as if it's executed by the JS engine in a **single pass**, top-down.\n\nSingle-pass definitely seems more straightforward than Chapter 1's assertion of a two-phase processing.\n\nHoisting as a mechanism for re-ordering code may be an attractive simplification, but it's not accurate. The JS engine doesn't actually re-arrange the code. It can't magically look ahead and find declarations; the only way to accurately find them, as well as all the scope boundaries in the program, would be to fully parse the code.\n\nGuess what parsing is? The first phase of the two-phase processing! There's no magical mental gymnastics that gets around that fact.\n\nSo if the hoisting metaphor is (at best) inaccurate, what should we do with the term? I think it's still useful—indeed, even members of TC39 regularly use it!—but I don't think we should claim it's an actual re-arrangement of source code.\n\n| WARNING: |\n| :--- |\n| Incorrect or incomplete mental models often still seem sufficient because they can occasionally lead to accidental right answers. But in the long run it's harder to accurately analyze and predict outcomes if your thinking isn't particularly aligned with how the JS engine works. |\n\nI assert that hoisting *should* be used to refer to the **compile-time operation** of generating runtime instructions for the automatic registration of a variable at the beginning of its scope, each time that scope is entered.\n\nThat's a subtle but important shift, from hoisting as a runtime behavior to its proper place among compile-time tasks.\n\n## Re-declaration?\n\nWhat do you think happens when a variable is declared more than once in the same scope? Consider:\n\n```js\nvar studentName = \"Frank\";\nconsole.log(studentName);\n// Frank\n\nvar studentName;\nconsole.log(studentName);   // ???\n```\n\nWhat do you expect to be printed for that second message? Many believe the second `var studentName` has re-declared the variable (and thus \"reset\" it), so they expect `undefined` to be printed.\n\nBut is there such a thing as a variable being \"re-declared\" in the same scope? No.\n\nIf you consider this program from the perspective of the hoisting metaphor, the code would be re-arranged like this for execution purposes:\n\n```js\nvar studentName;\nvar studentName;    // clearly a pointless no-op!\n\nstudentName = \"Frank\";\nconsole.log(studentName);\n// Frank\n\nconsole.log(studentName);\n// Frank\n```\n\nSince hoisting is actually about registering a variable at the beginning of a scope, there's nothing to be done in the middle of the scope where the original program actually had the second `var studentName` statement. It's just a no-op(eration), a pointless statement.\n\n| TIP: |\n| :--- |\n| In the style of the conversation narrative from Chapter 2, *Compiler* would find the second `var` declaration statement and ask the *Scope Manager* if it had already seen a `studentName` identifier; since it had, there wouldn't be anything else to do. |\n\nIt's also important to point out that `var studentName;` doesn't mean `var studentName = undefined;`, as most assume. Let's prove they're different by considering this variation of the program:\n\n```js\nvar studentName = \"Frank\";\nconsole.log(studentName);   // Frank\n\nvar studentName;\nconsole.log(studentName);   // Frank <--- still!\n\n// let's add the initialization explicitly\nvar studentName = undefined;\nconsole.log(studentName);   // undefined <--- see!?\n```\n\nSee how the explicit `= undefined` initialization produces a different outcome than assuming it happens implicitly when omitted? In the next section, we'll revisit this topic of initialization of variables from their declarations.\n\nA repeated `var` declaration of the same identifier name in a scope is effectively a do-nothing operation. Here's another illustration, this time across a function of the same name:\n\n```js\nvar greeting;\n\nfunction greeting() {\n    console.log(\"Hello!\");\n}\n\n// basically, a no-op\nvar greeting;\n\ntypeof greeting;        // \"function\"\n\nvar greeting = \"Hello!\";\n\ntypeof greeting;        // \"string\"\n```\n\nThe first `greeting` declaration registers the identifier to the scope, and because it's a `var` the auto-initialization will be `undefined`. The `function` declaration doesn't need to re-register the identifier, but because of *function hoisting* it overrides the auto-initialization to use the function reference. The second `var greeting` by itself doesn't do anything since `greeting` is already an identifier and *function hoisting* already took precedence for the auto-initialization.\n\nActually assigning `\"Hello!\"` to `greeting` changes its value from the initial function `greeting()` to the string; `var` itself doesn't have any effect.\n\nWhat about repeating a declaration within a scope using `let` or `const`?\n\n```js\nlet studentName = \"Frank\";\n\nconsole.log(studentName);\n\nlet studentName = \"Suzy\";\n```\n\nThis program will not execute, but instead immediately throw a `SyntaxError`. Depending on your JS environment, the error message will indicate something like: \"studentName has already been declared.\" In other words, this is a case where attempted \"re-declaration\" is explicitly not allowed!\n\nIt's not just that two declarations involving `let` will throw this error. If either declaration uses `let`, the other can be either `let` or `var`, and the error will still occur, as illustrated with these two variations:\n\n```js\nvar studentName = \"Frank\";\n\nlet studentName = \"Suzy\";\n```\n\nand:\n\n```js\nlet studentName = \"Frank\";\n\nvar studentName = \"Suzy\";\n```\n\nIn both cases, a `SyntaxError` is thrown on the *second* declaration. In other words, the only way to \"re-declare\" a variable is to use `var` for all (two or more) of its declarations.\n\nBut why disallow it? The reason for the error is not technical per se, as `var` \"re-declaration\" has always been allowed; clearly, the same allowance could have been made for `let`.\n\nIt's really more of a \"social engineering\" issue. \"Re-declaration\" of variables is seen by some, including many on the TC39 body, as a bad habit that can lead to program bugs. So when ES6 introduced `let`, they decided to prevent \"re-declaration\" with an error.\n\n| NOTE: |\n| :--- |\n| This is of course a stylistic opinion, not really a technical argument. Many developers agree with the position, and that's probably in part why TC39 included the error (as well as `let` conforming to `const`). But a reasonable case could have been made that staying consistent with `var`'s precedent was more prudent, and that such opinion-enforcement was best left to opt-in tooling like linters. In Appendix A, we'll explore whether `var` (and its associated behavior, like \"re-declaration\") can still be useful in modern JS. |\n\nWhen *Compiler* asks *Scope Manager* about a declaration, if that identifier has already been declared, and if either/both declarations were made with `let`, an error is thrown. The intended signal to the developer is \"Stop relying on sloppy re-declaration!\"\n\n### Constants?\n\nThe `const` keyword is more constrained than `let`. Like `let`, `const` cannot be repeated with the same identifier in the same scope. But there's actually an overriding technical reason why that sort of \"re-declaration\" is disallowed, unlike `let` which disallows \"re-declaration\" mostly for stylistic reasons.\n\nThe `const` keyword requires a variable to be initialized, so omitting an assignment from the declaration results in a `SyntaxError`:\n\n```js\nconst empty;   // SyntaxError\n```\n\n`const` declarations create variables that cannot be re-assigned:\n\n```js\nconst studentName = \"Frank\";\nconsole.log(studentName);\n// Frank\n\nstudentName = \"Suzy\";   // TypeError\n```\n\nThe `studentName` variable cannot be re-assigned because it's declared with a `const`.\n\n| WARNING: |\n| :--- |\n| The error thrown when re-assigning `studentName` is a `TypeError`, not a `SyntaxError`. The subtle distinction here is actually pretty important, but unfortunately far too easy to miss. Syntax errors represent faults in the program that stop it from even starting execution. Type errors represent faults that arise during program execution. In the preceding snippet, `\"Frank\"` is printed out before we process the re-assignment of `studentName`, which then throws the error. |\n\nSo if `const` declarations cannot be re-assigned, and `const` declarations always require assignments, then we have a clear technical reason why `const` must disallow any \"re-declarations\": any `const` \"re-declaration\" would also necessarily be a `const` re-assignment, which can't be allowed!\n\n```js\nconst studentName = \"Frank\";\n\n// obviously this must be an error\nconst studentName = \"Suzy\";\n```\n\nSince `const` \"re-declaration\" must be disallowed (on those technical grounds), TC39 essentially felt that `let` \"re-declaration\" should be disallowed as well, for consistency. It's debatable if this was the best choice, but at least we have the reasoning behind the decision.\n\n### Loops\n\nSo it's clear from our previous discussion that JS doesn't really want us to \"re-declare\" our variables within the same scope. That probably seems like a straightforward admonition, until you consider what it means for repeated execution of declaration statements in loops. Consider:\n\n```js\nvar keepGoing = true;\nwhile (keepGoing) {\n    let value = Math.random();\n    if (value > 0.5) {\n        keepGoing = false;\n    }\n}\n```\n\nIs `value` being \"re-declared\" repeatedly in this program? Will we get errors thrown? No.\n\nAll the rules of scope (including \"re-declaration\" of `let`-created variables) are applied *per scope instance*. In other words, each time a scope is entered during execution, everything resets.\n\nEach loop iteration is its own new scope instance, and within each scope instance, `value` is only being declared once. So there's no attempted \"re-declaration,\" and thus no error. Before we consider other loop forms, what if the `value` declaration in the previous snippet were changed to a `var`?\n\n```js\nvar keepGoing = true;\nwhile (keepGoing) {\n    var value = Math.random();\n    if (value > 0.5) {\n        keepGoing = false;\n    }\n}\n```\n\nIs `value` being \"re-declared\" here, especially since we know `var` allows it? No. Because `var` is not treated as a block-scoping declaration (see Chapter 6), it attaches itself to the global scope. So there's just one `value` variable, in the same scope as `keepGoing` (global scope, in this case). No \"re-declaration\" here, either!\n\nOne way to keep this all straight is to remember that `var`, `let`, and `const` keywords are effectively *removed* from the code by the time it starts to execute. They're handled entirely by the compiler.\n\nIf you mentally erase the declarator keywords and then try to process the code, it should help you decide if and when (re-)declarations might occur.\n\nWhat about \"re-declaration\" with other loop forms, like `for`-loops?\n\n```js\nfor (let i = 0; i < 3; i++) {\n    let value = i * 10;\n    console.log(`${ i }: ${ value }`);\n}\n// 0: 0\n// 1: 10\n// 2: 20\n```\n\nIt should be clear that there's only one `value` declared per scope instance. But what about `i`? Is it being \"re-declared\"?\n\nTo answer that, consider what scope `i` is in. It might seem like it would be in the outer (in this case, global) scope, but it's not. It's in the scope of `for`-loop body, just like `value` is. In fact, you could sorta think about that loop in this more verbose equivalent form:\n\n```js\n{\n    // a fictional variable for illustration\n    let $$i = 0;\n\n    for ( /* nothing */; $$i < 3; $$i++) {\n        // here's our actual loop `i`!\n        let i = $$i;\n\n        let value = i * 10;\n        console.log(`${ i }: ${ value }`);\n    }\n    // 0: 0\n    // 1: 10\n    // 2: 20\n}\n```\n\nNow it should be clear: the `i` and `value` variables are both declared exactly once **per scope instance**. No \"re-declaration\" here.\n\nWhat about other `for`-loop forms?\n\n```js\nfor (let index in students) {\n    // this is fine\n}\n\nfor (let student of students) {\n    // so is this\n}\n```\n\nSame thing with `for..in` and `for..of` loops: the declared variable is treated as *inside* the loop body, and thus is handled per iteration (aka, per scope instance). No \"re-declaration.\"\n\nOK, I know you're thinking that I sound like a broken record at this point. But let's explore how `const` impacts these looping constructs. Consider:\n\n```js\nvar keepGoing = true;\nwhile (keepGoing) {\n    // ooo, a shiny constant!\n    const value = Math.random();\n    if (value > 0.5) {\n        keepGoing = false;\n    }\n}\n```\n\nJust like the `let` variant of this program we saw earlier, `const` is being run exactly once within each loop iteration, so it's safe from \"re-declaration\" troubles. But things get more complicated when we talk about `for`-loops.\n\n`for..in` and `for..of` are fine to use with `const`:\n\n```js\nfor (const index in students) {\n    // this is fine\n}\n\nfor (const student of students) {\n    // this is also fine\n}\n```\n\nBut not the general `for`-loop:\n\n```js\nfor (const i = 0; i < 3; i++) {\n    // oops, this is going to fail with\n    // a Type Error after the first iteration\n}\n```\n\nWhat's wrong here? We could use `let` just fine in this construct, and we asserted that it creates a new `i` for each loop iteration scope, so it doesn't even seem to be a \"re-declaration.\"\n\nLet's mentally \"expand\" that loop like we did earlier:\n\n```js\n{\n    // a fictional variable for illustration\n    const $$i = 0;\n\n    for ( ; $$i < 3; $$i++) {\n        // here's our actual loop `i`!\n        const i = $$i;\n        // ..\n    }\n}\n```\n\nDo you spot the problem? Our `i` is indeed just created once inside the loop. That's not the problem. The problem is the conceptual `$$i` that must be incremented each time with the `$$i++` expression. That's **re-assignment** (not \"re-declaration\"), which isn't allowed for constants.\n\nRemember, this \"expanded\" form is only a conceptual model to help you intuit the source of the problem. You might wonder if JS could have effectively made the `const $$i = 0` instead into `let $ii = 0`, which would then allow `const` to work with our classic `for`-loop? It's possible, but then it could have introduced potentially surprising exceptions to `for`-loop semantics.\n\nFor example, it would have been a rather arbitrary (and likely confusing) nuanced exception to allow `i++` in the `for`-loop header to skirt strictness of the `const` assignment, but not allow other re-assignments of `i` inside the loop iteration, as is sometimes useful.\n\nThe straightforward answer is: `const` can't be used with the classic `for`-loop form because of the required re-assignment.\n\nInterestingly, if you don't do re-assignment, then it's valid:\n\n```js\nvar keepGoing = true;\n\nfor (const i = 0; keepGoing; /* nothing here */ ) {\n    keepGoing = (Math.random() > 0.5);\n    // ..\n}\n```\n\nThat works, but it's pointless. There's no reason to declare `i` in that position with a `const`, since the whole point of such a variable in that position is **to be used for counting iterations**. Just use a different loop form, like a `while` loop, or use a `let`!\n\n## Uninitialized Variables (aka, TDZ)\n\nWith `var` declarations, the variable is \"hoisted\" to the top of its scope. But it's also automatically initialized to the `undefined` value, so that the variable can be used throughout the entire scope.\n\nHowever, `let` and `const` declarations are not quite the same in this respect.\n\nConsider:\n\n```js\nconsole.log(studentName);\n// ReferenceError\n\nlet studentName = \"Suzy\";\n```\n\nThe result of this program is that a `ReferenceError` is thrown on the first line. Depending on your JS environment, the error message may say something like: \"Cannot access studentName before initialization.\"\n\n| NOTE: |\n| :--- |\n| The error message as seen here used to be much more vague or misleading. Thankfully, several of us in the community were successfully able to lobby for JS engines to improve this error message so it more accurately tells you what's wrong! |\n\nThat error message is quite indicative of what's wrong: `studentName` exists on line 1, but it's not been initialized, so it cannot be used yet. Let's try this:\n\n```js\nstudentName = \"Suzy\";   // let's try to initialize it!\n// ReferenceError\n\nconsole.log(studentName);\n\nlet studentName;\n```\n\nOops. We still get the `ReferenceError`, but now on the first line where we're trying to assign to (aka, initialize!) this so-called \"uninitialized\" variable `studentName`. What's the deal!?\n\nThe real question is, how do we initialize an uninitialized variable? For `let`/`const`, the **only way** to do so is with an assignment attached to a declaration statement. An assignment by itself is insufficient! Consider:\n\n```js\nlet studentName = \"Suzy\";\nconsole.log(studentName);   // Suzy\n```\n\nHere, we are initializing the `studentName` (in this case, to `\"Suzy\"` instead of `undefined`) by way of the `let` declaration statement form that's coupled with an assignment.\n\nAlternatively:\n\n```js\n// ..\n\nlet studentName;\n// or:\n// let studentName = undefined;\n\n// ..\n\nstudentName = \"Suzy\";\n\nconsole.log(studentName);\n// Suzy\n```\n\n| NOTE: |\n| :--- |\n| That's interesting! Recall from earlier, we said that `var studentName;` is *not* the same as `var studentName = undefined;`, but here with `let`, they behave the same. The difference comes down to the fact that `var studentName` automatically initializes at the top of the scope, where `let studentName` does not. |\n\nRemember that we've asserted a few times so far that *Compiler* ends up removing any `var`/`let`/`const` declarators, replacing them with the instructions at the top of each scope to register the appropriate identifiers.\n\nSo if we analyze what's going on here, we see that an additional nuance is that *Compiler* is also adding an instruction in the middle of the program, at the point where the variable `studentName` was declared, to handle that declaration's auto-initialization. We cannot use the variable at any point prior to that initialization occurring. The same goes for `const` as it does for `let`.\n\nThe term coined by TC39 to refer to this *period of time* from the entering of a scope to where the auto-initialization of the variable occurs is: Temporal Dead Zone (TDZ).\n\nThe TDZ is the time window where a variable exists but is still uninitialized, and therefore cannot be accessed in any way. Only the execution of the instructions left by *Compiler* at the point of the original declaration can do that initialization. After that moment, the TDZ is done, and the variable is free to be used for the rest of the scope.\n\nA `var` also technically has a TDZ, but it's zero in length and thus unobservable to our programs! Only `let` and `const` have an observable TDZ.\n\nBy the way, \"temporal\" in TDZ does indeed refer to *time* not *position in code*. Consider:\n\n```js\naskQuestion();\n// ReferenceError\n\nlet studentName = \"Suzy\";\n\nfunction askQuestion() {\n    console.log(`${ studentName }, do you know?`);\n}\n```\n\nEven though positionally the `console.log(..)` referencing `studentName` comes *after* the `let studentName` declaration, timing wise the `askQuestion()` function is invoked *before* the `let` statement is encountered, while `studentName` is still in its TDZ! Hence the error.\n\nThere's a common misconception that TDZ means `let` and `const` do not hoist. This is an inaccurate, or at least slightly misleading, claim. They definitely hoist.\n\nThe actual difference is that `let`/`const` declarations do not automatically initialize at the beginning of the scope, the way `var` does. The *debate* then is if the auto-initialization is *part of* hoisting, or not? I think auto-registration of a variable at the top of the scope (i.e., what I call \"hoisting\") and auto-initialization at the top of the scope (to `undefined`) are distinct operations and shouldn't be lumped together under the single term \"hoisting.\"\n\nWe've already seen that `let` and `const` don't auto-initialize at the top of the scope. But let's prove that `let` and `const` *do* hoist (auto-register at the top of the scope), courtesy of our friend shadowing (see \"Shadowing\" in Chapter 3):\n\n```js\nvar studentName = \"Kyle\";\n\n{\n    console.log(studentName);\n    // ???\n\n    // ..\n\n    let studentName = \"Suzy\";\n\n    console.log(studentName);\n    // Suzy\n}\n```\n\nWhat's going to happen with the first `console.log(..)` statement? If `let studentName` didn't hoist to the top of the scope, then the first `console.log(..)` *should* print `\"Kyle\"`, right? At that moment, it would seem, only the outer `studentName` exists, so that's the variable `console.log(..)` should access and print.\n\nBut instead, the first `console.log(..)` throws a TDZ error, because in fact, the inner scope's `studentName` **was** hoisted (auto-registered at the top of the scope). What **didn't** happen (yet!) was the auto-initialization of that inner `studentName`; it's still uninitialized at that moment, hence the TDZ violation!\n\nSo to summarize, TDZ errors occur because `let`/`const` declarations *do* hoist their declarations to the top of their scopes, but unlike `var`, they defer the auto-initialization of their variables until the moment in the code's sequencing where the original declaration appeared. This window of time (hint: temporal), whatever its length, is the TDZ.\n\nHow can you avoid TDZ errors?\n\nMy advice: always put your `let` and `const` declarations at the top of any scope. Shrink the TDZ window to zero (or near zero) length, and then it'll be moot.\n\nBut why is TDZ even a thing? Why didn't TC39 dictate that `let`/`const` auto-initialize the way `var` does? Just be patient, we'll come back to explore the *why* of TDZ in Appendix A.\n\n## Finally Initialized\n\nWorking with variables has much more nuance than it seems at first glance. *Hoisting*, *(re)declaration*, and the *TDZ* are common sources of confusion for developers, especially those who have worked in other languages before coming to JS. Before moving on, make sure your mental model is fully grounded on these aspects of JS scope and variables.\n\nHoisting is generally cited as an explicit mechanism of the JS engine, but it's really more a metaphor to describe the various ways JS handles variable declarations during compilation. But even as a metaphor, hoisting offers useful structure for thinking about the life-cycle of a variable—when it's created, when it's available to use, when it goes away.\n\nDeclaration and re-declaration of variables tend to cause confusion when thought of as runtime operations. But if you shift to compile-time thinking for these operations, the quirks and *shadows* diminish.\n\nThe TDZ (temporal dead zone) error is strange and frustrating when encountered. Fortunately, TDZ is relatively straightforward to avoid if you're always careful to place `let`/`const` declarations at the top of any scope.\n\nAs you successfully navigate these twists and turns of variable scope, the next chapter will lay out the factors that guide our decisions to place our declarations in various scopes, especially nested blocks.\n"
  },
  {
    "path": "scope-closures/ch6.md",
    "content": "# You Don't Know JS Yet: Scope & Closures - 2nd Edition\n# Chapter 6: Limiting Scope Exposure\n\nSo far our focus has been explaining the mechanics of how scopes and variables work. With that foundation now firmly in place, our attention raises to a higher level of thinking: decisions and patterns we apply across the whole program.\n\nTo begin, we're going to look at how and why we should be using different levels of scope (functions and blocks) to organize our program's variables, specifically to reduce scope over-exposure.\n\n## Least Exposure\n\nIt makes sense that functions define their own scopes. But why do we need blocks to create scopes as well?\n\nSoftware engineering articulates a fundamental discipline, typically applied to software security, called \"The Principle of Least Privilege\" (POLP). [^POLP] And a variation of this principle that applies to our current discussion is typically labeled as \"Least Exposure\" (POLE).\n\nPOLP expresses a defensive posture to software architecture: components of the system should be designed to function with least privilege, least access, least exposure. If each piece is connected with minimum-necessary capabilities, the overall system is stronger from a security standpoint, because a compromise or failure of one piece has a minimized impact on the rest of the system.\n\nIf POLP focuses on system-level component design, the POLE *Exposure* variant focuses on a lower level; we'll apply it to how scopes interact with each other.\n\nIn following POLE, what do we want to minimize the exposure of? Simply: the variables registered in each scope.\n\nThink of it this way: why shouldn't you just place all the variables of your program out in the global scope? That probably immediately feels like a bad idea, but it's worth considering why that is. When variables used by one part of the program are exposed to another part of the program, via scope, there are three main hazards that often arise:\n\n* **Naming Collisions**: if you use a common and useful variable/function name in two different parts of the program, but the identifier comes from one shared scope (like the global scope), then name collision occurs, and it's very likely that bugs will occur as one part uses the variable/function in a way the other part doesn't expect.\n\n    For example, imagine if all your loops used a single global `i` index variable, and then it happens that one loop in a function is running during an iteration of a loop from another function, and now the shared `i` variable gets an unexpected value.\n\n* **Unexpected Behavior**: if you expose variables/functions whose usage is otherwise *private* to a piece of the program, it allows other developers to use them in ways you didn't intend, which can violate expected behavior and cause bugs.\n\n    For example, if your part of the program assumes an array contains all numbers, but someone else's code accesses and modifies the array to include booleans and strings, your code may then misbehave in unexpected ways.\n\n    Worse, exposure of *private* details invites those with mal-intent to try to work around limitations you have imposed, to do things with your part of the software that shouldn't be allowed.\n\n* **Unintended Dependency**: if you expose variables/functions unnecessarily, it invites other developers to use and depend on those otherwise *private* pieces. While that doesn't break your program today, it creates a refactoring hazard in the future, because now you cannot as easily refactor that variable or function without potentially breaking other parts of the software that you don't control.\n\n    For example, if your code relies on an array of numbers, and you later decide it's better to use some other data structure instead of an array, you now must take on the liability of adjusting other affected parts of the software.\n\nPOLE, as applied to variable/function scoping, essentially says, default to exposing the bare minimum necessary, keeping everything else as private as possible. Declare variables in as small and deeply nested of scopes as possible, rather than placing everything in the global (or even outer function) scope.\n\nIf you design your software accordingly, you have a much greater chance of avoiding (or at least minimizing) these three hazards.\n\nConsider:\n\n```js\nfunction diff(x,y) {\n    if (x > y) {\n        let tmp = x;\n        x = y;\n        y = tmp;\n    }\n\n    return y - x;\n}\n\ndiff(3,7);      // 4\ndiff(7,5);      // 2\n```\n\nIn this `diff(..)` function, we want to ensure that `y` is greater than or equal to `x`, so that when we subtract (`y - x`), the result is `0` or larger. If `x` is initially larger (the result would be negative!), we swap `x` and `y` using a `tmp` variable, to keep the result positive.\n\nIn this simple example, it doesn't seem to matter whether `tmp` is inside the `if` block or whether it belongs at the function level—it certainly shouldn't be a global variable! However, following the POLE principle, `tmp` should be as hidden in scope as possible. So we block scope `tmp` (using `let`) to the `if` block.\n\n## Hiding in Plain (Function) Scope\n\nIt should now be clear why it's important to hide our variable and function declarations in the lowest (most deeply nested) scopes possible. But how do we do so?\n\nWe've already seen the `let` and `const` keywords, which are block scoped declarators; we'll come back to them in more detail shortly. But first, what about hiding `var` or `function` declarations in scopes? That can easily be done by wrapping a `function` scope around a declaration.\n\nLet's consider an example where `function` scoping can be useful.\n\nThe mathematical operation \"factorial\" (notated as \"6!\") is the multiplication of a given integer against all successively lower integers down to `1`—actually, you can stop at `2` since multiplying `1` does nothing. In other words, \"6!\" is the same as \"6 * 5!\", which is the same as \"6 * 5 * 4!\", and so on. Because of the nature of the math involved, once any given integer's factorial (like \"4!\") has been calculated, we shouldn't need to do that work again, as it'll always be the same answer.\n\nSo if you naively calculate factorial for `6`, then later want to calculate factorial for `7`, you might unnecessarily re-calculate the factorials of all the integers from 2 up to 6. If you're willing to trade memory for speed, you can solve that wasted computation by caching each integer's factorial as it's calculated:\n\n```js\nvar cache = {};\n\nfunction factorial(x) {\n    if (x < 2) return 1;\n    if (!(x in cache)) {\n        cache[x] = x * factorial(x - 1);\n    }\n    return cache[x];\n}\n\nfactorial(6);\n// 720\n\ncache;\n// {\n//     \"2\": 2,\n//     \"3\": 6,\n//     \"4\": 24,\n//     \"5\": 120,\n//     \"6\": 720\n// }\n\nfactorial(7);\n// 5040\n```\n\nWe're storing all the computed factorials in `cache` so that across multiple calls to `factorial(..)`, the previous computations remain. But the `cache` variable is pretty obviously a *private* detail of how `factorial(..)` works, not something that should be exposed in an outer scope—especially not the global scope.\n\n| NOTE: |\n| :--- |\n| `factorial(..)` here is recursive—a call to itself is made from inside—but that's just for brevity of code sake; a non-recursive implementation would yield the same scoping analysis with respect to `cache`. |\n\nHowever, fixing this over-exposure issue is not as simple as hiding the `cache` variable inside `factorial(..)`, as it might seem. Since we need `cache` to survive multiple calls, it must be located in a scope outside that function. So what can we do?\n\nDefine another middle scope (between the outer/global scope and the inside of `factorial(..)`) for `cache` to be located:\n\n```js\n// outer/global scope\n\nfunction hideTheCache() {\n    // \"middle scope\", where we hide `cache`\n    var cache = {};\n\n    return factorial;\n\n    // **********************\n\n    function factorial(x) {\n        // inner scope\n        if (x < 2) return 1;\n        if (!(x in cache)) {\n            cache[x] = x * factorial(x - 1);\n        }\n        return cache[x];\n    }\n}\n\nvar factorial = hideTheCache();\n\nfactorial(6);\n// 720\n\nfactorial(7);\n// 5040\n```\n\nThe `hideTheCache()` function serves no other purpose than to create a scope for `cache` to persist in across multiple calls to `factorial(..)`. But for `factorial(..)` to have access to `cache`, we have to define `factorial(..)` inside that same scope. Then we return the function reference, as a value from `hideTheCache()`, and store it in an outer scope variable, also named `factorial`. Now as we call `factorial(..)` (multiple times!), its persistent `cache` stays hidden yet accessible only to `factorial(..)`!\n\nOK, but... it's going to be tedious to define (and name!) a `hideTheCache(..)` function scope each time such a need for variable/function hiding occurs, especially since we'll likely want to avoid name collisions with this function by giving each occurrence a unique name. Ugh.\n\n| NOTE: |\n| :--- |\n| The illustrated technique—caching a function's computed output to optimize performance when repeated calls of the same inputs are expected—is quite common in the Functional Programming (FP) world, canonically referred to as \"memoization\"; this caching relies on closure (see Chapter 7). Also, there are memory usage concerns (addressed in \"A Word About Memory\" in Appendix B). FP libraries will usually provide an optimized and vetted utility for memoization of functions, which would take the place of `hideTheCache(..)` here. Memoization is beyond the *scope* (pun intended!) of our discussion, but see my *Functional-Light JavaScript* book for more information. |\n\nRather than defining a new and uniquely named function each time one of those scope-only-for-the-purpose-of-hiding-a-variable situations occurs, a perhaps better solution is to use a function expression:\n\n```js\nvar factorial = (function hideTheCache() {\n    var cache = {};\n\n    function factorial(x) {\n        if (x < 2) return 1;\n        if (!(x in cache)) {\n            cache[x] = x * factorial(x - 1);\n        }\n        return cache[x];\n    }\n\n    return factorial;\n})();\n\nfactorial(6);\n// 720\n\nfactorial(7);\n// 5040\n```\n\nWait! This is still using a function to create the scope for hiding `cache`, and in this case, the function is still named `hideTheCache`, so how does that solve anything?\n\nRecall from \"Function Name Scope\" (in Chapter 3), what happens to the name identifier from a `function` expression. Since `hideTheCache(..)` is defined as a `function` expression instead of a `function` declaration, its name is in its own scope—essentially the same scope as `cache`—rather than in the outer/global scope.\n\nThat means we can name every single occurrence of such a function expression the exact same name, and never have any collision. More appropriately, we can name each occurrence semantically based on whatever it is we're trying to hide, and not worry that whatever name we choose is going to collide with any other `function` expression scope in the program.\n\nIn fact, we *could* just leave off the name entirely—thus defining an \"anonymous `function` expression\" instead. But Appendix A will discuss the importance of names even for such scope-only functions.\n\n### Invoking Function Expressions Immediately\n\nThere's another important bit in the previous factorial recursive program that's easy to miss: the line at the end of the `function` expression that contains `})();`.\n\nNotice that we surrounded the entire `function` expression in a set of `( .. )`, and then on the end, we added that second `()` parentheses set; that's actually calling the `function` expression we just defined. Moreover, in this case, the first set of surrounding `( .. )` around the function expression is not strictly necessary (more on that in a moment), but we used them for readability sake anyway.\n\nSo, in other words, we're defining a `function` expression that's then immediately invoked. This common pattern has a (very creative!) name: Immediately Invoked Function Expression (IIFE).\n\nAn IIFE is useful when we want to create a scope to hide variables/functions. Since it's an expression, it can be used in **any** place in a JS program where an expression is allowed. An IIFE can be named, as with `hideTheCache()`, or (much more commonly!) unnamed/anonymous. And it can be standalone or, as before, part of another statement—`hideTheCache()` returns the `factorial()` function reference which is then `=` assigned to the variable `factorial`.\n\nFor comparison, here's an example of a standalone IIFE:\n\n```js\n// outer scope\n\n(function(){\n    // inner hidden scope\n})();\n\n// more outer scope\n```\n\nUnlike earlier with `hideTheCache()`, where the outer surrounding `(..)` were noted as being an optional stylistic choice, for a standalone IIFE they're **required**; they distinguish the `function` as an expression, not a statement. For consistency, however, always surround an IIFE `function` with `( .. )`.\n\n| NOTE: |\n| :--- |\n| Technically, the surrounding `( .. )` aren't the only syntactic way to ensure the `function` in an IIFE is treated by the JS parser as a function expression. We'll look at some other options in Appendix A. |\n\n#### Function Boundaries\n\nBeware that using an IIFE to define a scope can have some unintended consequences, depending on the code around it. Because an IIFE is a full function, the function boundary alters the behavior of certain statements/constructs.\n\nFor example, a `return` statement in some piece of code would change its meaning if an IIFE is wrapped around it, because now the `return` would refer to the IIFE's function. Non-arrow function IIFEs also change the binding of a `this` keyword—more on that in the *Objects & Classes* book. And statements like `break` and `continue` won't operate across an IIFE function boundary to control an outer loop or block.\n\nSo, if the code you need to wrap a scope around has `return`, `this`, `break`, or `continue` in it, an IIFE is probably not the best approach. In that case, you might look to create the scope with a block instead of a function.\n\n## Scoping with Blocks\n\nYou should by this point feel fairly comfortable with the merits of creating scopes to limit identifier exposure.\n\nSo far, we looked at doing this via `function` (i.e., IIFE) scope. But let's now consider using `let` declarations with nested blocks. In general, any `{ .. }` curly-brace pair which is a statement will act as a block, but **not necessarily** as a scope.\n\nA block only becomes a scope if necessary, to contain its block-scoped declarations (i.e., `let` or `const`). Consider:\n\n```js\n{\n    // not necessarily a scope (yet)\n\n    // ..\n\n    // now we know the block needs to be a scope\n    let thisIsNowAScope = true;\n\n    for (let i = 0; i < 5; i++) {\n        // this is also a scope, activated each\n        // iteration\n        if (i % 2 == 0) {\n            // this is just a block, not a scope\n            console.log(i);\n        }\n    }\n}\n// 0 2 4\n```\n\nNot all `{ .. }` curly-brace pairs create blocks (and thus are eligible to become scopes):\n\n* Object literals use `{ .. }` curly-brace pairs to delimit their key-value lists, but such object values are **not** scopes.\n\n* `class` uses `{ .. }` curly-braces around its body definition, but this is not a block or scope.\n\n* A `function` uses `{ .. } ` around its body, but this is not technically a block—it's a single statement for the function body. It *is*, however, a (function) scope.\n\n* The `{ .. }` curly-brace pair on a `switch` statement (around the set of `case` clauses) does not define a block/scope.\n\nOther than such non-block examples, a `{ .. }` curly-brace pair can define a block attached to a statement (like an `if` or `for`), or stand alone by itself—see the outermost `{ .. }` curly brace pair in the previous snippet. An explicit block of this sort—if it has no declarations, it's not actually a scope—serves no operational purpose, though it can still be useful as a semantic signal.\n\nExplicit standalone `{ .. }` blocks have always been valid JS syntax, but since they couldn't be a scope prior to ES6's `let`/`const`, they are quite rare. However, post ES6, they're starting to catch on a little bit.\n\nIn most languages that support block scoping, an explicit block scope is an extremely common pattern for creating a narrow slice of scope for one or a few variables. So following the POLE principle, we should embrace this pattern more widespread in JS as well; use (explicit) block scoping to narrow the exposure of identifiers to the minimum practical.\n\nAn explicit block scope can be useful even inside of another block (whether the outer block is a scope or not).\n\nFor example:\n\n```js\nif (somethingHappened) {\n    // this is a block, but not a scope\n\n    {\n        // this is both a block and an\n        // explicit scope\n        let msg = somethingHappened.message();\n        notifyOthers(msg);\n    }\n\n    // ..\n\n    recoverFromSomething();\n}\n```\n\nHere, the `{ .. }` curly-brace pair **inside** the `if` statement is an even smaller inner explicit block scope for `msg`, since that variable is not needed for the entire `if` block. Most developers would just block-scope `msg` to the `if` block and move on. And to be fair, when there's only a few lines to consider, it's a toss-up judgement call. But as code grows, these over-exposure issues become more pronounced.\n\nSo does it matter enough to add the extra `{ .. }` pair and indentation level? I think you should follow POLE and always (within reason!) define the smallest block for each variable. So I recommend using the extra explicit block scope as shown.\n\nRecall the discussion of TDZ errors from \"Uninitialized Variables (TDZ)\" (Chapter 5). My suggestion there was: to minimize the risk of TDZ errors with `let`/`const` declarations, always put those declarations at the top of their scope.\n\nIf you find yourself placing a `let` declaration in the middle of a scope, first think, \"Oh, no! TDZ alert!\" If this `let` declaration isn't needed in the first half of that block, you should use an inner explicit block scope to further narrow its exposure!\n\nAnother example with an explicit block scope:\n\n```js\nfunction getNextMonthStart(dateStr) {\n    var nextMonth, year;\n\n    {\n        let curMonth;\n        [ , year, curMonth ] = dateStr.match(\n                /(\\d{4})-(\\d{2})-\\d{2}/\n            ) || [];\n        nextMonth = (Number(curMonth) % 12) + 1;\n    }\n\n    if (nextMonth == 1) {\n        year++;\n    }\n\n    return `${ year }-${\n            String(nextMonth).padStart(2,\"0\")\n        }-01`;\n}\ngetNextMonthStart(\"2019-12-25\");   // 2020-01-01\n```\n\nLet's first identify the scopes and their identifiers:\n\n1. The outer/global scope has one identifier, the function `getNextMonthStart(..)`.\n\n2. The function scope for `getNextMonthStart(..)` has three: `dateStr` (parameter), `nextMonth`, and `year`.\n\n3. The `{ .. }` curly-brace pair defines an inner block scope that includes one variable: `curMonth`.\n\nSo why put `curMonth` in an explicit block scope instead of just alongside `nextMonth` and `year` in the top-level function scope? Because `curMonth` is only needed for those first two statements; at the function scope level it's over-exposed.\n\nThis example is small, so the hazards of over-exposing `curMonth` are pretty limited. But the benefits of the POLE principle are best achieved when you adopt the mindset of minimizing scope exposure by default, as a habit. If you follow the principle consistently even in the small cases, it will serve you more as your programs grow.\n\nLet's now look at an even more substantial example:\n\n```js\nfunction sortNamesByLength(names) {\n    var buckets = [];\n\n    for (let firstName of names) {\n        if (buckets[firstName.length] == null) {\n            buckets[firstName.length] = [];\n        }\n        buckets[firstName.length].push(firstName);\n    }\n\n    // a block to narrow the scope\n    {\n        let sortedNames = [];\n\n        for (let bucket of buckets) {\n            if (bucket) {\n                // sort each bucket alphanumerically\n                bucket.sort();\n\n                // append the sorted names to our\n                // running list\n                sortedNames = [\n                    ...sortedNames,\n                    ...bucket\n                ];\n            }\n        }\n\n        return sortedNames;\n    }\n}\n\nsortNamesByLength([\n    \"Sally\",\n    \"Suzy\",\n    \"Frank\",\n    \"John\",\n    \"Jennifer\",\n    \"Scott\"\n]);\n// [ \"John\", \"Suzy\", \"Frank\", \"Sally\",\n//   \"Scott\", \"Jennifer\" ]\n```\n\nThere are six identifiers declared across five different scopes. Could all of these variables have existed in the single outer/global scope? Technically, yes, since they're all uniquely named and thus have no name collisions. But this would be really poor code organization, and would likely lead to both confusion and future bugs.\n\nWe split them out into each inner nested scope as appropriate. Each variable is defined at the innermost scope possible for the program to operate as desired.\n\n`sortedNames` could have been defined in the top-level function scope, but it's only needed for the second half of this function. To avoid over-exposing that variable in a higher level scope, we again follow POLE and block-scope it in the inner explicit block scope.\n\n### `var` *and* `let`\n\nNext, let's talk about the declaration `var buckets`. That variable is used across the entire function (except the final `return` statement). Any variable that is needed across all (or even most) of a function should be declared so that such usage is obvious.\n\n| NOTE: |\n| :--- |\n| The parameter `names` isn't used across the whole function, but there's no way limit the scope of a parameter, so it behaves as a function-wide declaration regardless. |\n\nSo why did we use `var` instead of `let` to declare the `buckets` variable? There's both semantic and technical reasons to choose `var` here.\n\nStylistically, `var` has always, from the earliest days of JS, signaled \"variable that belongs to a whole function.\" As we asserted in \"Lexical Scope\" (Chapter 1), `var` attaches to the nearest enclosing function scope, no matter where it appears. That's true even if `var` appears inside a block:\n\n```js\nfunction diff(x,y) {\n    if (x > y) {\n        var tmp = x;    // `tmp` is function-scoped\n        x = y;\n        y = tmp;\n    }\n\n    return y - x;\n}\n```\n\nEven though `var` is inside a block, its declaration is function-scoped (to `diff(..)`), not block-scoped.\n\nWhile you can declare `var` inside a block (and still have it be function-scoped), I would recommend against this approach except in a few specific cases (discussed in Appendix A). Otherwise, `var` should be reserved for use in the top-level scope of a function.\n\nWhy not just use `let` in that same location? Because `var` is visually distinct from `let` and therefore signals clearly, \"this variable is function-scoped.\" Using `let` in the top-level scope, especially if not in the first few lines of a function, and when all the other declarations in blocks use `let`, does not visually draw attention to the difference with the function-scoped declaration.\n\nIn other words, I feel `var` better communicates function-scoped than `let` does, and `let` both communicates (and achieves!) block-scoping where `var` is insufficient. As long as your programs are going to need both function-scoped and block-scoped variables, the most sensible and readable approach is to use both `var` *and* `let` together, each for their own best purpose.\n\nThere are other semantic and operational reasons to choose `var` or `let` in different scenarios. We'll explore the case for `var` *and* `let` in more detail in Appendix A.\n\n| WARNING: |\n| :--- |\n| My recommendation to use both `var` *and* `let` is clearly controversial and contradicts the majority. It's far more common to hear assertions like, \"var is broken, let fixes it\" and, \"never use var, let is the replacement.\" Those opinions are valid, but they're merely opinions, just like mine. `var` is not factually broken or deprecated; it has worked since early JS and it will continue to work as long as JS is around. |\n\n### Where To `let`?\n\nMy advice to reserve `var` for (mostly) only a top-level function scope means that most other declarations should use `let`. But you may still be wondering how to decide where each declaration in your program belongs?\n\nPOLE already guides you on those decisions, but let's make sure we explicitly state it. The way to decide is not based on which keyword you want to use. The way to decide is to ask, \"What is the most minimal scope exposure that's sufficient for this variable?\"\n\nOnce that is answered, you'll know if a variable belongs in a block scope or the function scope. If you decide initially that a variable should be block-scoped, and later realize it needs to be elevated to be function-scoped, then that dictates a change not only in the location of that variable's declaration, but also the declarator keyword used. The decision-making process really should proceed like that.\n\nIf a declaration belongs in a block scope, use `let`. If it belongs in the function scope, use `var` (again, just my opinion).\n\nBut another way to sort of visualize this decision making is to consider the pre-ES6 version of a program. For example, let's recall `diff(..)` from earlier:\n\n```js\nfunction diff(x,y) {\n    var tmp;\n\n    if (x > y) {\n        tmp = x;\n        x = y;\n        y = tmp;\n    }\n\n    return y - x;\n}\n```\n\nIn this version of `diff(..)`, `tmp` is clearly declared in the function scope. Is that appropriate for `tmp`? I would argue, no. `tmp` is only needed for those few statements. It's not needed for the `return` statement. It should therefore be block-scoped.\n\nPrior to ES6, we didn't have `let` so we couldn't *actually* block-scope it. But we could do the next-best thing in signaling our intent:\n\n```js\nfunction diff(x,y) {\n    if (x > y) {\n        // `tmp` is still function-scoped, but\n        // the placement here semantically\n        // signals block-scoping\n        var tmp = x;\n        x = y;\n        y = tmp;\n    }\n\n    return y - x;\n}\n```\n\nPlacing the `var` declaration for `tmp` inside the `if` statement signals to the reader of the code that `tmp` belongs to that block. Even though JS doesn't enforce that scoping, the semantic signal still has benefit for the reader of your code.\n\nFollowing this perspective, you can find any `var` that's inside a block of this sort and switch it to `let` to enforce the semantic signal already being sent. That's proper usage of `let` in my opinion.\n\nAnother example that was historically based on `var` but which should now pretty much always use `let` is the `for` loop:\n\n```js\nfor (var i = 0; i < 5; i++) {\n    // do something\n}\n```\n\nNo matter where such a loop is defined, the `i` should basically always be used only inside the loop, in which case POLE dictates it should be declared with `let` instead of `var`:\n\n```js\nfor (let i = 0; i < 5; i++) {\n    // do something\n}\n```\n\nAlmost the only case where switching a `var` to a `let` in this way would \"break\" your code is if you were relying on accessing the loop's iterator (`i`) outside/after the loop, such as:\n\n```js\nfor (var i = 0; i < 5; i++) {\n    if (checkValue(i)) {\n        break;\n    }\n}\n\nif (i < 5) {\n    console.log(\"The loop stopped early!\");\n}\n```\n\nThis usage pattern is not terribly uncommon, but most feel it smells like poor code structure. A preferable approach is to use another outer-scoped variable for that purpose:\n\n```js\nvar lastI;\n\nfor (let i = 0; i < 5; i++) {\n    lastI = i;\n    if (checkValue(i)) {\n        break;\n    }\n}\n\nif (lastI < 5) {\n    console.log(\"The loop stopped early!\");\n}\n```\n\n`lastI` is needed across this whole scope, so it's declared with `var`. `i` is only needed in (each) loop iteration, so it's declared with `let`.\n\n### What's the Catch?\n\nSo far we've asserted that `var` and parameters are function-scoped, and `let`/`const` signal block-scoped declarations. There's one little exception to call out: the `catch` clause.\n\nSince the introduction of `try..catch` back in ES3 (in 1999), the `catch` clause has used an additional (little-known) block-scoping declaration capability:\n\n```js\ntry {\n    doesntExist();\n}\ncatch (err) {\n    console.log(err);\n    // ReferenceError: 'doesntExist' is not defined\n    // ^^^^ message printed from the caught exception\n\n    let onlyHere = true;\n    var outerVariable = true;\n}\n\nconsole.log(outerVariable);     // true\n\nconsole.log(err);\n// ReferenceError: 'err' is not defined\n// ^^^^ this is another thrown (uncaught) exception\n```\n\nThe `err` variable declared by the `catch` clause is block-scoped to that block. This `catch` clause block can hold other block-scoped declarations via `let`. But a `var` declaration inside this block still attaches to the outer function/global scope.\n\nES2019 (recently, at the time of writing) changed `catch` clauses so their declaration is optional; if the declaration is omitted, the `catch` block is no longer (by default) a scope; it's still a block, though!\n\nSo if you need to react to the condition *that an exception occurred* (so you can gracefully recover), but you don't care about the error value itself, you can omit the `catch` declaration:\n\n```js\ntry {\n    doOptionOne();\n}\ncatch {   // catch-declaration omitted\n    doOptionTwoInstead();\n}\n```\n\nThis is a small but delightful simplification of syntax for a fairly common use case, and may also be slightly more performant in removing an unnecessary scope!\n\n## Function Declarations in Blocks (FiB)\n\nWe've seen now that declarations using `let` or `const` are block-scoped, and `var` declarations are function-scoped. So what about `function` declarations that appear directly inside blocks? As a feature, this is called \"FiB.\"\n\nWe typically think of `function` declarations like they're the equivalent of a `var` declaration. So are they function-scoped like `var` is?\n\nNo and yes. I know... that's confusing. Let's dig in:\n\n```js\nif (false) {\n    function ask() {\n        console.log(\"Does this run?\");\n    }\n}\nask();\n```\n\nWhat do you expect for this program to do? Three reasonable outcomes:\n\n1. The `ask()` call might fail with a `ReferenceError` exception, because the `ask` identifier is block-scoped to the `if` block scope and thus isn't available in the outer/global scope.\n\n2. The `ask()` call might fail with a `TypeError` exception, because the `ask` identifier exists, but it's `undefined` (since the `if` statement doesn't run) and thus not a callable function.\n\n3. The `ask()` call might run correctly, printing out the \"Does it run?\" message.\n\nHere's the confusing part: depending on which JS environment you try that code snippet in, you may get different results! This is one of those few crazy areas where existing legacy behavior betrays a predictable outcome.\n\nThe JS specification says that `function` declarations inside of blocks are block-scoped, so the answer should be (1). However, most browser-based JS engines (including v8, which comes from Chrome but is also used in Node) will behave as (2), meaning the identifier is scoped outside the `if` block but the function value is not automatically initialized, so it remains `undefined`.\n\nWhy are browser JS engines allowed to behave contrary to the specification? Because these engines already had certain behaviors around FiB before ES6 introduced block scoping, and there was concern that changing to adhere to the specification might break some existing website JS code. As such, an exception was made in Appendix B of the JS specification, which allows certain deviations for browser JS engines (only!).\n\n| NOTE: |\n| :--- |\n| You wouldn't typically categorize Node as a browser JS environment, since it usually runs on a server. But Node's v8 engine is shared with Chrome (and Edge) browsers. Since v8 is first a browser JS engine, it adopts this Appendix B exception, which then means that the browser exceptions are extended to Node. |\n\nOne of the most common use cases for placing a `function` declaration in a block is to conditionally define a function one way or another (like with an `if..else` statement) depending on some environment state. For example:\n\n```js\nif (typeof Array.isArray != \"undefined\") {\n    function isArray(a) {\n        return Array.isArray(a);\n    }\n}\nelse {\n    function isArray(a) {\n        return Object.prototype.toString.call(a)\n            == \"[object Array]\";\n    }\n}\n```\n\nIt's tempting to structure code this way for performance reasons, since the `typeof Array.isArray` check is only performed once, as opposed to defining just one `isArray(..)` and putting the `if` statement inside it—the check would then run unnecessarily on every call.\n\n| WARNING: |\n| :--- |\n| In addition to the risks of FiB deviations, another problem with conditional-definition of functions is it's harder to debug such a program. If you end up with a bug in the `isArray(..)` function, you first have to figure out *which* `isArray(..)` implementation is actually running! Sometimes, the bug is that the wrong one was applied because the conditional check was incorrect! If you define multiple versions of a function, that program is always harder to reason about and maintain. |\n\nIn addition to the previous snippets, several other FiB corner cases are lurking; such behaviors in various browsers and non-browser JS environments (JS engines that aren't browser based) will likely vary. For example:\n\n```js\nif (true) {\n    function ask() {\n        console.log(\"Am I called?\");\n    }\n}\n\nif (true) {\n    function ask() {\n        console.log(\"Or what about me?\");\n    }\n}\n\nfor (let i = 0; i < 5; i++) {\n    function ask() {\n        console.log(\"Or is it one of these?\");\n    }\n}\n\nask();\n\nfunction ask() {\n    console.log(\"Wait, maybe, it's this one?\");\n}\n```\n\nRecall that function hoisting as described in \"When Can I Use a Variable?\" (in Chapter 5) might suggest that the final `ask()` in this snippet, with \"Wait, maybe...\" as its message, would hoist above the call to `ask()`. Since it's the last function declaration of that name, it should \"win,\" right? Unfortunately, no.\n\nIt's not my intention to document all these weird corner cases, nor to try to explain why each of them behaves a certain way. That information is, in my opinion, arcane legacy trivia.\n\nMy real concern with FiB is, what advice can I give to ensure your code behaves predictably in all circumstances?\n\nAs far as I'm concerned, the only practical answer to avoiding the vagaries of FiB is to simply avoid FiB entirely. In other words, never place a `function` declaration directly inside any block. Always place `function` declarations anywhere in the top-level scope of a function (or in the global scope).\n\nSo for the earlier `if..else` example, my suggestion is to avoid conditionally defining functions if at all possible. Yes, it may be slightly less performant, but this is the better overall approach:\n\n```js\nfunction isArray(a) {\n    if (typeof Array.isArray != \"undefined\") {\n        return Array.isArray(a);\n    }\n    else {\n        return Object.prototype.toString.call(a)\n            == \"[object Array]\";\n    }\n}\n```\n\nIf that performance hit becomes a critical path issue for your application, I suggest you consider this approach:\n\n```js\nvar isArray = function isArray(a) {\n    return Array.isArray(a);\n};\n\n// override the definition, if you must\nif (typeof Array.isArray == \"undefined\") {\n    isArray = function isArray(a) {\n        return Object.prototype.toString.call(a)\n            == \"[object Array]\";\n    };\n}\n```\n\nIt's important to notice that here I'm placing a `function` **expression**, not a declaration, inside the `if` statement. That's perfectly fine and valid, for `function` expressions to appear inside blocks. Our discussion about FiB is about avoiding `function` **declarations** in blocks.\n\nEven if you test your program and it works correctly, the small benefit you may derive from using FiB style in your code is far outweighed by the potential risks in the future for confusion by other developers, or variances in how your code runs in other JS environments.\n\nFiB is not worth it, and should be avoided.\n\n## Blocked Over\n\nThe point of lexical scoping rules in a programming language is so we can appropriately organize our program's variables, both for operational as well as semantic code communication purposes.\n\nAnd one of the most important organizational techniques is to ensure that no variable is over-exposed to unnecessary scopes (POLE). Hopefully you now appreciate block scoping much more deeply than before.\n\nHopefully by now you feel like you're standing on much more solid ground with understanding lexical scope. From that base, the next chapter jumps into the weighty topic of closure.\n\n[^POLP]: *Principle of Least Privilege*, https://en.wikipedia.org/wiki/Principle_of_least_privilege, 3 March 2020.\n"
  },
  {
    "path": "scope-closures/ch7.md",
    "content": "# You Don't Know JS Yet: Scope & Closures - 2nd Edition\n# Chapter 7: Using Closures\n\nUp to this point, we've focused on the ins and outs of lexical scope, and how that affects the organization and usage of variables in our programs.\n\nOur attention again shifts broader in abstraction, to the historically somewhat daunting topic of closure. Don't worry! You don't need an advanced computer science degree to make sense of it. Our broad goal in this book is not merely to understand scope, but to more effectively use it in the structure of our programs; closure is central to that effort.\n\nRecall the main conclusion of Chapter 6: the *least exposure* principle (POLE) encourages us to use block (and function) scoping to limit the scope exposure of variables. This helps keep code understandable and maintainable, and helps avoid many scoping pitfalls (i.e., name collision, etc.).\n\nClosure builds on this approach: for variables we need to use over time, instead of placing them in larger outer scopes, we can encapsulate (more narrowly scope) them but still preserve access from inside functions, for broader use. Functions *remember* these referenced scoped variables via closure.\n\nWe already saw an example of this kind of closure in the previous chapter (`factorial(..)` in Chapter 6), and you've almost certainly already used it in your own programs. If you've ever written a callback that accesses variables outside its own scope... guess what!? That's closure.\n\nClosure is one of the most important language characteristics ever invented in programming—it underlies major programming paradigms, including Functional Programming (FP), modules, and even a bit of class-oriented design. Getting comfortable with closure is required for mastering JS and effectively leveraging many important design patterns throughout your code.\n\nAddressing all aspects of closure requires a daunting mountain of discussion and code throughout this chapter. Make sure to take your time and ensure you're comfortable with each bit before moving onto the next.\n\n## See the Closure\n\nClosure is originally a mathematical concept, from lambda calculus. But I'm not going to list out math formulas or use a bunch of notation and jargon to define it.\n\nInstead, I'm going to focus on a practical perspective. We'll start by defining closure in terms of what we can observe in different behavior of our programs, as opposed to if closure was not present in JS. However, later in this chapter, we're going to flip closure around to look at it from an *alternative perspective*.\n\nClosure is a behavior of functions and only functions. If you aren't dealing with a function, closure does not apply. An object cannot have closure, nor does a class have closure (though its functions/methods might). Only functions have closure.\n\nFor closure to be observed, a function must be invoked, and specifically it must be invoked in a different branch of the scope chain from where it was originally defined. A function executing in the same scope it was defined would not exhibit any observably different behavior with or without closure being possible; by the observational perspective and definition, that is not closure.\n\nLet's look at some code, annotated with its relevant scope bubble colors (see Chapter 2):\n\n```js\n// outer/global scope: RED(1)\n\nfunction lookupStudent(studentID) {\n    // function scope: BLUE(2)\n\n    var students = [\n        { id: 14, name: \"Kyle\" },\n        { id: 73, name: \"Suzy\" },\n        { id: 112, name: \"Frank\" },\n        { id: 6, name: \"Sarah\" }\n    ];\n\n    return function greetStudent(greeting){\n        // function scope: GREEN(3)\n\n        var student = students.find(\n            student => student.id == studentID\n        );\n\n        return `${ greeting }, ${ student.name }!`;\n    };\n}\n\nvar chosenStudents = [\n    lookupStudent(6),\n    lookupStudent(112)\n];\n\n// accessing the function's name:\nchosenStudents[0].name;\n// greetStudent\n\nchosenStudents[0](\"Hello\");\n// Hello, Sarah!\n\nchosenStudents[1](\"Howdy\");\n// Howdy, Frank!\n```\n\nThe first thing to notice about this code is that the `lookupStudent(..)` outer function creates and returns an inner function called `greetStudent(..)`. `lookupStudent(..)` is called twice, producing two separate instances of its inner `greetStudent(..)` function, both of which are saved into the `chosenStudents` array.\n\nWe verify that's the case by checking the `.name` property of the returned function saved in `chosenStudents[0]`, and it's indeed an instance of the inner `greetStudent(..)`.\n\nAfter each call to `lookupStudent(..)` finishes, it would seem like all its inner variables would be discarded and GC'd (garbage collected). The inner function is the only thing that seems to be returned and preserved. But here's where the behavior differs in ways we can start to observe.\n\nWhile `greetStudent(..)` does receive a single argument as the parameter named `greeting`, it also makes reference to both `students` and `studentID`, identifiers which come from the enclosing scope of `lookupStudent(..)`. Each of those references from the inner function to the variable in an outer scope is called a *closure*. In academic terms, each instance of `greetStudent(..)` *closes over* the outer variables `students` and `studentID`.\n\nSo what do those closures do here, in a concrete, observable sense?\n\nClosure allows `greetStudent(..)` to continue to access those outer variables even after the outer scope is finished (when each call to `lookupStudent(..)` completes). Instead of the instances of `students` and `studentID` being GC'd, they stay around in memory. At a later time when either instance of the `greetStudent(..)` function is invoked, those variables are still there, holding their current values.\n\nIf JS functions did not have closure, the completion of each `lookupStudent(..)` call would immediately tear down its scope and GC the `students` and `studentID` variables. When we later called one of the `greetStudent(..)` functions, what would then happen?\n\nIf `greetStudent(..)` tried to access what it thought was a BLUE(2) marble, but that marble did not actually exist (anymore), the reasonable assumption is we should get a `ReferenceError`, right?\n\nBut we don't get an error. The fact that the execution of `chosenStudents[0](\"Hello\")` works and returns us the message \"Hello, Sarah!\", means it was still able to access the `students` and `studentID` variables. This is a direct observation of closure!\n\n### Pointed Closure\n\nActually, we glossed over a little detail in the previous discussion which I'm guessing many readers missed!\n\nBecause of how terse the syntax for `=>` arrow functions is, it's easy to forget that they still create a scope (as asserted in \"Arrow Functions\" in Chapter 3). The `student => student.id == studentID` arrow function is creating another scope bubble inside the `greetStudent(..)` function scope.\n\nBuilding on the metaphor of colored buckets and bubbles from Chapter 2, if we were creating a colored diagram for this code, there's a fourth scope at this innermost nesting level, so we'd need a fourth color; perhaps we'd pick ORANGE(4) for that scope:\n\n```js\nvar student = students.find(\n    student =>\n        // function scope: ORANGE(4)\n        student.id == studentID\n);\n```\n\nThe BLUE(2) `studentID` reference is actually inside the ORANGE(4) scope rather than the GREEN(3) scope of `greetStudent(..)`; also, the `student` parameter of the arrow function is ORANGE(4), shadowing the GREEN(3) `student`.\n\nThe consequence here is that this arrow function passed as a callback to the array's `find(..)` method has to hold the closure over `studentID`, rather than `greetStudent(..)` holding that closure. That's not too big of a deal, as everything still works as expected. It's just important not to skip over the fact that even tiny arrow functions can get in on the closure party.\n\n### Adding Up Closures\n\nLet's examine one of the canonical examples often cited for closure:\n\n```js\nfunction adder(num1) {\n    return function addTo(num2){\n        return num1 + num2;\n    };\n}\n\nvar add10To = adder(10);\nvar add42To = adder(42);\n\nadd10To(15);    // 25\nadd42To(9);     // 51\n```\n\nEach instance of the inner `addTo(..)` function is closing over its own `num1` variable (with values `10` and `42`, respectively), so those `num1`'s don't go away just because `adder(..)` finishes. When we later invoke one of those inner `addTo(..)` instances, such as the `add10To(15)` call, its closed-over `num1` variable still exists and still holds the original `10` value. The operation is thus able to perform `10 + 15` and return the answer `25`.\n\nAn important detail might have been too easy to gloss over in that previous paragraph, so let's reinforce it: closure is associated with an instance of a function, rather than its single lexical definition. In the preceding snippet, there's just one inner `addTo(..)` function defined inside `adder(..)`, so it might seem like that would imply a single closure.\n\nBut actually, every time the outer `adder(..)` function runs, a *new* inner `addTo(..)` function instance is created, and for each new instance, a new closure. So each inner function instance (labeled `add10To(..)` and `add42To(..)` in our program) has its own closure over its own instance of the scope environment from that execution of `adder(..)`.\n\nEven though closure is based on lexical scope, which is handled at compile time, closure is observed as a runtime characteristic of function instances.\n\n### Live Link, Not a Snapshot\n\nIn both examples from the previous sections, we **read the value from a variable** that was held in a closure. That makes it feel like closure might be a snapshot of a value at some given moment. Indeed, that's a common misconception.\n\nClosure is actually a live link, preserving access to the full variable itself. We're not limited to merely reading a value; the closed-over variable can be updated (re-assigned) as well! By closing over a variable in a function, we can keep using that variable (read and write) as long as that function reference exists in the program, and from anywhere we want to invoke that function. This is why closure is such a powerful technique used widely across so many areas of programming!\n\nFigure 4 depicts the function instances and scope links:\n\n<figure>\n    <img src=\"images/fig4.png\" width=\"400\" alt=\"Function instances linked to scopes via closure\" align=\"center\">\n    <figcaption><em>Fig. 4: Visualizing Closures</em></figcaption>\n    <br><br>\n</figure>\n\nAs shown in Figure 4, each call to `adder(..)` creates a new BLUE(2) scope containing a `num1` variable, as well as a new instance of `addTo(..)` function as a GREEN(3) scope. Notice that the function instances (`addTo10(..)` and `addTo42(..)`) are present in and invoked from the RED(1) scope.\n\nNow let's examine an example where the closed-over variable is updated:\n\n```js\nfunction makeCounter() {\n    var count = 0;\n\n    return function getCurrent() {\n        count = count + 1;\n        return count;\n    };\n}\n\nvar hits = makeCounter();\n\n// later\n\nhits();     // 1\n\n// later\n\nhits();     // 2\nhits();     // 3\n```\n\nThe `count` variable is closed over by the inner `getCurrent()` function, which keeps it around instead of it being subjected to GC. The `hits()` function calls access *and* update this variable, returning an incrementing count each time.\n\nThough the enclosing scope of a closure is typically from a function, that's not actually required; there only needs to be an inner function present inside an outer scope:\n\n```js\nvar hits;\n{   // an outer scope (but not a function)\n    let count = 0;\n    hits = function getCurrent(){\n        count = count + 1;\n        return count;\n    };\n}\nhits();     // 1\nhits();     // 2\nhits();     // 3\n```\n\n| NOTE: |\n| :--- |\n| I deliberately defined `getCurrent()` as a `function` expression instead of a `function` declaration. This isn't about closure, but with the dangerous quirks of FiB (Chapter 6). |\n\nBecause it's so common to mistake closure as value-oriented instead of variable-oriented, developers sometimes get tripped up trying to use closure to snapshot-preserve a value from some moment in time. Consider:\n\n```js\nvar studentName = \"Frank\";\n\nvar greeting = function hello() {\n    // we are closing over `studentName`,\n    // not \"Frank\"\n    console.log(\n        `Hello, ${ studentName }!`\n    );\n}\n\n// later\n\nstudentName = \"Suzy\";\n\n// later\n\ngreeting();\n// Hello, Suzy!\n```\n\nBy defining `greeting()` (aka, `hello()`) when `studentName` holds the value `\"Frank\"` (before the re-assignment to `\"Suzy\"`), the mistaken assumption is often that the closure will capture `\"Frank\"`. But `greeting()` is closed over the variable `studentName`, not its value. Whenever `greeting()` is invoked, the current value of the variable (`\"Suzy\"`, in this case) is reflected.\n\nThe classic illustration of this mistake is defining functions inside a loop:\n\n```js\nvar keeps = [];\n\nfor (var i = 0; i < 3; i++) {\n    keeps[i] = function keepI(){\n        // closure over `i`\n        return i;\n    };\n}\n\nkeeps[0]();   // 3 -- WHY!?\nkeeps[1]();   // 3\nkeeps[2]();   // 3\n```\n\n| NOTE: |\n| :--- |\n| This kind of closure illustration typically uses a `setTimeout(..)` or some other callback like an event handler, inside the loop. I've simplified the example by storing function references in an array, so that we don't need to consider asynchronous timing in our analysis. The closure principle is the same, regardless. |\n\nYou might have expected the `keeps[0]()` invocation to return `0`, since that function was created during the first iteration of the loop when `i` was `0`. But again, that assumption stems from thinking of closure as value-oriented rather than variable-oriented.\n\nSomething about the structure of a `for`-loop can trick us into thinking that each iteration gets its own new `i` variable; in fact, this program only has one `i` since it was declared with `var`.\n\nEach saved function returns `3`, because by the end of the loop, the single `i` variable in the program has been assigned `3`. Each of the three functions in the `keeps` array do have individual closures, but they're all closed over that same shared `i` variable.\n\nOf course, a single variable can only ever hold one value at any given moment. So if you want to preserve multiple values, you need a different variable for each.\n\nHow could we do that in the loop snippet? Let's create a new variable for each iteration:\n\n```js\nvar keeps = [];\n\nfor (var i = 0; i < 3; i++) {\n    // new `j` created each iteration, which gets\n    // a copy of the value of `i` at this moment\n    let j = i;\n\n    // the `i` here isn't being closed over, so\n    // it's fine to immediately use its current\n    // value in each loop iteration\n    keeps[i] = function keepEachJ(){\n        // close over `j`, not `i`!\n        return j;\n    };\n}\nkeeps[0]();   // 0\nkeeps[1]();   // 1\nkeeps[2]();   // 2\n```\n\nEach function is now closed over a separate (new) variable from each iteration, even though all of them are named `j`. And each `j` gets a copy of the value of `i` at that point in the loop iteration; that `j` never gets re-assigned. So all three functions now return their expected values: `0`, `1`, and `2`!\n\nAgain remember, even if we were using asynchrony in this program, such as passing each inner `keepEachJ()` function into `setTimeout(..)` or some event handler subscription, the same kind of closure behavior would still be observed.\n\nRecall the \"Loops\" section in Chapter 5, which illustrates how a `let` declaration in a `for` loop actually creates not just one variable for the loop, but actually creates a new variable for *each iteration* of the loop. That trick/quirk is exactly what we need for our loop closures:\n\n```js\nvar keeps = [];\n\nfor (let i = 0; i < 3; i++) {\n    // the `let i` gives us a new `i` for\n    // each iteration, automatically!\n    keeps[i] = function keepEachI(){\n        return i;\n    };\n}\nkeeps[0]();   // 0\nkeeps[1]();   // 1\nkeeps[2]();   // 2\n```\n\nSince we're using `let`, three `i`'s are created, one for each loop, so each of the three closures *just work* as expected.\n\n### Common Closures: Ajax and Events\n\nClosure is most commonly encountered with callbacks:\n\n```js\nfunction lookupStudentRecord(studentID) {\n    ajax(\n        `https://some.api/student/${ studentID }`,\n        function onRecord(record) {\n            console.log(\n                `${ record.name } (${ studentID })`\n            );\n        }\n    );\n}\n\nlookupStudentRecord(114);\n// Frank (114)\n```\n\nThe `onRecord(..)` callback is going to be invoked at some point in the future, after the response from the Ajax call comes back. This invocation will happen from the internals of the `ajax(..)` utility, wherever that comes from. Furthermore, when that happens, the `lookupStudentRecord(..)` call will long since have completed.\n\nWhy then is `studentID` still around and accessible to the callback? Closure.\n\nEvent handlers are another common usage of closure:\n\n```js\nfunction listenForClicks(btn,label) {\n    btn.addEventListener(\"click\",function onClick(){\n        console.log(\n            `The ${ label } button was clicked!`\n        );\n    });\n}\n\nvar submitBtn = document.getElementById(\"submit-btn\");\n\nlistenForClicks(submitBtn,\"Checkout\");\n```\n\nThe `label` parameter is closed over by the `onClick(..)` event handler callback. When the button is clicked, `label` still exists to be used. This is closure.\n\n### What If I Can't See It?\n\nYou've probably heard this common adage:\n\n> If a tree falls in the forest but nobody is around to hear it, does it make a sound?\n\nIt's a silly bit of philosophical gymnastics. Of course from a scientific perspective, sound waves are created. But the real point: *does it matter* if the sound happens?\n\nRemember, the emphasis in our definition of closure is observability. If a closure exists (in a technical, implementation, or academic sense) but it cannot be observed in our programs, *does it matter?* No.\n\nTo reinforce this point, let's look at some examples that are *not* observably based on closure.\n\nFor example, invoking a function that makes use of lexical scope lookup:\n\n```js\nfunction say(myName) {\n    var greeting = \"Hello\";\n    output();\n\n    function output() {\n        console.log(\n            `${ greeting }, ${ myName }!`\n        );\n    }\n}\n\nsay(\"Kyle\");\n// Hello, Kyle!\n```\n\nThe inner function `output()` accesses the variables `greeting` and `myName` from its enclosing scope. But the invocation of `output()` happens in that same scope, where of course `greeting` and `myName` are still available; that's just lexical scope, not closure.\n\nAny lexically scoped language whose functions didn't support closure would still behave this same way.\n\nIn fact, global scope variables essentially cannot be (observably) closed over, because they're always accessible from everywhere. No function can ever be invoked in any part of the scope chain that is not a descendant of the global scope.\n\nConsider:\n\n```js\nvar students = [\n    { id: 14, name: \"Kyle\" },\n    { id: 73, name: \"Suzy\" },\n    { id: 112, name: \"Frank\" },\n    { id: 6, name: \"Sarah\" }\n];\n\nfunction getFirstStudent() {\n    return function firstStudent(){\n        return students[0].name;\n    };\n}\n\nvar student = getFirstStudent();\n\nstudent();\n// Kyle\n```\n\nThe inner `firstStudent()` function does reference `students`, which is a variable outside its own scope. But since `students` happens to be from the global scope, no matter where that function is invoked in the program, its ability to access `students` is nothing more special than normal lexical scope.\n\nAll function invocations can access global variables, regardless of whether closure is supported by the language or not. Global variables don't need to be closed over.\n\nVariables that are merely present but never accessed don't result in closure:\n\n```js\nfunction lookupStudent(studentID) {\n    return function nobody(){\n        var msg = \"Nobody's here yet.\";\n        console.log(msg);\n    };\n}\n\nvar student = lookupStudent(112);\n\nstudent();\n// Nobody's here yet.\n```\n\nThe inner function `nobody()` doesn't close over any outer variables—it only uses its own variable `msg`. Even though `studentID` is present in the enclosing scope, `studentID` is not referred to by `nobody()`. The JS engine doesn't need to keep `studentID` around after `lookupStudent(..)` has finished running, so GC wants to clean up that memory!\n\nWhether JS functions support closure or not, this program would behave the same. Therefore, no observed closure here.\n\nIf there's no function invocation, closure can't be observed:\n\n```js\nfunction greetStudent(studentName) {\n    return function greeting(){\n        console.log(\n            `Hello, ${ studentName }!`\n        );\n    };\n}\n\ngreetStudent(\"Kyle\");\n\n// nothing else happens\n```\n\nThis one's tricky, because the outer function definitely does get invoked. But the inner function is the one that *could* have had closure, and yet it's never invoked; the returned function here is just thrown away. So even if technically the JS engine created closure for a brief moment, it was not observed in any meaningful way in this program.\n\nA tree may have fallen... but we didn't hear it, so we don't care.\n\n### Observable Definition\n\nWe're now ready to define closure:\n\n> Closure is observed when a function uses variable(s) from outer scope(s) even while running in a scope where those variable(s) wouldn't be accessible.\n\nThe key parts of this definition are:\n\n* Must be a function involved\n\n* Must reference at least one variable from an outer scope\n\n* Must be invoked in a different branch of the scope chain from the variable(s)\n\nThis observation-oriented definition means we shouldn't dismiss closure as some indirect, academic trivia. Instead, we should look and plan for the direct, concrete effects closure has on our program behavior.\n\n## The Closure Lifecycle and Garbage Collection (GC)\n\nSince closure is inherently tied to a function instance, its closure over a variable lasts as long as there is still a reference to that function.\n\nIf ten functions all close over the same variable, and over time nine of these function references are discarded, the lone remaining function reference still preserves that variable. Once that final function reference is discarded, the last closure over that variable is gone, and the variable itself is GC'd.\n\nThis has an important impact on building efficient and performant programs. Closure can unexpectedly prevent the GC of a variable that you're otherwise done with, which leads to run-away memory usage over time. That's why it's important to discard function references (and thus their closures) when they're not needed anymore.\n\nConsider:\n\n```js\nfunction manageBtnClickEvents(btn) {\n    var clickHandlers = [];\n\n    return function listener(cb){\n        if (cb) {\n            let clickHandler =\n                function onClick(evt){\n                    console.log(\"clicked!\");\n                    cb(evt);\n                };\n            clickHandlers.push(clickHandler);\n            btn.addEventListener(\n                \"click\",\n                clickHandler\n            );\n        }\n        else {\n            // passing no callback unsubscribes\n            // all click handlers\n            for (let handler of clickHandlers) {\n                btn.removeEventListener(\n                    \"click\",\n                    handler\n                );\n            }\n\n            clickHandlers = [];\n        }\n    };\n}\n\n// var mySubmitBtn = ..\nvar onSubmit = manageBtnClickEvents(mySubmitBtn);\n\nonSubmit(function checkout(evt){\n    // handle checkout\n});\n\nonSubmit(function trackAction(evt){\n    // log action to analytics\n});\n\n// later, unsubscribe all handlers:\nonSubmit();\n```\n\nIn this program, the inner `onClick(..)` function holds a closure over the passed in `cb` (the provided event callback). That means the `checkout()` and `trackAction()` function expression references are held via closure (and cannot be GC'd) for as long as these event handlers are subscribed.\n\nWhen we call `onSubmit()` with no input on the last line, all event handlers are unsubscribed, and the `clickHandlers` array is emptied. Once all click handler function references are discarded, the closures of `cb` references to `checkout()` and `trackAction()` are discarded.\n\nWhen considering the overall health and efficiency of the program, unsubscribing an event handler when it's no longer needed can be even more important than the initial subscription!\n\n### Per Variable or Per Scope?\n\nAnother question we need to tackle: should we think of closure as applied only to the referenced outer variable(s), or does closure preserve the entire scope chain with all its variables?\n\nIn other words, in the previous event subscription snippet, is the inner `onClick(..)` function closed over only `cb`, or is it also closed over `clickHandler`, `clickHandlers`, and `btn`?\n\nConceptually, closure is **per variable** rather than *per scope*. Ajax callbacks, event handlers, and all other forms of function closures are typically assumed to close over only what they explicitly reference.\n\nBut the reality is more complicated than that.\n\nAnother program to consider:\n\n```js\nfunction manageStudentGrades(studentRecords) {\n    var grades = studentRecords.map(getGrade);\n\n    return addGrade;\n\n    // ************************\n\n    function getGrade(record){\n        return record.grade;\n    }\n\n    function sortAndTrimGradesList() {\n        // sort by grades, descending\n        grades.sort(function desc(g1,g2){\n            return g2 - g1;\n        });\n\n        // only keep the top 10 grades\n        grades = grades.slice(0,10);\n    }\n\n    function addGrade(newGrade) {\n        grades.push(newGrade);\n        sortAndTrimGradesList();\n        return grades;\n    }\n}\n\nvar addNextGrade = manageStudentGrades([\n    { id: 14, name: \"Kyle\", grade: 86 },\n    { id: 73, name: \"Suzy\", grade: 87 },\n    { id: 112, name: \"Frank\", grade: 75 },\n    // ..many more records..\n    { id: 6, name: \"Sarah\", grade: 91 }\n]);\n\n// later\n\naddNextGrade(81);\naddNextGrade(68);\n// [ .., .., ... ]\n```\n\nThe outer function `manageStudentGrades(..)` takes a list of student records, and returns an `addGrade(..)` function reference, which we externally label `addNextGrade(..)`. Each time we call `addNextGrade(..)` with a new grade, we get back a current list of the top 10 grades, sorted numerically descending (see `sortAndTrimGradesList()`).\n\nFrom the end of the original `manageStudentGrades(..)` call, and between the multiple `addNextGrade(..)` calls, the `grades` variable is preserved inside `addGrade(..)` via closure; that's how the running list of top grades is maintained. Remember, it's a closure over the variable `grades` itself, not the array it holds.\n\nThat's not the only closure involved, however. Can you spot other variables being closed over?\n\nDid you spot that `addGrade(..)` references `sortAndTrimGradesList`? That means it's also closed over that identifier, which happens to hold a reference to the `sortAndTrimGradesList()` function. That second inner function has to stay around so that `addGrade(..)` can keep calling it, which also means any variables *it* closes over stick around—though, in this case, nothing extra is closed over there.\n\nWhat else is closed over?\n\nConsider the `getGrade` variable (and its function); is it closed over? It's referenced in the outer scope of `manageStudentGrades(..)` in the `.map(getGrade)` call. But it's not referenced in `addGrade(..)` or `sortAndTrimGradesList()`.\n\nWhat about the (potentially) large list of student records we pass in as `studentRecords`? Is that variable closed over? If it is, the array of student records is never getting GC'd, which leads to this program holding onto a larger amount of memory than we might assume. But if we look closely again, none of the inner functions reference `studentRecords`.\n\nAccording to the *per variable* definition of closure, since `getGrade` and `studentRecords` are *not* referenced by the inner functions, they're not closed over. They should be freely available for GC right after the `manageStudentGrades(..)` call completes.\n\nIndeed, try debugging this code in a recent JS engine, like v8 in Chrome, placing a breakpoint inside the `addGrade(..)` function. You may notice that the inspector **does not** list the `studentRecords` variable. That's proof, debugging-wise anyway, that the engine does not maintain `studentRecords` via closure. Phew!\n\nBut how reliable is this observation as proof? Consider this (rather contrived!) program:\n\n```js\nfunction storeStudentInfo(id,name,grade) {\n    return function getInfo(whichValue){\n        // warning:\n        //   using `eval(..)` is a bad idea!\n        var val = eval(whichValue);\n        return val;\n    };\n}\n\nvar info = storeStudentInfo(73,\"Suzy\",87);\n\ninfo(\"name\");\n// Suzy\n\ninfo(\"grade\");\n// 87\n```\n\nNotice that the inner function `getInfo(..)` is not explicitly closed over any of `id`, `name`, or `grade` variables. And yet, calls to `info(..)` seem to still be able to access the variables, albeit through use of the `eval(..)` lexical scope cheat (see Chapter 1).\n\nSo all the variables were definitely preserved via closure, despite not being explicitly referenced by the inner function. So does that disprove the *per variable* assertion in favor of *per scope*? Depends.\n\nMany modern JS engines do apply an *optimization* that removes any variables from a closure scope that aren't explicitly referenced. However, as we see with `eval(..)`, there are situations where such an optimization cannot be applied, and the closure scope continues to contain all its original variables. In other words, closure must be *per scope*, implementation wise, and then an optional optimization trims down the scope to only what was closed over (a similar outcome as *per variable* closure).\n\nEven as recent as a few years ago, many JS engines did not apply this optimization; it's possible your websites may still run in such browsers, especially on older or lower-end devices. That means it's possible that long-lived closures such as event handlers may be holding onto memory much longer than we would have assumed.\n\nAnd the fact that it's an optional optimization in the first place, rather than a requirement of the specification, means that we shouldn't just casually over-assume its applicability.\n\nIn cases where a variable holds a large value (like an object or array) and that variable is present in a closure scope, if you don't need that value anymore and don't want that memory held, it's safer (memory usage) to manually discard the value rather than relying on closure optimization/GC.\n\nLet's apply a *fix* to the earlier `manageStudentGrades(..)` example to ensure the potentially large array held in `studentRecords` is not caught up in a closure scope unnecessarily:\n\n```js\nfunction manageStudentGrades(studentRecords) {\n    var grades = studentRecords.map(getGrade);\n\n    // unset `studentRecords` to prevent unwanted\n    // memory retention in the closure\n    studentRecords = null;\n\n    return addGrade;\n    // ..\n}\n```\n\nWe're not removing `studentRecords` from the closure scope; that we cannot control. We're ensuring that even if `studentRecords` remains in the closure scope, that variable is no longer referencing the potentially large array of data; the array can be GC'd.\n\nAgain, in many cases JS might automatically optimize the program to the same effect. But it's still a good habit to be careful and explicitly make sure we don't keep any significant amount of device memory tied up any longer than necessary.\n\nAs a matter of fact, we also technically don't need the function `getGrade()` anymore after the `.map(getGrade)` call completes. If profiling our application showed this was a critical area of excess memory use, we could possibly eek out a tiny bit more memory by freeing up that reference so its value isn't tied up either. That's likely unnecessary in this toy example, but this is a general technique to keep in mind if you're optimizing the memory footprint of your application.\n\nThe takeaway: it's important to know where closures appear in our programs, and what variables are included. We should manage these closures carefully so we're only holding onto what's minimally needed and not wasting memory.\n\n## An Alternative Perspective\n\nReviewing our working definition for closure, the assertion is that functions are \"first-class values\" that can be passed around the program, just like any other value. Closure is the link-association that connects that function to the scope/variables outside of itself, no matter where that function goes.\n\nLet's recall a code example from earlier in this chapter, again with relevant scope bubble colors annotated:\n\n```js\n// outer/global scope: RED(1)\n\nfunction adder(num1) {\n    // function scope: BLUE(2)\n\n    return function addTo(num2){\n        // function scope: GREEN(3)\n\n        return num1 + num2;\n    };\n}\n\nvar add10To = adder(10);\nvar add42To = adder(42);\n\nadd10To(15);    // 25\nadd42To(9);     // 51\n```\n\nOur current perspective suggests that wherever a function is passed and invoked, closure preserves a hidden link back to the original scope to facilitate the access to the closed-over variables. Figure 4, repeated here for convenience, illustrates this notion:\n\n<figure>\n    <img src=\"images/fig4.png\" width=\"400\" alt=\"Function instances linked to scopes via closure\" align=\"center\">\n    <figcaption><em>Fig. 4 (repeat): Visualizing Closures</em></figcaption>\n    <br><br>\n</figure>\n\nBut there's another way of thinking about closure, and more precisely the nature of functions being *passed around*, that may help deepen the mental models.\n\nThis alternative model de-emphasizes \"functions as first-class values,\" and instead embraces how functions (like all non-primitive values) are held by reference in JS, and assigned/passed by reference-copy—see Appendix A of the *Get Started* book for more information.\n\nInstead of thinking about the inner function instance of `addTo(..)` moving to the outer RED(1) scope via the `return` and assignment, we can envision that function instances actually just stay in place in their own scope environment, of course with their scope-chain intact.\n\nWhat gets *sent* to the RED(1) scope is **just a reference** to the in-place function instance, rather than the function instance itself. Figure 5 depicts the inner function instances remaining in place, pointed to by the RED(1) `addTo10` and `addTo42` references, respectively:\n\n<figure>\n    <img src=\"images/fig5.png\" width=\"400\" alt=\"Function instances inside scopes via closure, linked to by references\" align=\"center\">\n    <figcaption><em>Fig. 5: Visualizing Closures (Alternative)</em></figcaption>\n    <br><br>\n</figure>\n\nAs shown in Figure 5, each call to `adder(..)` still creates a new BLUE(2) scope containing a `num1` variable, as well as an instance of the GREEN(3) `addTo(..)` scope. But what's different from Figure 4 is, now these GREEN(3) instances remain in place, naturally nested inside of their BLUE(2) scope instances. The `addTo10` and `addTo42` references are moved to the RED(1) outer scope, not the function instances themselves.\n\nWhen `addTo10(15)` is called, the `addTo(..)` function instance (still in place in its original BLUE(2) scope environment) is invoked. Since the function instance itself never moved, of course it still has natural access to its scope chain. Same with the `addTo42(9)` call—nothing special here beyond lexical scope.\n\nSo what then *is* closure, if not the *magic* that lets a function maintain a link to its original scope chain even as that function moves around in other scopes? In this alternative model, functions stay in place and keep accessing their original scope chain just like they always could.\n\nClosure instead describes the *magic* of **keeping alive a function instance**, along with its whole scope environment and chain, for as long as there's at least one reference to that function instance floating around in any other part of the program.\n\nThat definition of closure is less observational and a bit less familiar-sounding compared to the traditional academic perspective. But it's nonetheless still useful, because the benefit is that we simplify explanation of closure to a straightforward combination of references and in-place function instances.\n\nThe previous model (Figure 4) is not *wrong* at describing closure in JS. It's just more conceptually inspired, an academic perspective on closure. By contrast, the alternative model (Figure 5) could be described as a bit more implementation focused, how JS actually works.\n\nBoth perspectives/models are useful in understanding closure, but the reader may find one a little easier to hold than the other. Whichever you choose, the observable outcomes in our program are the same.\n\n| NOTE: |\n| :--- |\n| This alternative model for closure does affect whether we classify synchronous callbacks as examples of closure or not. More on this nuance in Appendix A. |\n\n## Why Closure?\n\nNow that we have a well-rounded sense of what closure is and how it works, let's explore some ways it can improve the code structure and organization of an example program.\n\nImagine you have a button on a page that when clicked, should retrieve and send some data via an Ajax request. Without using closure:\n\n```js\nvar APIendpoints = {\n    studentIDs:\n        \"https://some.api/register-students\",\n    // ..\n};\n\nvar data = {\n    studentIDs: [ 14, 73, 112, 6 ],\n    // ..\n};\n\nfunction makeRequest(evt) {\n    var btn = evt.target;\n    var recordKind = btn.dataset.kind;\n    ajax(\n        APIendpoints[recordKind],\n        data[recordKind]\n    );\n}\n\n// <button data-kind=\"studentIDs\">\n//    Register Students\n// </button>\nbtn.addEventListener(\"click\",makeRequest);\n```\n\nThe `makeRequest(..)` utility only receives an `evt` object from a click event. From there, it has to retrieve the `data-kind` attribute from the target button element, and use that value to lookup both a URL for the API endpoint as well as what data should be included in the Ajax request.\n\nThis works OK, but it's unfortunate (inefficient, more confusing) that the event handler has to read a DOM attribute each time it's fired. Why couldn't an event handler *remember* this value? Let's try using closure to improve the code:\n\n```js\nvar APIendpoints = {\n    studentIDs:\n        \"https://some.api/register-students\",\n    // ..\n};\n\nvar data = {\n    studentIDs: [ 14, 73, 112, 6 ],\n    // ..\n};\n\nfunction setupButtonHandler(btn) {\n    var recordKind = btn.dataset.kind;\n\n    btn.addEventListener(\n        \"click\",\n        function makeRequest(evt){\n            ajax(\n                APIendpoints[recordKind],\n                data[recordKind]\n            );\n        }\n    );\n}\n\n// <button data-kind=\"studentIDs\">\n//    Register Students\n// </button>\n\nsetupButtonHandler(btn);\n```\n\nWith the `setupButtonHandler(..)` approach, the `data-kind` attribute is retrieved once and assigned to the `recordKind` variable at initial setup. `recordKind` is then closed over by the inner `makeRequest(..)` click handler, and its value is used on each event firing to look up the URL and data that should be sent.\n\n| NOTE: |\n| :--- |\n| `evt` is still passed to `makeRequest(..)`, though in this case we're not using it anymore. It's still listed, for consistency with the previous snippet. |\n\nBy placing `recordKind` inside `setupButtonHandler(..)`, we limit the scope exposure of that variable to a more appropriate subset of the program; storing it globally would have been worse for code organization and readability. Closure lets the inner `makeRequest()` function instance *remember* this variable and access whenever it's needed.\n\nBuilding on this pattern, we could have looked up both the URL and data once, at setup:\n\n```js\nfunction setupButtonHandler(btn) {\n    var recordKind = btn.dataset.kind;\n    var requestURL = APIendpoints[recordKind];\n    var requestData = data[recordKind];\n\n    btn.addEventListener(\n        \"click\",\n        function makeRequest(evt){\n            ajax(requestURL,requestData);\n        }\n    );\n}\n```\n\nNow `makeRequest(..)` is closed over `requestURL` and `requestData`, which is a little bit cleaner to understand, and also slightly more performant.\n\nTwo similar techniques from the Functional Programming (FP) paradigm that rely on closure are partial application and currying. Briefly, with these techniques, we alter the *shape* of functions that require multiple inputs so some inputs are provided up front, and other inputs are provided later; the initial inputs are remembered via closure. Once all inputs have been provided, the underlying action is performed.\n\nBy creating a function instance that encapsulates some information inside (via closure), the function-with-stored-information can later be used directly without needing to re-provide that input. This makes that part of the code cleaner, and also offers the opportunity to label partially applied functions with better semantic names.\n\nAdapting partial application, we can further improve the preceding code:\n\n```js\nfunction defineHandler(requestURL,requestData) {\n    return function makeRequest(evt){\n        ajax(requestURL,requestData);\n    };\n}\n\nfunction setupButtonHandler(btn) {\n    var recordKind = btn.dataset.kind;\n    var handler = defineHandler(\n        APIendpoints[recordKind],\n        data[recordKind]\n    );\n    btn.addEventListener(\"click\",handler);\n}\n```\n\nThe `requestURL` and `requestData` inputs are provided ahead of time, resulting in the `makeRequest(..)` partially applied function, which we locally label `handler`. When the event eventually fires, the final input (`evt`, even though it's ignored) is passed to `handler()`, completing its inputs and triggering the underlying Ajax request.\n\nBehavior-wise, this program is pretty similar to the previous one, with the same type of closure. But by isolating the creation of `makeRequest(..)` in a separate utility (`defineHandler(..)`), we make that definition more reusable across the program. We also explicitly limit the closure scope to only the two variables needed.\n\n## Closer to Closure\n\nAs we close down a dense chapter, take some deep breaths let it all sink in. Seriously, that's a lot of information for anyone to consume!\n\nWe explored two models for mentally tackling closure:\n\n* Observational: closure is a function instance remembering its outer variables even as that function is passed to and **invoked in** other scopes.\n\n* Implementational: closure is a function instance and its scope environment preserved in-place while any references to it are passed around and **invoked from** other scopes.\n\nSummarizing the benefits to our programs:\n\n* Closure can improve efficiency by allowing a function instance to remember previously determined information instead of having to compute it each time.\n\n* Closure can improve code readability, bounding scope-exposure by encapsulating variable(s) inside function instances, while still making sure the information in those variables is accessible for future use. The resultant narrower, more specialized function instances are cleaner to interact with, since the preserved information doesn't need to be passed in every invocation.\n\nBefore you move on, take some time to restate this summary *in your own words*, explaining what closure is and why it's helpful in your programs. The main book text concludes with a final chapter that builds on top of closure with the module pattern.\n"
  },
  {
    "path": "scope-closures/ch8.md",
    "content": "# You Don't Know JS Yet: Scope & Closures - 2nd Edition\n# Chapter 8: The Module Pattern\n\nIn this chapter, we wrap up the main text of the book by exploring one of the most important code organization patterns in all of programming: the module. As we'll see, modules are inherently built from what we've already covered: the payoff for your efforts in learning lexical scope and closure.\n\nWe've examined every angle of lexical scope, from the breadth of the global scope down through nested block scopes, into the intricacies of the variable lifecycle. Then we leveraged lexical scope to understand the full power of closure.\n\nTake a moment to reflect on how far you've come in this journey so far; you've taken big steps in getting to know JS more deeply!\n\nThe central theme of this book has been that understanding and mastering scope and closure is key in properly structuring and organizing our code, especially the decisions on where to store information in variables.\n\nOur goal in this final chapter is to appreciate how modules embody the importance of these topics, elevating them from abstract concepts to concrete, practical improvements in building programs.\n\n## Encapsulation and Least Exposure (POLE)\n\nEncapsulation is often cited as a principle of object-oriented (OO) programming, but it's more fundamental and broadly applicable than that. The goal of encapsulation is the bundling or co-location of information (data) and behavior (functions) that together serve a common purpose.\n\nIndependent of any syntax or code mechanisms, the spirit of encapsulation can be realized in something as simple as using separate files to hold bits of the overall program with common purpose. If we bundle everything that powers a list of search results into a single file called \"search-list.js\", we're encapsulating that part of the program.\n\nThe recent trend in modern front-end programming to organize applications around Component architecture pushes encapsulation even further. For many, it feels natural to consolidate everything that constitutes the search results list—even beyond code, including presentational markup and styling—into a single unit of program logic, something tangible we can interact with. And then we label that collection the \"SearchList\" component.\n\nAnother key goal is the control of visibility of certain aspects of the encapsulated data and functionality. Recall from Chapter 6 the *least exposure* principle (POLE), which seeks to defensively guard against various *dangers* of scope over-exposure; these affect both variables and functions. In JS, we most often implement visibility control through the mechanics of lexical scope.\n\nThe idea is to group alike program bits together, and selectively limit programmatic access to the parts we consider *private* details. What's not considered *private* is then marked as *public*, accessible to the whole program.\n\nThe natural effect of this effort is better code organization. It's easier to build and maintain software when we know where things are, with clear and obvious boundaries and connection points. It's also easier to maintain quality if we avoid the pitfalls of over-exposed data and functionality.\n\nThese are some of the main benefits of organizing JS programs into modules.\n\n## What Is a Module?\n\nA module is a collection of related data and functions (often referred to as methods in this context), characterized by a division between hidden *private* details and *public* accessible details, usually called the \"public API.\"\n\nA module is also stateful: it maintains some information over time, along with functionality to access and update that information.\n\n| NOTE: |\n| :--- |\n| A broader concern of the module pattern is fully embracing system-level modularization through loose-coupling and other program architecture techniques. That's a complex topic well beyond the bounds of our discussion, but is worth further study beyond this book. |\n\nTo get a better sense of what a module is, let's compare some module characteristics to useful code patterns that aren't quite modules.\n\n### Namespaces (Stateless Grouping)\n\nIf you group a set of related functions together, without data, then you don't really have the expected encapsulation a module implies. The better term for this grouping of *stateless* functions is a namespace:\n\n```js\n// namespace, not module\nvar Utils = {\n    cancelEvt(evt) {\n        evt.preventDefault();\n        evt.stopPropagation();\n        evt.stopImmediatePropagation();\n    },\n    wait(ms) {\n        return new Promise(function c(res){\n            setTimeout(res,ms);\n        });\n    },\n    isValidEmail(email) {\n        return /[^@]+@[^@.]+\\.[^@.]+/.test(email);\n    }\n};\n```\n\n`Utils` here is a useful collection of utilities, yet they're all state-independent functions. Gathering functionality together is generally good practice, but that doesn't make this a module. Rather, we've defined a `Utils` namespace and organized the functions under it.\n\n### Data Structures (Stateful Grouping)\n\nEven if you bundle data and stateful functions together, if you're not limiting the visibility of any of it, then you're stopping short of the POLE aspect of encapsulation; it's not particularly helpful to label that a module.\n\nConsider:\n\n```js\n// data structure, not module\nvar Student = {\n    records: [\n        { id: 14, name: \"Kyle\", grade: 86 },\n        { id: 73, name: \"Suzy\", grade: 87 },\n        { id: 112, name: \"Frank\", grade: 75 },\n        { id: 6, name: \"Sarah\", grade: 91 }\n    ],\n    getName(studentID) {\n        var student = this.records.find(\n            student => student.id == studentID\n        );\n        return student.name;\n    }\n};\n\nStudent.getName(73);\n// Suzy\n```\n\nSince `records` is publicly accessible data, not hidden behind a public API, `Student` here isn't really a module.\n\n`Student` does have the data-and-functionality aspect of encapsulation, but not the visibility-control aspect. It's best to label this an instance of a data structure.\n\n### Modules (Stateful Access Control)\n\nTo embody the full spirit of the module pattern, we not only need grouping and state, but also access control through visibility (private vs. public).\n\nLet's turn `Student` from the previous section into a module. We'll start with a form I call the \"classic module,\" which was originally referred to as the \"revealing module\" when it first emerged in the early 2000s. Consider:\n\n```js\nvar Student = (function defineStudent(){\n    var records = [\n        { id: 14, name: \"Kyle\", grade: 86 },\n        { id: 73, name: \"Suzy\", grade: 87 },\n        { id: 112, name: \"Frank\", grade: 75 },\n        { id: 6, name: \"Sarah\", grade: 91 }\n    ];\n\n    var publicAPI = {\n        getName\n    };\n\n    return publicAPI;\n\n    // ************************\n\n    function getName(studentID) {\n        var student = records.find(\n            student => student.id == studentID\n        );\n        return student.name;\n    }\n})();\n\nStudent.getName(73);   // Suzy\n```\n\n`Student` is now an instance of a module. It features a public API with a single method: `getName(..)`. This method is able to access the private hidden `records` data.\n\n| WARNING: |\n| :--- |\n| I should point out that the explicit student data being hard-coded into this module definition is just for our illustration purposes. A typical module in your program will receive this data from an outside source, typically loaded from databases, JSON data files, Ajax calls, etc. The data is then injected into the module instance typically through method(s) on the module's public API. |\n\nHow does the classic module format work?\n\nNotice that the instance of the module is created by the `defineStudent()` IIFE being executed. This IIFE returns an object (named `publicAPI`) that has a property on it referencing the inner `getName(..)` function.\n\nNaming the object `publicAPI` is stylistic preference on my part. The object can be named whatever you like (JS doesn't care), or you can just return an object directly without assigning it to any internal named variable. More on this choice in Appendix A.\n\nFrom the outside, `Student.getName(..)` invokes this exposed inner function, which maintains access to the inner `records` variable via closure.\n\nYou don't *have* to return an object with a function as one of its properties. You could just return a function directly, in place of the object. That still satisfies all the core bits of a classic module.\n\nBy virtue of how lexical scope works, defining variables and functions inside your outer module definition function makes everything *by default* private. Only properties added to the public API object returned from the function will be exported for external public use.\n\nThe use of an IIFE implies that our program only ever needs a single central instance of the module, commonly referred to as a \"singleton.\" Indeed, this specific example is simple enough that there's no obvious reason we'd need anything more than just one instance of the `Student` module.\n\n#### Module Factory (Multiple Instances)\n\nBut if we did want to define a module that supported multiple instances in our program, we can slightly tweak the code:\n\n```js\n// factory function, not singleton IIFE\nfunction defineStudent() {\n    var records = [\n        { id: 14, name: \"Kyle\", grade: 86 },\n        { id: 73, name: \"Suzy\", grade: 87 },\n        { id: 112, name: \"Frank\", grade: 75 },\n        { id: 6, name: \"Sarah\", grade: 91 }\n    ];\n\n    var publicAPI = {\n        getName\n    };\n\n    return publicAPI;\n\n    // ************************\n\n    function getName(studentID) {\n        var student = records.find(\n            student => student.id == studentID\n        );\n        return student.name;\n    }\n}\n\nvar fullTime = defineStudent();\nfullTime.getName(73);            // Suzy\n```\n\nRather than specifying `defineStudent()` as an IIFE, we just define it as a normal standalone function, which is commonly referred to in this context as a \"module factory\" function.\n\nWe then call the module factory, producing an instance of the module that we label `fullTime`. This module instance implies a new instance of the inner scope, and thus a new closure that `getName(..)` holds over `records`. `fullTime.getName(..)` now invokes the method on that specific instance.\n\n#### Classic Module Definition\n\nSo to clarify what makes something a classic module:\n\n* There must be an outer scope, typically from a module factory function running at least once.\n\n* The module's inner scope must have at least one piece of hidden information that represents state for the module.\n\n* The module must return on its public API a reference to at least one function that has closure over the hidden module state (so that this state is actually preserved).\n\nYou'll likely run across other variations on this classic module approach, which we'll look at in more detail in Appendix A.\n\n## Node CommonJS Modules\n\nIn Chapter 4, we introduced the CommonJS module format used by Node. Unlike the classic module format described earlier, where you could bundle the module factory or IIFE alongside any other code including other modules, CommonJS modules are file-based; one module per file.\n\nLet's tweak our module example to adhere to that format:\n\n```js\nmodule.exports.getName = getName;\n\n// ************************\n\nvar records = [\n    { id: 14, name: \"Kyle\", grade: 86 },\n    { id: 73, name: \"Suzy\", grade: 87 },\n    { id: 112, name: \"Frank\", grade: 75 },\n    { id: 6, name: \"Sarah\", grade: 91 }\n];\n\nfunction getName(studentID) {\n    var student = records.find(\n        student => student.id == studentID\n    );\n    return student.name;\n}\n```\n\nThe `records` and `getName` identifiers are in the top-level scope of this module, but that's not the global scope (as explained in Chapter 4). As such, everything here is *by default* private to the module.\n\nTo expose something on the public API of a CommonJS module, you add a property to the empty object provided as `module.exports`. In some older legacy code, you may run across references to just a bare `exports`, but for code clarity you should always fully qualify that reference with the `module.` prefix.\n\nFor style purposes, I like to put my \"exports\" at the top and my module implementation at the bottom. But these exports can be placed anywhere. I strongly recommend collecting them all together, either at the top or bottom of your file.\n\nSome developers have the habit of replacing the default exports object, like this:\n\n```js\n// defining a new object for the API\nmodule.exports = {\n    // ..exports..\n};\n```\n\nThere are some quirks with this approach, including unexpected behavior if multiple such modules circularly depend on each other. As such, I recommend against replacing the object. If you want to assign multiple exports at once, using object literal style definition, you can do this instead:\n\n```js\nObject.assign(module.exports,{\n   // .. exports ..\n});\n```\n\nWhat's happening here is defining the `{ .. }` object literal with your module's public API specified, and then `Object.assign(..)` is performing a shallow copy of all those properties onto the existing `module.exports` object, instead of replacing it This is a nice balance of convenience and safer module behavior.\n\nTo include another module instance into your module/program, use Node's `require(..)` method. Assuming this module is located at \"/path/to/student.js\", this is how we can access it:\n\n```js\nvar Student = require(\"/path/to/student.js\");\n\nStudent.getName(73);\n// Suzy\n```\n\n`Student` now references the public API of our example module.\n\nCommonJS modules behave as singleton instances, similar to the IIFE module definition style presented before. No matter how many times you `require(..)` the same module, you just get additional references to the single shared module instance.\n\n`require(..)` is an all-or-nothing mechanism; it includes a reference of the entire exposed public API of the module. To effectively access only part of the API, the typical approach looks like this:\n\n```js\nvar getName = require(\"/path/to/student.js\").getName;\n\n// or alternately:\n\nvar { getName } = require(\"/path/to/student.js\");\n```\n\nSimilar to the classic module format, the publicly exported methods of a CommonJS module's API hold closures over the internal module details. That's how the module singleton state is maintained across the lifetime of your program.\n\n| NOTE: |\n| :--- |\n| In Node `require(\"student\")` statements, non-absolute paths (`\"student\"`) assume a \".js\" file extension and search \"node_modules\". |\n\n## Modern ES Modules (ESM)\n\nThe ESM format shares several similarities with the CommonJS format. ESM is file-based, and module instances are singletons, with everything private *by default*. One notable difference is that ESM files are assumed to be strict-mode, without needing a `\"use strict\"` pragma at the top. There's no way to define an ESM as non-strict-mode.\n\nInstead of `module.exports` in CommonJS, ESM uses an `export` keyword to expose something on the public API of the module. The `import` keyword replaces the `require(..)` statement. Let's adjust \"students.js\" to use the ESM format:\n\n```js\nexport { getName };\n\n// ************************\n\nvar records = [\n    { id: 14, name: \"Kyle\", grade: 86 },\n    { id: 73, name: \"Suzy\", grade: 87 },\n    { id: 112, name: \"Frank\", grade: 75 },\n    { id: 6, name: \"Sarah\", grade: 91 }\n];\n\nfunction getName(studentID) {\n    var student = records.find(\n        student => student.id == studentID\n    );\n    return student.name;\n}\n```\n\nThe only change here is the `export { getName }` statement. As before, `export` statements can appear anywhere throughout the file, though `export` must be at the top-level scope; it cannot be inside any other block or function.\n\nESM offers a fair bit of variation on how the `export` statements can be specified. For example:\n\n```js\nexport function getName(studentID) {\n    // ..\n}\n```\n\nEven though `export` appears before the `function` keyword here, this form is still a `function` declaration that also happens to be exported. That is, the `getName` identifier is *function hoisted* (see Chapter 5), so it's available throughout the whole scope of the module.\n\nAnother allowed variation:\n\n```js\nexport default function getName(studentID) {\n    // ..\n}\n```\n\nThis is a so-called \"default export,\" which has different semantics from other exports. In essence, a \"default export\" is a shorthand for consumers of the module when they `import`, giving them a terser syntax when they only need this single default API member.\n\nNon-`default` exports are referred to as \"named exports.\"\n\nThe `import` keyword—like `export`, it must be used only at the top level of an ESM outside of any blocks or functions—also has a number of variations in syntax. The first is referred to as \"named import\":\n\n```js\nimport { getName } from \"/path/to/students.js\";\n\ngetName(73);   // Suzy\n```\n\nAs you can see, this form imports only the specifically named public API members from a module (skipping anything not named explicitly), and it adds those identifiers to the top-level scope of the current module. This type of import is a familiar style to those used to package imports in languages like Java.\n\nMultiple API members can be listed inside the `{ .. }` set, separated with commas. A named import can also be *renamed* with the `as` keyword:\n\n```js\nimport { getName as getStudentName }\n   from \"/path/to/students.js\";\n\ngetStudentName(73);\n// Suzy\n```\n\nIf `getName` is a \"default export\" of the module, we can import it like this:\n\n```js\nimport getName from \"/path/to/students.js\";\n\ngetName(73);   // Suzy\n```\n\nThe only difference here is dropping the `{ }` around the import binding. If you want to mix a default import with other named imports:\n\n```js\nimport { default as getName, /* .. others .. */ }\n   from \"/path/to/students.js\";\n\ngetName(73);   // Suzy\n```\n\nBy contrast, the other major variation on `import` is called \"namespace import\":\n\n```js\nimport * as Student from \"/path/to/students.js\";\n\nStudent.getName(73);   // Suzy\n```\n\nAs is likely obvious, the `*` imports everything exported to the API, default and named, and stores it all under the single namespace identifier as specified. This approach most closely matches the form of classic modules for most of JS's history.\n\n| NOTE: |\n| :--- |\n| As of the time of this writing, modern browsers have supported ESM for a few years now, but Node's stable'ish support for ESM is fairly recent, and has been evolving for quite a while. The evolution is likely to continue for another year or more; the introduction of ESM to JS back in ES6 created a number of challenging compatibility concerns for Node's interop with CommonJS modules. Consult Node's ESM documentation for all the latest details: https://nodejs.org/api/esm.html |\n\n## Exit Scope\n\nWhether you use the classic module format (browser or Node), CommonJS format (in Node), or ESM format (browser or Node), modules are one of the most effective ways to structure and organize your program's functionality and data.\n\nThe module pattern is the conclusion of our journey in this book of learning how we can use the rules of lexical scope to place variables and functions in proper locations. POLE is the defensive *private by default* posture we always take, making sure we avoid over-exposure and interact only with the minimal public API surface area necessary.\n\nAnd underneath modules, the *magic* of how all our module state is maintained is closures leveraging the lexical scope system.\n\nThat's it for the main text. Congratulations on quite a journey so far! As I've said numerous times throughout, it's a really good idea to pause, reflect, and practice what we've just discussed.\n\nWhen you're comfortable and ready, check out the appendices, which dig deeper into some of the corners of these topics, and also challenge you with some practice exercises to solidify what you've learned.\n"
  },
  {
    "path": "scope-closures/foreword.md",
    "content": "# You Don't Know JS Yet: Scope & Closures - 2nd Edition\n# Foreword\n\nIf I look over the books on my bookshelf, I can clearly see which of these titles are well loved. Well loved in this sense meaning they are a little worn. Their binding is broken, their pages are tattered, there might even be a spilled drink smear or two. What’s ironic to me is that the most loved of my books often _**look**_ the least cared for, though honestly the opposite is true.\n\n*Scope and Closures* (1st ed.) is one of my most loved books. It’s small, but the binding is coming undone. The pages are worn and dog-eared. It’s a bit rumpled. It’s not a book I’ve read once. I’ve picked it up again and again in the many years since it was originally published.\n\nFor me, it’s also been a benchmark for my own personal progression through JavaScript. When I first read it in 2014, I was familiar with the concepts but the depth of my understanding was admittedly not as deep as the thin volume.\n\nOver the years, even though I wasn’t necessarily feeling my own improvement on a day-to-day basis, each one of the concepts became more approachable. I’d smile to myself, realizing how far I’d come with the help of these guides. It became apparent there was an inverse correlation between how well I treated the book and how much I loved it.\n\nWhen Kyle asked me to write the Foreword for the 2nd edition, I was floored. It’s not often you’re asked to write about a book that’s been so formative for your own understanding and career, *Scope and Closures* in particular. I remember the day I first understood closures, the first time I used one well. The satisfaction was great, in part because the symmetry of the idea was compelling to me. Before I even picked this book up, I was already enamoured with closures. And yet, there’s a difference between being able to execute code successfully and fully explore the concepts with any depth. This book took my base understanding and drew it out, helped me master it.\n\nThis book is deceptively short. It’s helpful that it’s small because it’s dense with useful knowledge. Since it is compact, I’d suggest you give yourself time to absorb each page. Take your time with it. Treat the book with care, and by that I mean, wear it down.\n\nSarah Drasner<br>\nHead of Developer Experience<br>\nNetlify\n"
  },
  {
    "path": "scope-closures/toc.md",
    "content": "# You Don't Know JS Yet: Scope & Closures - 2nd Edition\n\n## Table of Contents\n\n* Foreword\n* Preface\n* Chapter 1: What's the Scope?\n    * About This Book\n    * Compiled vs. Interpreted\n    * Compiling Code\n    * Compiler Speak\n    * Cheating: Run-Time Scope Modifications\n    * Lexical Scope\n* Chapter 2: Illustrating Lexical Scope\n    * Marbles, and Buckets, and Bubbles... Oh My!\n    * A Conversation Among Friends\n    * Nested Scope\n    * Continue the Conversation\n* Chapter 3: The Scope Chain\n    * \"Lookup\" Is (Mostly) Conceptual\n    * Shadowing\n    * Function Name Scope\n    * Arrow Functions\n    * Backing Out\n* Chapter 4: Around the Global Scope\n    * Why Global Scope?\n    * Where Exactly is this Global Scope?\n    * Global This\n    * Globally Aware\n* Chapter 5: The (Not So) Secret Lifecycle of Variables\n    * When Can I Use a Variable?\n    * Hoisting: Yet Another Metaphor\n    * Re-declaration?\n    * Uninitialized Variables (aka, TDZ)\n    * Finally Initialized\n* Chapter 6: Limiting Scope Exposure\n    * Least Exposure\n    * Hiding in Plain (Function) Scope\n    * Scoping with Blocks\n    * Function Declarations in Blocks\n    * Blocked Over\n* Chapter 7: Using Closures\n    * See the Closure\n    * The Closure Lifecycle and Garbage Collection (GC)\n    * An Alternative Perspective\n    * Why Closure?\n    * Closer to Closure\n* Chapter 8: The Module Pattern\n    * Encapsulation and Least Exposure (POLE)\n    * What is a Module?\n    * Node CommonJS Modules\n    * Modern ES Modules (ESM)\n    * Exit Scope\n* Appendix A: Exploring Further\n    * Implied Scopes\n    * Anonymous vs. Named Functions\n    * Hoisting: Functions and Variables\n    * The Case for `var`\n    * What's the Deal with TDZ?\n    * Are Synchronous Callbacks Still Closures?\n    * Classic Module Variations\n* Appendix B: Practice\n    * Buckets of Marbles\n    * Closure (PART 1)\n    * Closure (PART 2)\n    * Closure (PART 3)\n    * Modules\n    * Suggested Solutions\n"
  },
  {
    "path": "sync-async/README.md",
    "content": "# You Don't Know JS Yet: Async & Performance - 2nd Edition\n\n| NOTE: |\n| :--- |\n| Work in progress |\n\n[Table of Contents](toc.md)\n\n* [Foreword](foreword.md) (by TBA)\n* [Preface](../preface.md)\n* [Chapter 1: TODO](ch1.md)\n"
  },
  {
    "path": "sync-async/ch1.md",
    "content": "# You Don't Know JS Yet: Sync & Async - 2nd Edition\n# Chapter 1: TODO\n\n| NOTE: |\n| :--- |\n| Work in progress |\n\n"
  },
  {
    "path": "sync-async/foreword.md",
    "content": "# You Don't Know JS Yet: Async & Performance - 2nd Edition\n# Foreword\n\n| NOTE: |\n| :--- |\n| Work in progress |\n"
  },
  {
    "path": "sync-async/toc.md",
    "content": "# You Don't Know JS Yet: Sync & Async - 2nd Edition\n\n| NOTE: |\n| :--- |\n| Work in progress |\n\n## Table of Contents\n\n* Foreword\n* Preface\n* Chapter 1: TODO\n    * TODO\n"
  },
  {
    "path": "types-grammar/README.md",
    "content": "# You Don't Know JS Yet: Types & Grammar - 2nd Edition\n\n| NOTE: |\n| :--- |\n| Work in progress |\n\n[Table of Contents](toc.md)\n\n* [Foreword](foreword.md) (by TBA)\n* [Preface](../preface.md)\n* [Chapter 1: Primitive Values](ch1.md)\n* [Chapter 2: Primitive Behaviors](ch2.md)\n* [Chapter 3: Object Values](ch3.md)\n* [Chapter 4: Coercing Values](ch4.md)\n* Chapter 5: TODO\n* [Thank You!](thanks.md)\n"
  },
  {
    "path": "types-grammar/ch1.md",
    "content": "# You Don't Know JS Yet: Types & Grammar - 2nd Edition\n# Chapter 1: Primitive Values\n\n| NOTE: |\n| :--- |\n| Work in progress |\n\nIn Chapter 1 of the \"Objects & Classes\" book of this series, we confronted the common misconception that \"everything in JS is an object\". We now circle back to that topic, and again dispel that myth.\n\nHere, we'll look at the core value types of JS, specifically the non-object types called *primitives*.\n\n## Value Types\n\nJS doesn't apply types to variables or properties -- what I call, \"container types\" -- but rather, values themselves have types -- what I call, \"value types\".\n\nThe language provides seven built-in, primitive (non-object) value types: [^PrimitiveValues]\n\n* `undefined`\n* `null`\n* `boolean`\n* `number`\n* `bigint`\n* `symbol`\n* `string`\n\nThese value-types define collections of one or more concrete values, each with a set of shared behaviors for all values of each type.\n\n### Type-Of\n\nAny value's value-type can be inspected via the `typeof` operator, which always returns a `string` value representing the underlying JS value-type:\n\n```js\ntypeof true;            // \"boolean\"\n\ntypeof 42;              // \"number\"\n\ntypeof 42n;             // \"bigint\"\n\ntypeof Symbol(\"42\");    // \"symbol\"\n```\n\nThe `typeof` operator, when used against a variable instead of a value, is reporting the value-type of *the value in the variable*:\n\n```js\ngreeting = \"Hello\";\ntypeof greeting;        // \"string\"\n```\n\nJS variables themselves don't have types. They hold any arbitrary value, which itself has a value-type.\n\n### Non-objects?\n\nWhat specifically makes the 7 primitive value types distinct from the object value types (and sub-types)? Why shouldn't we just consider them all as essentially *objects* under the covers?\n\nConsider:\n\n```js\nmyName = \"Kyle\";\n\nmyName.nickname = \"getify\";\n\nconsole.log(myName.nickname);           // undefined\n```\n\nThis snippet appears to silently fail to add a `nickname` property to a primitive string. Taken at face value, that might imply that primitives are really just objects under the covers, as many have (wrongly) asserted over the years.\n\n| WARNING: |\n| :--- |\n| One might explain that silent failure as an example of *auto-boxing* (see \"Automatic Objects\" in Chapter 3), where the primitive is implicitly converted to a `String` instance wrapper object while attempting to assign the property, and then this internal object is thrown away after the statement completes. In fact, I said exactly that in the first edition of this book. But I was wrong; oops! |\n\nSomething deeper is at play, as we see in this version of the previous snippet:\n\n```js\n\"use strict\";\n\nmyName = \"Kyle\";\n\nmyName.nickname = \"getify\";\n// TypeError: Cannot create property 'nickname'\n// on string 'Kyle'\n```\n\nInteresting! In strict-mode, JS enforces a restriction that disallows setting a new property on a primitive value, as if implicitly promoting it to a new object.\n\nBy contrast, in non-strict mode, JS allows the violation to go unmentioned. So why? Because strict-mode was added to the language in ES5.1 (2011), more than 15 years in, and such a change would have broken existing programs had it not been defined as sensitive to the new strict-mode declaration.\n\nSo what can we conclude about the distinction between primitives and objects? Primitives are values that *are not allowed to have properties*; only objects are allowed such.\n\n| TIP: |\n| :--- |\n| This particular distinction seems to be contradicted by expressions like `\"hello\".length`; even in strict-mode, it returns the expected value `5`. So it certainly *seems* like the string has a `length` property! But, as just previously mentioned, the correct explanation is *auto-boxing*; we'll cover the topic in \"Automatic Objects\" in Chapter 3. |\n\n## Empty Values\n\nThe `null` and `undefined` types both typically represent an emptiness or absence of value.\n\nUnfortunately, the `null` value-type has an unexpected `typeof` result. Instead of `\"null\"`, we see:\n\n```js\ntypeof null;            // \"object\"\n```\n\nNo, that doesn't mean that `null` is somehow a special kind of object. It's just a legacy of early days of JS, which cannot be changed because of how much code out in the wild it would break.\n\nThe `undefined` type is reported both for explicit `undefined` values and any place where a seemingly missing value is encountered:\n\n```js\ntypeof undefined;               // \"undefined\"\n\nvar whatever;\n\ntypeof whatever;                // \"undefined\"\ntypeof nonExistent;             // \"undefined\"\n\nwhatever = {};\ntypeof whatever.missingProp;    // \"undefined\"\n\nwhatever = [];\ntypeof whatever[10];            // \"undefined\"\n```\n\n| NOTE: |\n| :--- |\n| The `typeof nonExistent` expression is referring to an undeclared variable `nonExistent`. Normally, accessing an undeclared variable reference would cause an exception, but the `typeof` operator is afforded the special ability to safely access even non-existent identifiers and calmly return `\"undefined\"` instead of throwing an exception. |\n\nHowever, each respective \"empty\" type has exactly one value, of the same name. So `null` is the only value in the `null` value-type, and `undefined` is the only value in the `undefined` value-type.\n\n### Null'ish\n\nSemantically, `null` and `undefined` types both represent general emptiness, or absence of another affirmative, meaningful value.\n\n| NOTE: |\n| :--- |\n| JS operations which behave the same whether `null` or `undefined` is encountered, are referred to as \"null'ish\" (or \"nullish\"). I guess \"undefined'ish\" would look/sound too weird! |\n\nFor a lot of JS, especially the code developers write, these two *nullish* values are interchangeable; the decision to intentionally use/assign `null` or `undefined` in any given scenario is situation dependent and left up to the developer.\n\nJS provides a number of capabilities for helping treat the two nullish values as indistinguishable.\n\nFor example, the `==` (coercive-equality comparison) operator specifically treats `null` and `undefined` as coercively equal to each other, but to no other values in the language. As such, a `.. == null` check is safe to perform if you want to check if a value is specifically either `null` or `undefined`:\n\n```js\nif (greeting == null) {\n    // greeting is nullish/empty\n}\n```\n\nAnother (recent) addition to JS is the `??` (nullish-coalescing) operator:\n\n```js\nwho = myName ?? \"User\";\n\n// equivalent to:\nwho = (myName != null) ? myName : \"User\";\n```\n\nAs the ternary equivalent illustrates, `??` checks to see if `myName` is non-nullish, and if so, returns its value. Otherwise, it returns the other operand (here, `\"User\"`).\n\nAlong with `??`, JS also added the `?.` (nullish conditional-chaining) operator:\n\n```js\nrecord = {\n    shippingAddress: {\n        street: \"123 JS Lane\",\n        city: \"Browserville\",\n        state: \"XY\"\n    }\n};\n\nconsole.log( record?.shippingAddress?.street );\n// 123 JS Lane\n\nconsole.log( record?.billingAddress?.street );\n// undefined\n```\n\nThe `?.` operator checks the value immediately preceding (to the left) value, and if it's nullish, the operator stops and returns an `undefined` value. Otherwise, it performs the `.` property access against that value and continues with the expression.\n\nJust to be clear: `record?.` is saying, \"check `record` for nullish before `.` property access\". Additionally, `billingAddress?.` is saying, \"check `billingAddress` for nullish before `.` property access\".\n\n| WARNING: |\n| :--- |\n| Some JS developers believe that the newer `?.` is superior to `.`, and should thus almost always be used instead of `.`. I believe that's an unwise perspective. First of all, it's adding extra visual clutter, which should only be done if you're getting benefit from it. Secondly, you should be aware of, and planning for, the emptiness of some value, to justify using `?.`. If you always expect a non-nullish value to be present in some expression, using `?.` to access a property on it is not only unnecessary/wasteful, but also could potentially hide future bugs where your assumption of value-presence had failed but `?.` covered it up. As with most features in JS, use `.` where it's most appropriate, and use `?.` where it's most appropriate. Never substitute one when the other is more appropriate. |\n\nThere's also a somewhat strange `?.[` form of the operator, not `?[`, for when you need to use `[ .. ]` style access instead of `.` access:\n\n```js\nrecord?.[\"shipping\" + \"Address\"]?.state;    // XY\n```\n\nYet another variation, referred to as \"optional-call\", is `?.(`, and is used when conditionally calling a function if the value is non-nullish:\n\n```js\n// instead of:\n//   if (someFunc) someFunc(42);\n//\n// or:\n//   someFunc && someFunc(42);\n\nsomeFunc?.(42);\n```\n\nThe `?.(` operator seems like it is checking to see if `someFunc(..)` is a valid function that can be called. But it's not! It's only checking to make sure the value is non-nullish before trying to invoke it. If it's some other non-nullish but also non-function value type, the execution attempt will still fail with a `TypeError` exception.\n\n| WARNING: |\n| :--- |\n| Because of that gotcha, I *strongly dislike* this operator form, and caution anyone against ever using it. I think it's a poorly conceived feature that does more harm (to JS itself, and to programs) than good. There's very few JS features I would go so far as to say, \"never use it.\" But this is one of the truly *bad parts* of the language, in my opinion. |\n\n### Distinct'ish\n\nIt's important to keep in mind that `null` and `undefined` *are* actually distinct types, and thus `null` can be noticeably different from `undefined`. You can, carefully, construct programs that mostly treat them as indistinguishable. But that requires care and discipline by the developer. From JS's perspective, they're more often distinct.\n\nThere are cases where `null` and `undefined` will trigger different behavior by the language, which is important to keep in mind. We won't cover all the cases exhaustively here, but here's on example:\n\n```js\nfunction greet(msg = \"Hello\") {\n    console.log(msg);\n}\n\ngreet();            // Hello\ngreet(undefined);   // Hello\ngreet(\"Hi\");        // Hi\n\ngreet(null);        // null\n```\n\nThe `= ..` clause on a parameter is referred to as the \"parameter default\". It only kicks in and assigns its default value to the parameter if the argument in that position is missing, or is exactly the `undefined` value. If you pass `null`, that clause doesn't trigger, and `null` is thus assigned to the parameter.\n\nThere's no *right* or *wrong* way to use `null` or `undefined` in a program. So the takeaway is: be careful when choosing one value or the other. And if you're using them interchangeably, be extra careful.\n\n## Boolean Values\n\nThe `boolean` type contains two values: `false` and `true`.\n\nIn the \"old days\", programming languages would, by convention, use `0` to mean `false` and `1` to mean `true`. So you can think of the `boolean` type, and the keywords `false` and `true`, as a semantic convenience sugar on top of the `0` and `1` values:\n\n```js\n// isLoggedIn = 1;\nisLoggedIn = true;\n\nisComplete = 0;\n// isComplete = false;\n```\n\nBoolean values are how all decision making happens in a JS program:\n\n```js\nif (isLoggedIn) {\n    // do something\n}\n\nwhile (!isComplete) {\n    // keep going\n}\n```\n\nThe `!` operator negates/flips a boolean value to the other one: `false` becomes `true`, and `true` becomes `false`.\n\n## String Values\n\nThe `string` type contains any value which is a collection of one or more characters, delimited (surrounding on either side) by quote characters:\n\n```js\nmyName = \"Kyle\";\n```\n\nJS does not distinguish a single character as a different type as some languages do; `\"a\"` is a string just like `\"abc\"` is.\n\nStrings can be delimited by double-quotes (`\"`), single-quotes (`'`), or back-ticks (`` ` ``). The ending delimiter must always match the starting delimiter.\n\nStrings have an intrinsic length which corresponds to how many code-points -- actually, code-units, more on that in a bit -- they contain.\n\n```js\nmyName = \"Kyle\";\n\nmyName.length;      // 4\n```\n\nThis does not necessarily correspond to the number of visible characters present between the start and end delimiters (aka, the string literal). It can sometimes be a little confusing to keep straight the difference between a string literal and the underlying string value, so pay close attention.\n\n| NOTE: |\n| :--- |\n| We'll cover length computation of strings in detail, in Chapter 2. |\n\n### JS Character Encodings\n\nWhat type of character encoding does JS use for string characters?\n\nYou've probably heard of \"Unicode\" and perhaps even \"UTF-8\" (8-bit) or \"UTF-16\" (16-bit). If you're like me (before doing the research it took to write this text), you might have just hand-waved and decided that's all you need to know about character encodings in JS strings.\n\nBut... it's not. Not even close.\n\nIt turns out, you need to understand how a variety of aspects of Unicode work, and even to consider concepts from UCS-2 (2-byte Universal Character Set), which is similar to UTF-16, but not quite the same. [^UTFUCS]\n\nUnicode defines all the \"characters\" we can represent universally in computer programs, by assigning a specific number to each, called code-points. These numbers range from `0` all the way up to a maximum of `1114111` (`10FFFF` in hexadecimal).\n\nThe standard notation for Unicode characters is `U+` followed by 4-6 hexadecimal characters. For example, the `❤` (heart symbol) is code-point `10084` (`2764` in hexadecimal), and is thus notated with `U+2764`.\n\nThe first group of 65,535 code points in Unicode is called the BMP (Basic Multilingual Plane). These can all be represented with 16 bits (2 bytes). When representing Unicode characters from the BMP, it's fairly straightforward, as they can *fit* neatly into single UTF-16 JS characters.\n\nAll the rest of the code points are grouped into 16 so called \"supplemental planes\" or \"astral planes\". These code-points require more than 16 bits to represent -- 21 bits to be exact -- so when representing extended/supplemental characters above the BMP, JS actually stores these code-points as a pairing of two adjacent 16-bit code units, called *surrogate halves* (or *surrogate pairs*).\n\nFor example, the Unicode code point `127878` (hexadecimal `1F386`) is `🎆` (fireworks symbol). JS stores this in a string value as two surrogate-halve code units: `U+D83C` and `U+DF86`. Keep in mind that these two parts of the whole character do *not* standalone; they're only valid/meaningful when paired immediately adjacent to each other.\n\nThis has implications on the length of strings, because a single visible character like the `🎆` fireworks symbol, when in a JS string, is a counted as 2 characters for the purposes of the string length!\n\nWe'll revisit Unicode characters in a bit, and then cover the challenges of computing string length in Chapter 2.\n\n### Escape Sequences\n\nIf `\"` or `'` are used to delimit a string literal, the contents are only parsed for *character-escape sequences*: `\\` followed by one or more characters that JS recognizes and parses with special meaning. Any other characters in a string that don't parse as escape-sequences (single-character or multi-character), are inserted as-is into the string value.\n\nFor single-character escape sequences, the following characters are recognized after a `\\`: `b`, `f`, `n`, `r`, `t`, `v`, `0`, `'`, `\"`, and `\\`. For example,  `\\n` means new-line, `\\t` means tab, etc.\n\nIf a `\\` is followed by any other character (except `x` and `u` -- explained below), like for example `\\k`, that sequence is interpreted as the `\\` being an unnecessary escape, which is thus dropped, leaving just the literal character itself (`k`).\n\nTo include a `\"` in the middle of a `\"`-delimited string literal, use the `\\\"` escape sequence. Similarly, if you're including a `'` character in the middle of a `'`-delimited string literal, use the `\\'` escape sequence. By contrast, a `'` does *not* need to be escaped inside a `\"`-delimited string, nor vice versa.\n\n```js\nmyTitle = \"Kyle Simpson (aka, \\\"getify\\\"), former O'Reilly author\";\n\nconsole.log(myTitle);\n// Kyle Simpson (aka, \"getify\"), former O'Reilly author\n```\n\nIn text, forward slash `/` is most common. But occasionally, you need a backward slash `\\`. To include a literal `\\` backslash character without it performing as the start of a character-escape sequence, use the `\\\\` (double backslashes).\n\nSo, then... what would `\\\\\\` (three backslashes) in a string parse as? The first two `\\`'s would be a `\\\\` escape sequence, thereby inserting just a single `\\` character in the string value, and the remaining `\\` would just escape whatever character comes immediately after it.\n\nOne place backslashes show up commonly is in Windows file paths, which use the `\\` separator instead of the `/` separator used in linux/unix style paths:\n\n```js\nwindowsFontsPath =\n    \"C:\\\\Windows\\\\Fonts\\\\\";\n\nconsole.log(windowsFontsPath);\n// C:\\Windows\\Fonts\\\"\n```\n\n| TIP: |\n| :--- |\n| What about four backslashes `\\\\\\\\` in a string literal? Well, that's just two `\\\\` escape sequences next to each other, so it results in two adjacent backslashes (`\\\\`) in the underlying string value. You might recognize there's an odd/even rule pattern at play. You should thus be able to deciper any odd (`\\\\\\\\\\`, `\\\\\\\\\\\\\\\\\\`, etc) or even (`\\\\\\\\\\\\`, `\\\\\\\\\\\\\\\\\\\\`, etc) number of backslashes in a string literal. |\n\n#### Line Continuation\n\nThe `\\` character followed by an actual new-line character (not just literal `n`) is a special case, and it creates what's called a line-continuation:\n\n```js\ngreeting = \"Hello \\\nFriends!\";\n\nconsole.log(greeting);\n// Hello Friends!\n```\n\nAs you can see, the new-line at the end of the `greeting = ` line is immediately preceded by a `\\`, which allows this string literal to continue onto the subsequent line. Without the escaping `\\` before it, a new-line -- the actual new-line, not the `\\n` character escape sequence -- appearing in a `\"` or `'` delimited string literal would actually produce a JS syntax parsing error.\n\nBecause the end-of-line `\\` turns the new-line character into a line continuation, the new-line character is omitted from the string, as shown by the `console.log(..)` output.\n\n| NOTE: |\n| :--- |\n| This line-continuation feature is often referred to as \"multi-line strings\", but I think that's a confusing label. As you can see, the string value itself doesn't have multiple lines, it only was defined across multiple lines via the line continuations. A multi-line string would actually have multiple lines in the underlying value. We'll revisit this topic later in this chapter when we cover Template Literals. |\n\n### Multi-Character Escapes\n\nMulti-character escape sequences may be hexadecimal or Unicode sequences.\n\nHexadecimal escape sequences are used to encode any of the base ASCII characters (codes 0-255), and look like `\\x` followed by exactly two hexadecimal characters (`0-9` and `a-f` / `A-F` -- case insensitive). For example, `A9` or `a9` are decimal value `169`, which corresponds to:\n\n```js\ncopyright = \"\\xA9\";  // or \"\\xa9\"\n\nconsole.log(copyright);     // ©\n```\n\nFor any normal character that can be typed on a keyboard, such as `\"a\"`, it's usually most readable to just specify the literal character, as opposed to a more obfuscated hexadecimal representation:\n\n```js\n\"a\" === \"\\x61\";             // true\n```\n\n#### Unicode In Strings\n\nUnicode escape sequences alone can encode any of the characters from the Unicode BMP. They look like `\\u` followed by exactly four hexadecimal characters.\n\nFor example, the escape-sequence `\\u00A9` (or `\\u00a9`) corresponds to that same `©` symbol, while `\\u263A` (or `\\u263a`) corresponds to the Unicode character with code-point `9786`: `☺` (smiley face symbol).\n\nWhen any character-escape sequence (regardless of length) is recognized, the single character it represents is inserted into the string, rather than the original separate characters. So, in the string `\"\\u263A\"`, there's only one (smiley) character, not six individual characters.\n\nBut as explained earlier, many Unicode code-points are well above `65535`. For example, `1F4A9` (or `1f4a9`) is decimal code-point `128169`, which corresponds to the funny `💩` (pile-of-poo) symbol.\n\nBut `\\u1F4A9` wouldn't work to include this character in a string, since it would be parsed as the Unicode escape sequence `\\u1F4A`, followed by a literal `9` character. To address this limitation, a variation of Unicode escape sequences was introduced to allow an arbitrary number of hexadecimal characters after the `\\u`, by surrounding them with `{ .. }` curly braces:\n\n```js\nmyReaction = \"\\u{1F4A9}\";\n\nconsole.log(myReaction);\n// 💩\n```\n\nRecall the earlier discussion of extended (non-BMP) Unicode characters and *surrogate halves*? The same `💩` could also be defined with two explicit code-units, that form a surrogate pair:\n\n```js\nmyReaction = \"\\uD83D\\uDCA9\";\n\nconsole.log(myReaction);\n// 💩\n```\n\nAll three representations of this same character are stored internally by JS identically, and are indistinguishable:\n\n```js\n\"💩\" === \"\\u{1F4A9}\";                // true\n\"\\u{1F4A9}\" === \"\\uD83D\\uDCA9\";     // true\n```\n\nEven though JS doesn't care which way such a character is represented in your program, consider the readability differences carefully when authoring your code.\n\n| NOTE: |\n| :--- |\n| Even though `💩` looks like a single character, its internal representation affects things like the length computation of a string with that character in it. We'll cover length computation of strings in Chapter 2. |\n\n##### Unicode Normalization\n\nAnother wrinkle in Unicode string handling is that even certain single BMP characters can be represented in different ways.\n\nFor example, the `\"é\"` character can either be represented as itself (code-point `233`, aka `\\xe9` or `\\u00e9` or `\\u{e9}`), or as the combination of two code-points: the `\"e\"` character (code-point `101`, aka `\\x65`, `\\u0065`, `\\u{65}`) and the *combining tilde* (code-point `769`, aka `\\u0301`, `\\u{301}`).\n\nConsider:\n\n```js\neTilde1 = \"é\";\neTilde2 = \"\\u00e9\";\neTilde3 = \"\\u0065\\u0301\";\n\nconsole.log(eTilde1);       // é\nconsole.log(eTilde2);       // é\nconsole.log(eTilde3);       // é\n```\n\nThe string literal assigned to `eTilde3` in this snippet stores the accent mark as a separate *combining mark* symbol. Like surrogate pairs, a combining mark only makes sense in connection with the symbol it's adjacent to (usually after).\n\nThe rendering of the Unicode symbol should be the same regardless, but how the `\"é\"` character is internally stored affects things like `length` computation of the containing string, as well as equality and relational comparison (more on these in Chapter 2):\n\n```js\neTilde1.length;             // 2\neTilde2.length;             // 1\neTilde3.length;             // 2\n\neTilde1 === eTilde2;        // false\neTilde1 === eTilde3;        // true\n```\n\nOne particular challenge is that you may copy-paste a string with an `\"é\"` character visible in it, and that character you copied may have been in the *composed* or *decomposed* form. But there's no visual way to tell, and yet the underlying string value in the literal will be different:\n\n```js\n\"é\" === \"é\";           // false!!\n```\n\nThis internal representation difference can be quite challenging if not carefully planned for. Fortunately, JS provides a `normalize(..)` utility method on strings to help:\n\n```js\neTilde1 = \"é\";\neTilde2 = \"\\u{e9}\";\neTilde3 = \"\\u{65}\\u{301}\";\n\neTilde1.normalize(\"NFC\") === eTilde2;\neTilde2.normalize(\"NFD\") === eTilde3;\n```\n\nThe `\"NFC\"` normalization mode combines adjacent code-points into the *composed* code-point (if possible), whereas the `\"NFD\"` normalization mode splits a single code-point into its *decomposed* code-points (if possible).\n\nAnd there can actually be more than two individual *decomposed* code-points that make up a single *composed* code-point -- for example, a single character could have several diacritical marks applied to it.\n\nWhen dealing with Unicode strings that will be compared, sorted, or length analyzed, it's very important to keep Unicode normalization in mind, and use it where necessary.\n\n##### Unicode Grapheme Clusters\n\nA final complication of Unicode string handling is the support for clustering of multiple adjacent code-points into a single visually distinct symbol, referred to as a *grapheme* (or a *grapheme cluster*).\n\nAn example would be a family emoji such as `\"👩‍👩‍👦‍👦\"`, which is actually made up of 7 code-points that all cluster/group together into a single visual symbol.\n\nConsider:\n\n```js\nfamilyEmoji = \"\\u{1f469}\\u{200d}\\u{1f469}\\u{200d}\\u{1f466}\\u{200d}\\u{1f466}\";\n\nfamilyEmoji;            // 👩‍👩‍👦‍👦\n```\n\nThis emoji is *not* a single registered Unicode code-point, and as such, there's no *normalization* that can be performed to compose these 7 separate code-points into a single entity. The visual rendering logic for such composite symbols is quite complex, well beyond what most of JS developers want to embed into our programs. Libraries do exist for handling some of this logic, but they're often large and still don't necessarily cover all of the nuances/variations.\n\nUnlike surrogate pairs and combining marks, the symbols in grapheme clusters can in fact act as standalone characters, but have the special combining behavior when placed adjacent to each other.\n\nThis kind of complexity significantly affects length computations, comparison, sorting, and many other common string-oriented operations.\n\n### Template Literals\n\nI mentioned earlier that strings can alternately be delimited with `` `..` `` back-ticks:\n\n```js\nmyName = `Kyle`;\n```\n\nAll the same rules for character encodings, character escape sequences, and lengths apply to these types of strings.\n\nHowever, the contents of these template (string) literals are additionally parsed for a special delimiter sequence `${ .. }`, which marks an expression to evaluate and interpolate into the string value at that location:\n\n```js\nmyName = `Kyle`;\n\ngreeting = `Hello, ${myName}!`;\n\nconsole.log(greeting);      // Hello, Kyle!\n```\n\nEverything between the `{ .. }` in such a template literal is an arbitrary JS expression. It can be simple variables like `myName`, or complex JS programs, or anything in between (even another template literal expression!).\n\n| TIP: |\n| :--- |\n| This feature is commonly called \"template literals\" or \"template strings\", but I think that's confusing. \"Template\" usually means, in programming contexts, a reusable set of text that can be re-evaluated with different data. For example, *template engines* for pages, email templates for newsletter campaigns, etc. This JS feature is not re-usable. It's a literal, and it produces a single, immediate value (usually a string). You can put such a value in a function, and call the function multiple times. But then the function is acting as the template, not the the literal itself. I prefer instead to refer to this feature as *interpolated literals*, or the funny, short-hand: *interpoliterals*. I just think that name is more accurately descriptive. |\n\nTemplate literals also have an interesting different behavior with respect to new-lines, compared to classic `\"` or `'` delimited strings. Recall that for those strings, a line-continuation required a `\\` at the end of each line, right before a new-line. Not so, with template literals!\n\n```js\nmyPoem = `\nRoses are red\nViolets are blue\nC3PO's a funny robot\nand so R2.`;\n\nconsole.log(myPoem);\n//\n// Roses are red\n// Violets are blue\n// C3PO's a funny robot\n// and so R2.\n```\n\nLine-continuations with template literals do *not require* escaping. However, that means the new-line is part of the string, even the first new-line above. In other words, `myPoem` above holds a truly *multi-line string*, as shown. However, if you `\\` escape the end of any line in a template literal, the new-line will be omitted, just like with non-template literal strings.\n\nTemplate literals usually result in a string value, but not always. A form of template literal that may look kind of strange is called a *tagged template literal*:\n\n```js\nprice = formatCurrency`The cost is: ${totalCost}`;\n```\n\nHere, `formatCurrency` is a tag applied to the template literal value, which actually invokes `formatCurrency(..)` as a function, passing it the string literals and interpolated expressions parsed from the value. This function can then assemble those in any way it sees fit -- such as formatting a `number` value as currency in the current locale -- and return whatever value, string or otherwise, that it wants.\n\nSo tagged template literals are not always strings; they can be any value. But untagged template literals *will always be* strings.\n\nSome JS developers believe that untagged template literal strings are best to use for *all* strings, even if not using any expression interpolation or multiple lines. I disagree. I think they should only be used when interpolating (or multi-line'ing).\n\n| TIP: |\n| :--- |\n| The principle I always apply in making such determinations: use the closest-matched, and least capable, feature/tool, for any task. |\n\nMoreover, there are a few places where `` `..` `` style strings are disallowed. For example, the `\"use strict\"` pragma cannot use back-ticks, or the pragma will be silently ignored (and thus the program accidentally runs in non-strict mode). Also, this style of strings cannot be used in quoted property names of object literals, destruturing patterns, or in the ES Module `import .. from ..` module-specifier clause.\n\nMy take: use `` `..` `` delimited strings where allowed, but only when interpolation/multi-line is needed; and keep using `\"..\"` or `'..'` delimited strings for everything else.\n\n## Number Values\n\nThe `number` type contains any numeric value (whole number or decimal), such as `-42` or `3.1415926`. These values are represented by the JS engine as 64-bit, IEEE-754 double-precision binary floating-point values. [^IEEE754]\n\nJS `number`s are always decimals; whole numbers (aka \"integers\") are not stored in a different/special way. An \"integer\" stored as a `number` value merely has nothing non-zero as its fraction portion; `42` is thus indistinguishable in JS from `42.0` and `42.000000`.\n\nWe can use `Number.isInteger(..)` to determine if a `number` value has any non-zero fraction or not:\n\n```js\nNumber.isInteger(42);           // true\nNumber.isInteger(42.0);         // true\nNumber.isInteger(42.000000);    // true\n\nNumber.isInteger(42.0000001);   // false\n```\n\n### Parsing vs Coercion\n\nIf a string value holds numeric-looking contents, you may need to convert from that string value to a `number`, for mathematical operation purposes.\n\nHowever, it's very important to distinguish between parsing-conversion and coercive-conversion.\n\nWe can parse-convert with JS's built-in `parseInt(..)` or `parseFloat(..)` utilities:\n\n```js\nsomeNumericText = \"123.456\";\n\nparseInt(someNumericText,10);               // 123\nparseFloat(someNumericText);                // 123.456\n\nparseInt(\"42\",10) === parseFloat(\"42\");     // true\n\nparseInt(\"512px\");                          // 512\n```\n\n| NOTE: |\n| :--- |\n| Parsing is only relevant for string values, as it's a character-by-character (left-to-right) operation. It doesn't make sense to parse the contents of a `boolean`, nor to parse the contents of a `number` or a `null`; there's nothing to parse. If you pass anything other than a string value to `parseInt(..)` / `parseFloat(..)`, those utilities first convert that value to a string and then try to parse it. That's almost certainly problematic (leading to bugs) or wasteful -- `parseInt(42)` is silly, and `parseInt(42.3)` is an abuse of `parseInt(..)` to do the job of `Math.floor(..)`. |\n\nParsing pulls out numeric-looking characters from the string value, and puts them into a `number` value, stopping once it encounters a character that's non-numeric (e.g., not `-`, `.` or `0`-`9`). If parsing fails on the first character, both utilities return the special `NaN` value (see \"Invalid Number\" below), indicating the operation was invalid and failed.\n\nWhen `parseInt(..)` encounters the `.` in `\"123.456\"`, it stops, using just the `123` in the resulting `number` value. `parseFloat(..)` by contrast accepts this `.` character, and keeps right on parsing a float with any decimal digits after the `.`.\n\nThe `parseInt(..)` utility specifically, takes as an optional -- but *actually*, rather necessary -- second argument, `radix`: the numeric base to assume for interpreting the string characters for the `number` (range `2` - `36`). `10` is for standard base-10 numbers, `2` is for binary, `8` is for octal, and `16` is for hexadecimal. Any other unusual `radix`, like `23`, assumes digits in order, `0` - `9` followed by the `a` - `z` (case insensitive) character ordination. If the specified radix is outside the `2` - `36` range, `parseInt(..)` fails as invalid and returns the `NaN` value.\n\nIf `radix` is omitted, the behavior of `parseInt(..)` is rather nuanced and confusing, in that it attempts to make a best-guess for a radix, based on what it sees in the first character. This historically has lead to lots of subtle bugs, so never rely on the default auto-guessing; always specify an explicit radix (like `10` in the calls above).\n\n`parseFloat(..)` always parses with a radix of `10`, so no second argument is accepted.\n\n| WARNING: |\n| :--- |\n| One surprising difference between `parseInt(..)` and `parseFloat(..)` is that `parseInt(..)` will not fully parse scientific notation (e.g., `\"1.23e+5\"`), instead stopping at the `.` as it's not valid for integers; in fact, even `\"1e+5\"` stops at the `\"e\"`. `parseFloat(..)` on the other hand fully parses scientific notation as expected. |\n\nIn contrast to parsing-conversion, coercive-conversion is an all-or-nothing sort of operation. Either the entire contents of the string are recognized as numeric (integer or floating-point), or the whole conversion fails (resulting in `NaN` -- again, see \"Invalid Number\" later in this chapter).\n\nCoercive-conversion can be done explicitly with the `Number(..)` function (no `new` keyword) or with the unary `+` operator in front of the value:\n\n```js\nsomeNumericText = \"123.456\";\n\nNumber(someNumericText);        // 123.456\n+someNumericText;               // 123.456\n\nNumber(\"512px\");                // NaN\n+\"512px\";                       // NaN\n```\n\n### Other Numeric Representations\n\nIn addition to defining numbers using traditional base-10 numerals (`0`-`9`), JS supports defining whole-number-only number literals in three other bases: binary (base-2), octal (base-8), and hexadecimal (base-16).\n\n```js\n// binary\nmyAge = 0b101010;\nmyAge;              // 42\n\n// octal\nmyAge = 0o52;\nmyAge;              // 42\n\n// hexadecimal\nmyAge = 0x2a;\nmyAge;              // 42\n```\n\nAs you can see, the prefixes `0b` (binary), `0o` (octal), and `0x` (hexadecimal) signal defining numbers in the different bases, but decimals are not allowed on these numeric literals.\n\n| NOTE: |\n| :--- |\n| JS syntax allows `0B`, `0O`, and `0X` prefixes as well. However, please don't ever use those uppercase prefix forms. I think any sensible person would agree: `0O` is much easier to confuse at a glance than `0o` (which is, itself, a bit visually ambiguous at a glance). Always stick to the lowercase prefix forms! |\n\nIt's important to realize that you're not defining a *different number*, just using a different form to produce the same underlying numeric value.\n\nBy default, JS represents the underlying numeric value in output/string fashion with standard base-10 form. However, `number` values have a built-in `toString(..)` method that produces a string representation in any specified base/radix (as with `parseInt(..)`, in the range `2` - `36`):\n\n```js\nmyAge = 42;\n\nmyAge.toString(2);          // \"101010\"\nmyAge.toString(8);          // \"52\"\nmyAge.toString(16);         // \"2a\"\nmyAge.toString(23);         // \"1j\"\nmyAge.toString(36);         // \"16\"\n```\n\nYou can round-trip any arbitrary-radix string representation back into a `number` using `parseInt(..)`, with the appropriate radix:\n\n```js\nmyAge = 42;\n\nparseInt(myAge.toString(\"23\"),23);      // 42\n```\n\nAnother allowed form for specifying number literals is using scientific notation:\n\n```js\nmyAge = 4.2E1;      // or 4.2e1 or 4.2e+1\n\nmyAge;              // 42\n```\n\n`4.2E1` (or `4.2e1`) means, `4.2 * (10 ** 1)` (`10` to the `1` power). The exponent can optionally have a sign `+` or `-`. If the sign is omitted, it's assumed to be `+`. A negative exponent makes the number smaller (moves the decimal leftward) rather than larger (moving the decimal rightward):\n\n```js\n4.2E-3;             // 0.0042\n```\n\nThis scientific notation form is especially useful for readability when specifying larger powers of `10`:\n\n```js\nsomeBigPowerOf10 = 1000000000;\n\n// vs:\n\nsomeBigPowerOf10 = 1e9;\n```\n\nBy default, JS will represent (e.g., as string values, etc) either very large or very small numbers -- specifically, if the values require more than 21 digits of precision -- using this same scientific notation:\n\n```js\nratherBigNumber = 123 ** 11;\nratherBigNumber.toString();     // \"9.748913698143826e+22\"\n\nprettySmallNumber = 123 ** -11;\nprettySmallNumber.toString();   // \"1.0257553107587752e-23\"\n```\n\nNumbers with smaller absolute values (closer to `0`) than these thresholds can still be forced into scientific notation form (as strings):\n\n```js\nplainBoringNumber = 42;\n\nplainBoringNumber.toExponential();      // \"4.2e+1\"\nplainBoringNumber.toExponential(0);     // \"4e+1\"\nplainBoringNumber.toExponential(4);     // \"4.2000e+1\"\n```\n\nThe optional argument to `toExponential(..)` specifies the number of decimal digits to include in the string representation.\n\nAnother readability affordance for specifying numeric literals in code is the ability to insert `_` as a digit separator wherever its convenient/meaningful to do so. For example:\n\n```js\nsomeBigPowerOf10 = 1_000_000_000;\n\ntotalCostInPennies = 123_45;  // vs 12_345\n```\n\nThe decision to use `12345` (no separator), `12_345` (like \"12,345\"), or `123_45` (like \"123.45\") is entirely up to the author of the code; JS ignores the separators. But depending on the context, `123_45` could be more semantically meaningful (readability wise) than the more traditional three-digit-grouping-from-the-right-separated-with-commas style mimicked with `12_345`.\n\n### IEEE-754 Bitwise Binary Representations\n\nIEEE-754[^IEEE754] is a technical standard for binary representation of decimal numbers. It's widely used by most computer programming languages, including JS, Python, Ruby, etc.\n\nI'm not going to cover it exhaustively, but I think a brief primer on how numbers work in languages like JS is more than warranted, given how few programmers have *any* familiarity with it.\n\nIn 64-bit IEEE-754 -- so called \"double-precision\", because originally IEEE-754 used to be 32-bit, and now it's double that! -- the 64 bits are divided into three sections: 52 bits for the number's base value (aka, \"fraction\", \"mantissa\", or \"significand\"), 11 bits for the exponent to raise `2` to before multiplying, and 1 bit for the sign of the ultimate value.\n\n| NOTE: |\n| :--- |\n| Since only 52 of the 64 bits are actually used to represent the base value, `number` doesn't actually have `2^64` values in it. According to the specification for the `number` type[^NumberType], the number of values is precisely `2^64 - 2^53 + 3`, or about 18 quintillion, split about evenly between positive and negative numbers. |\n\nThese bits are arranged left-to-right, as so (S = Sign Bit, E = Exponent Bit, M = Mantissa Bit):\n\n```js\nSEEEEEEEEEEEMMMMMMMMMMMMMMMMMMMM\nMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM\n```\n\nSo, the number `42` (or `42.000000`) would be represented by these bits:\n\n```\n// 42:\n01000000010001010000000000000000\n00000000000000000000000000000000\n```\n\nThe sign bit is `0`, meaning the number is positive (`1` means negative).\n\nThe 11-bit exponent is binary `10000000100`, which in base-10 is `1028`. But in IEEE-754, this value is interpreted as being stored unsigned with an \"exponent bias\" of `1023`, meaning that we're shifting up the exponent range from `-1022:1023` to `1:2046` (where `0` and `2047` are reserved for special representations). So, take `1028` and subtract the bias `1023`, which gives an effective exponent of `5`. We raise `2` to that value (`2^5`), giving `32`.\n\n| NOTE: |\n| :--- |\n| If the subtracting `1023` from the exponent value gives a negative (e.g., `-3`), that's still interpreted as `2`'s exponent; raising `2` to negative numbers just produces smaller and smaller values. |\n\nThe remaining 52 bits give us the base value `01010000...`, interpreted as binary decimal `1.0101000...` (with all trailing zeros). Converting *that* to base-10, we get `1.3125000...`. Finally, then multiply that by `32` already computed from the exponent. The result: `42`.\n\nAs you might be able to tell now, this IEEE-754 number representation standard is called \"floating point\" because the decimal point \"floats\" back-and-forth along the bits, depending on the specified exponent value.\n\nThe number `42.0000001`, which is only different from `42.000000` by just `0.0000001`, would be represented by these bits:\n\n```\n// 42.0000001:\n01000000010001010000000000000000\n00000000110101101011111110010101\n```\n\nNotice how the previous bit pattern and this one differ by quite a few bits in the trailing positions! The binary decimal fraction containing all those extra `1` bits (`1.010100000000...01011111110010101`) converts to base-10 as `1.31250000312500003652`, which multiplied by `32` gives us exactly `42.0000001`.\n\nWe'll revisit more details about floating-point (im)precision in Chapter 2. But now you understand a *bit more* about how IEEE-754 works!\n\n### Number Limits\n\nAs might be evident now that you've seen how IEEE-754 works, the 52 bits of the number's base must be shared, representing both the whole number portion (if any) as well as the decimal portion (if any), of the intended `number` value. Essentially, the larger the whole number portion to be represented, the less bits are available for the decimal portion, and vice versa.\n\nThe largest value that can accurately be stored in the `number` type is exposed as `Number.MAX_VALUE`:\n\n```js\nNumber.MAX_VALUE;           // 1.7976931348623157e+308\n```\n\nYou might expect that value to be a decimal value, given the representation. But on closer inspection, `1.79E308` is (approximately) `2^1024 - 1`. That seems much more like it should be an integer, right? We can verify:\n\n```js\nNumber.isInteger(Number.MAX_VALUE);         // true\n```\n\nBut what happens if you go above the max value?\n\n```js\nNumber.MAX_VALUE === (Number.MAX_VALUE + 1);\n// true -- oops!\n\nNumber.MAX_VALUE === (Number.MAX_VALUE + 10000000);\n// true\n```\n\nSo, is `Number.MAX_VALUE` actually the largest value representable in JS? It's certainly the largest *finite* `number` value.\n\nIEEE-754 defines a special infinite value, which JS exposes as `Infinity`; there's also a `-Infinity` at the far other end of the number line. Values can be tested to see if they are finite or infinite:\n\n```js\nNumber.isFinite(Number.MAX_VALUE);  // true\n\nNumber.isFinite(Infinity);          // false\nNumber.isFinite(-Infinity);         // false\n```\n\nYou can't ever count upwards (with `+ 1`) from `Number.MAX_VALUE` to `Infinity`, no matter how long you let the program run, because the `+ 1` operation isn't actually incrementing beyond the top `Number.MAX_VALUE` value.\n\nHowever, JS arithmetic operations (`+`, `*`, and even `/`) can definitely overflow the `number` type on the top-end, in which case `Infinity` is the result:\n\n```js\nNumber.MAX_VALUE + 1E291;           // 1.7976931348623157e+308\nNumber.MAX_VALUE + 1E292;           // Infinity\n\nNumber.MAX_VALUE * 1.0000000001;    // Infinity\n\n1 / 1E-308;                         // 1e+308\n1 / 1E-309;                         // Infinity\n```\n\n| TIP: |\n| :--- |\n| The reverse is not true: an arithmetic operation on an infinite value *will never* produce a finite value. |\n\nGoing from the very large to the very, very small -- actually, closest to zero, which is not the same thing as going very, very negative! -- the smallest absolute decimal value you could theoretically store in the `number` type would be `2^-1022` (remember the IEEE-754 exponent range?), or around `2E-308`. However, JS engines are allowed by the specification to vary in their internal representations for this lower limit. Whatever the engine's effective lower limit is, it'll be exposed as `Number.MIN_VALUE`:\n\n```js\nNumber.MIN_VALUE;               // 5e-324 <-- usually!\n```\n\nMost JS engines seem to have a minimum representable value around `5E-324` (about `2^-1074`). Depending on the engine and/or platform, a different value may be exposed. Be careful about any program logic that relies on such implementation-dependent values.\n\n### Safe Integer Limits\n\nSince `Number.MAX_VALUE` is an integer, you might assume that it's the largest integer in the language. But that's not really accurate.\n\nThe largest integer you can accurately store in the `number` type is `2^53 - 1`, or `9007199254740991`, which is *way smaller* than `Number.MAX_VALUE` (about `2^1024 - 1`). This special safer value is exposed as `Number.MAX_SAFE_INTEGER`:\n\n```js\nmaxInt = Number.MAX_SAFE_INTEGER;\n\nmaxInt;             // 9007199254740991\n\nmaxInt + 1;         // 9007199254740992\n\nmaxInt + 2;         // 9007199254740992\n```\n\nWe've seen that integers larger than `9007199254740991` can show up. However, those larger integers are not \"safe\", in that the precision/accuracy start to break down when you do operations with them. As shown above, the `maxInt + 1` and `maxInt + 2` expressions both errantly give the same result, illustrating the hazard when exceeding the `Number.MAX_SAFE_INTEGER` limit.\n\nBut what's the smallest safe integer?\n\nDepending on how you interpret \"smallest\", you could either answer `0` or... `Number.MIN_SAFE_INTEGER`:\n\n```js\nNumber.MIN_SAFE_INTEGER;    // -9007199254740991\n```\n\nAnd JS provides a utility to determine if a value is an integer in this safe range (`-2^53 + 1` - `2^53 - 1`):\n\n```js\nNumber.isSafeInteger(2 ** 53);      // false\nNumber.isSafeInteger(2 ** 53 - 1);  // true\n```\n\n### Double Zeros\n\nIt may surprise you to learn that JS has two zeros: `0`, and `-0` (negative zero). But what on earth is a \"negative zero\"? [^SignedZero] A mathematician would surely balk at such a notion.\n\nThis isn't just a funny JS quirk; it's mandated by the IEEE-754[^IEEE754] specification. All floating point numbers are signed, including zero. And though JS does kind of hide the existence of `-0`, it's entirely possible to produce it and to detect it:\n\n```js\nfunction isNegZero(v) {\n    return v == 0 && (1 / v) == -Infinity;\n}\n\nregZero = 0 / 1;\nnegZero = 0 / -1;\n\nregZero === negZero;        // true -- oops!\nObject.is(-0,regZero);      // false -- phew!\nObject.is(-0,negZero);      // true\n\nisNegZero(regZero);         // false\nisNegZero(negZero);         // true\n```\n\nYou may wonder why we'd ever need such a thing as `-0`. It can be useful when using numbers to represent both the magnitude of movement (speed) of some item (like a game character or an animation) and also its direction (e.g., negative = left, positive = right).\n\nWithout having a signed zero value, you couldn't tell which direction such an item was pointing at the moment it came to rest.\n\n| NOTE: |\n| :--- |\n| While JS defines a signed zero in the `number` type, there is no corresponding signed zero in the `bigint` number type. As such, `-0n` is just interpreted as `0n`, and the two are indistinguishable. |\n\n### Invalid Number\n\nMathematical operations can sometimes produce an invalid result. For example:\n\n```js\n42 / \"Kyle\";            // NaN\n```\n\nIt's probably obvious, but if you try to divide a number by a string, that's an invalid mathematical operation.\n\nAnother type of invalid numeric operation is trying to coercively-convert a non-numeric resembling value to a `number`. As discussed earlier, we can do so with either the `Number(..)` function or the unary `+` operator:\n\n```js\nmyAge = Number(\"just a number\");\n\nmyAge;                  // NaN\n\n+undefined;             // NaN\n```\n\nAll such invalid operations (mathematical or coercive/numeric) produce the special `number` value called `NaN`.\n\nThe historical root of \"NaN\" (from the IEEE-754[^IEEE754] specification) is as an acronym for \"Not a Number\". Technically, there are about 9 quadrillion values in the 64-bit IEEE-754 number space designated as \"NaN\", but JS treats all of them indistinguishably as the single `NaN` value.\n\nUnfortunately, that *not a number* meaning produces confusion, since `NaN` is *absolutely* a `number`.\n\n| TIP: |\n| :--- |\n| Why is `NaN` a `number`?!? Think of the opposite: what if a mathematical/numeric operation, like `+` or `/`, produced a non-`number` value (like `null`, `undefined`, etc)? Wouldn't that be really strange and unexpected? What if they threw exceptions, so that you had to `try..catch` all your math? The only sensible behavior is, numeric/mathematical operations should *always* produce a `number`, even if that value is invalid because it came from an invalid operation. |\n\nTo avoid such confusion, I strongly prefer to define \"NaN\" as any of the following instead:\n\n* \"iNvalid Number\"\n* \"Not actual Number\"\n* \"Not available Number\"\n* \"Not applicable Number\"\n\n`NaN` is a special value in JS, in that it's the only value in the language that lacks the *identity property* -- it's never equal to itself.\n\n```js\nNaN === NaN;            // false\n```\n\nSo unfortunately, the `===` operator cannot check a value to see if it's `NaN`. But there are some ways to do so:\n\n```js\npoliticianIQ = \"nothing\" / Infinity;\n\nNumber.isNaN(politicianIQ);         // true\n\nObject.is(NaN,politicianIQ);        // true\n[ NaN ].includes(politicianIQ);     // true\n```\n\nHere's a fact of virtually all JS programs, whether you realize it or not: `NaN` happens. Seriously, almost all programs that do any math or numeric conversions are subject to `NaN` showing up.\n\nIf you're not properly checking for `NaN` in your programs where you do math or numeric conversions, I can say with some degree of certainty: you probably have a number bug in your program somewhere, and it just hasn't bitten you yet (that you know of!).\n\n| WARNING: |\n| :--- |\n| JS originally provided a global function called `isNaN(..)` for `NaN` checking, but it unfortunately has a long-standing coercion bug. `isNaN(\"Kyle\")` returns `true`, even though the string value `\"Kyle\"` is most definitely *not* the `NaN` value. This is because the global `isNaN(..)` function forces any non-`number` argument to coerce to a `number` first, before checking for `NaN`. Coercing `\"Kyle\"` to a `number` produces `NaN`, so now the function sees a `NaN` and returns `true`! This buggy global `isNaN(..)` still exists in JS, but should never be used. When `NaN` checking, always use `Number.isNaN(..)`, `Object.is(..)`, etc. |\n\n## BigInteger Values\n\nAs the maximum safe integer in JS `number`s is `9007199254740991` (see above), such a relatively low limit can present a problem if a JS program needs to perform larger integer math, or even just hold values like 64-bit integer IDs (e.g., Twitter Tweet IDs).\n\nFor that reason, JS provides the alternate `bigint` type (BigInteger), which can store arbitrarily large (theoretically not limited, except by finite machine memory and/or JS implementation) integers.\n\nTo distinguish a `bigint` from a whole (integer) `number` value, which would otherwise both look the same (`42`), JS requires an `n` suffix on `bigint` values:\n\n```js\nmyAge = 42n;        // this is a bigint, not a number\n\nmyKidsAge = 11;     // this is a number, not a bigint\n```\n\nLet's illustrate the upper un-boundedness of `bigint`:\n\n```js\nNumber.MAX_SAFE_INTEGER;        // 9007199254740991\n\nNumber.MAX_SAFE_INTEGER + 2;    // 9007199254740992 -- oops!\n\nmyBigInt = 9007199254740991n;\n\nmyBigInt + 2n;                  // 9007199254740993n -- phew!\n\nmyBigInt ** 2n;                 // 81129638414606663681390495662081n\n```\n\nAs you can see, the `bigint` value-type is able to do precise arithmetic above the integer limit of the `number` value-type.\n\n| WARNING: |\n| :--- |\n| Notice that the `+` operator required `.. + 2n` instead of just `.. + 2`? You cannot mix `number` and `bigint` value-types in the same expression. This restriction is annoying, but it protects your program from invalid mathematical operations that would give non-obvious unexpected results. |\n\nA `bigint` value can also be created with the `BigInt(..)` function; for example, to convert a whole (integer) `number` value to a `bigint`:\n\n```js\nmyAge = 42n;\n\ninc = 1;\n\nmyAge += BigInt(inc);\n\nmyAge;              // 43n\n```\n\n| WARNING: |\n| :--- |\n| Though it may seem counter-intuitive to some readers, `BigInt(..)` is *always* called without the `new` keyword. If `new` is used, an exception will be thrown. |\n\nThat's definitely one of the most common usages of the `BigInt(..)` function: to convert `number`s to `bigint`s, for mathematical operation purposes.\n\nBut it's not that uncommon to represent large integer values as strings, especially if those values are coming to the JS environment from other language environments, or via certain exchange formats, which themselves do not support `bigint`-style values.\n\nAs such, `BigInt(..)` is useful to coerce those string values to `bigint`s:\n\n```js\nmyBigInt = BigInt(\"12345678901234567890\");\n\nmyBigInt;                       // 12345678901234567890n\n```\n\nUnlike `parseInt(..)`, if any character in the string is non-numeric (`0-9` digits or `-`), including `.` or even a trailing `n` suffix character, an exception will be thrown. In other words, `BigInt(..)` is an all-or-nothing coercion-conversion, not a parsing-conversion.\n\n| NOTE: |\n| :--- |\n| I think it's absurd that `BigInt(..)` won't accept the trailing `n` character while string coercing (and thus effectively ignore it). I lobbied vehemently for that behavior, in the TC39 process, but was ultimately denied. In my opinion, it's now a tiny little gotcha wart on JS, but a wart nonetheless. |\n\n## Symbol Values\n\nThe `symbol` type contains special opaque values called \"symbols\". These values can only be created by the `Symbol(..)` function:\n\n```js\nsecret = Symbol(\"my secret\");\n```\n\n| WARNING: |\n| :--- |\n| Just as with `BigInt(..)`, the `Symbol(..)` function must be called without the `new` keyword. |\n\nThe `\"my secret\"` string passed into the `Symbol(..)` function call is *not* the symbol value itself, even though it seems that way. It's merely an optional descriptive label, used only for debugging purposes for the benefit of the developer.\n\nThe underlying value returned from `Symbol(..)` is a special kind of value that resists the program/developer inspecting anything about its underlying representation. That's what I mean by \"opaque\".\n\n| NOTE: |\n| :--- |\n| You could think of symbols as if they are monotonically incrementing integer numbers -- indeed, that's similar to how at least some JS engines implement them. But the JS engine will never expose any representation of a symbol's underlying value in any way that you or the program can see. |\n\nSymbols are guaranteed by the JS engine to be unique (only within the program itself), and are unguessable. In other words, a duplicate symbol value can never be created in a program.\n\nYou might be wondering at this point what symbols are used for?\n\nOne typical usage is as \"special\" values that the developer distinguishes from any other values that could accidentally collide. For example:\n\n```js\nEMPTY = Symbol(\"not set yet\");\nmyNickname = EMPTY;\n\n// later:\n\nif (myNickname == EMPTY) {\n    // ..\n}\n```\n\nHere, I've defined a special `EMPTY` value and initialized `myNickname` to it. Later, I check to see if it's still that special value, and then perform some action if so. I might not want to have used `null` or `undefined` for such purposes, as another developer might be able to pass in one of those common built-in values. `EMPTY` by contrast here is a unique, unguessable value that only I've defined and have control over and access to.\n\nPerhaps even more commonly, symbols are often used as special (meta-) properties on objects:\n\n```js\nmyInfo = {\n    name: \"Kyle Simpson\",\n    nickname: \"getify\",\n    age: 42\n};\n\n// later:\nPRIVATE_ID = Symbol(\"private unique ID, don't touch!\");\n\nmyInfo[PRIVATE_ID] = generateID();\n```\n\nIt's important to note that symbol properties are still publicly visible on any object; they're not *actually* private. But they're treated as special and set-apart from the normal collection of object properties. It's similar to if I had done instead:\n\n```js\nObject.defineProperty(myInfo,\"__private_id_dont_touch\",{\n    value: generateID(),\n    enumerable: false,\n});\n```\n\nBy convention only, most developers know that if a property name is prefixed with `_` (or even more so, `__`!), that means it's \"pseudo-private\" and to leave it alone unless they're really supposed to access it.\n\nSymbols basically serve the same use-case, but a bit more ergonomically than the prefixing approach.\n\n### Well-Known Symbols (WKS)\n\nJS pre-defines a set of symbols, referred to as *well-known symbols* (WKS), that represent certain special meta-programming hooks on objects. These symbols are stored as static properties on the `Symbol` function object. For example:\n\n```js\nmyInfo = {\n    // ..\n};\n\nString(myInfo);         // [object Object]\n\nmyInfo[Symbol.toStringTag] = \"my-info\";\nString(myInfo);         // [object my-info]\n```\n\n`Symbol.toStringTag` is a well-known symbol for accessing and overriding the default string representation of a plain object (`\"[object Object]\"`), replacing the `\"Object\"` part with a different value (e.g., `\"my-info\"`).\n\nSee the \"Objects & Classes\" book of this series for more information about Well-Known Symbols and metaprogramming.\n\n### Global Symbol Registry\n\nOften, you want to keep symbol values private, such as inside a module scope. But occasionally, you want to expose them so they're accessible globally throughout all the files in a JS program.\n\nInstead of just attaching them as global variables (i.e., properties on the `globalThis` object), JS provides an alternate *global namespace* to register symbols in:\n\n```js\n// retrieve if already registered,\n// otherwise register\nPRIVATE_ID = Symbol.for(\"private-id\");\n\n// elsewhere:\n\nprivateIDKey = Symbol.keyFor(PRIVATE_ID);\nprivateIDKey;           // \"private-id\"\n\n// elsewhere:\n\n// retrieve symbol from registry undeer\n// specified key\nprivateIDSymbol = Symbol.for(privateIDKey);\n```\n\nThe value passed to `Symbol.for(..)` is *not* the same as passed to `Symbol(..)`. `Symbol.for(..)` expects a unique *key* for the symbol to be registered under in the global registry, whereas `Symbol(..)` optionally accepts a descriptive label (not necessarily unique).\n\nIf the registry doesn't have a symbol under that specified *key*, a new symbol (with no descriptive label) is created and automatically registered there. Otherwise, `Symbol.for(..)` returns whatever previously registered symbol is under that *key*.\n\nGoing in the opposite direction, if you have the symbol value itself, and want to retrieve the *key* it's registered under, `Symbol.keyFor(..)` takes the symbol itself as input, and returns the *key* (if any). That's useful in case it's more convenient to pass around the *key* string value than the symbol itself.\n\n### Object or Primitive?\n\nUnlike other primitives like `42`, where you can create multiple copies of the same value, symbols *do* act more like specific object references in that they're always completely unique (for purposes of value assignment and equality comparison). The specification also categorizes the `Symbol()` function under the \"Fundamental Objects\" section, calling the function a \"constructor\", and even defining its `prototype` property.\n\nHowever, as mentioned earlier, `new` cannot be used with `Symbol(..)`; this is similar to the `BigInt()` \"constructor\". We clearly know `bigint` values are primitives, so `symbol` values seem to be of the same *kind*.\n\nAnd in the specification's \"Terms and Definitions\", it lists symbol as a primitive value. [^PrimitiveValues] Moreover, the values themselves are used in JS programs as primitives rather than objects. For example, symbols are primarily used as keys in objects -- we know objects cannot use other object values as keys! -- along with strings, which are also primitives.\n\nAs mentioned earlier, some JS engines even internally implement symbols as unique, monotonically incrementing integers (primitives!).\n\nFinally, as explained at the top of this chapter, we know primitive values are *not allowed* to have properties set on them, but are *auto-boxed* (see \"Automatic Objects\" in Chapter 3) internally to the corresponding object-wrapper type to facilitate property/method access. Symbols follow all these exact behaviors, the same as all the other primitives.\n\nAll this considered, I think symbols are *much more* like primitives than objects, so that's how I present them in this book.\n\n## Primitives Are Built-In Types\n\nWe've now dug deeply into the seven primitive (non-object) value types that JS provides automatically built-in.\n\nBefore we move on to discussing JS's built-in object value type, we want to take a closer look at the kinds of behaviors we can expect from JS values. We'll do so in-depth, in the next chapter.\n\n[^PrimitiveValues]: \"4.4.5 primitive value\", ECMAScript 2022 Language Specification; https://tc39.es/ecma262/#sec-primitive-value ; Accessed August 2022\n\n[^UTFUCS]: \"JavaScript’s internal character encoding: UCS-2 or UTF-16?\"; Mathias Bynens; January 20 2012; https://mathiasbynens.be/notes/javascript-encoding ; Accessed July 2022\n\n[^IEEE754]: \"IEEE-754\"; https://en.wikipedia.org/wiki/IEEE_754 ; Accessed July 2022\n\n[^NumberType]: \"6.1.6.1 The Number Type\", ECMAScript 2022 Language Specification; https://262.ecma-international.org/13.0/#sec-ecmascript-language-types-number-type ; Accessed August 2022\n\n[^SignedZero]: \"Signed Zero\", Wikipedia; https://en.wikipedia.org/wiki/Signed_zero ; Accessed August 2022\n"
  },
  {
    "path": "types-grammar/ch2.md",
    "content": "# You Don't Know JS Yet: Types & Grammar - 2nd Edition\n# Chapter 2: Primitive Behaviors\n\n| NOTE: |\n| :--- |\n| Work in progress |\n\nSo far, we've explored seven built-in primitive value types in JS: `null`, `undefined`, `boolean`, `string`, `number`, `bigint`, and `symbol`.\n\nChapter 1 was quite a lot to take in, much more involved than I bet most readers expected. If you're still catching your breath after reading all that, don't worry about taking a bit of a break before continuing on here!\n\nOnce you're clear headed and ready to move on, let's dig into certain behaviors implied by value types for all their respective values. We'll take a careful and  closer look at all of these various behaviors.\n\n## Primitive Immutability\n\nAll primitive values are immutable, meaning nothing in a JS program can reach into the contents of the value and modify it in any way.\n\n```js\nmyAge = 42;\n\n// later:\n\nmyAge = 43;\n```\n\nThe `myAge = 43` statement doesn't change the value. It reassigns a different value `43` to `myAge`, completely replacing the previous value of `42`.\n\nNew values are also created through various operations, but again these do not modify the original value:\n\n```js\n42 + 1;             // 43\n\n\"Hello\" + \"!\";      // \"Hello!\"\n```\n\nThe values `43` and `\"Hello!\"` are new, distinct values from the previous `42` and `\"Hello\"` values, respectively.\n\nEven a string value, which looks like merely an array of characters -- and array contents are typically mutable -- is immutable:\n\n```js\ngreeting = \"Hello.\";\n\ngreeting[5] = \"!\";\n\nconsole.log(greeting);      // Hello.\n```\n\n| WARNING: |\n| :--- |\n| In non-strict mode, assigning to a read-only property (like `greeting[5] = ..`) silently fails. In strict-mode, the disallowed assignment will throw an exception. |\n\nThe nature of primitive values being immutable is not affected *in any way* by how the variable or object property holding the value is declared. For example, whether `const`, `let`, or `var` are used to declare the `greeting` variable above, the string value it holds is immutable.\n\n`const` doesn't create immutable values, it declares variables that cannot be reassigned (aka, immutable assignments) -- see the \"Scope & Closures\" title of this series for more information.\n\nA property on an object may be marked as read-only -- with the `writable: false` descriptor attribute, as discussed in the \"Objects & Classes\" title of this series. But that still has no affect on the nature of the value, only on preventing the reassignment of the property.\n\n### Primitives With Properties?\n\nAdditionally, properties *cannot* be added to any primitive values:\n\n```js\ngreeting = \"Hello.\";\n\ngreeting.isRendered = true;\n\ngreeting.isRendered;        // undefined\n```\n\nThis snippet looks like it's adding a property `isRendered` to the value in `greeting`, but this assignment silently fails (even in strict-mode).\n\nProperty access is not allowed in any way on nullish primitive values `null` and `undefined`. But properties *can* be accessed on all other primitive values -- yes, that sounds counter-intuitive.\n\nFor example, all string values have a read-only `length` property:\n\n```js\ngreeting = \"Hello.\";\n\ngreeting.length;            // 6\n```\n\n`length` can not be set, but it can be accesses, and it exposes the number of code-units stored in the value (see \"JS Character Encodings\" in Chapter 1), which often means the number of characters in the string.\n\n| NOTE: |\n| :--- |\n| Sort of. For most standard characters, that's true; one character is one code-point, which is one code-unit. However, as explained in Chapter 1, extended Unicode characters above code-point `65535` will be stored as two code-units (surrogate halves). Thus, for each such character, `length` will include `2` in its count, even though the character visually prints as one symbol. |\n\nNon-nullish primitive values also have a couple of standard built-in methods that can be accessed:\n\n```js\ngreeting = \"Hello.\";\n\ngreeting.toString();    // \"Hello.\" <-- redundant\ngreeting.valueOf();     // \"Hello.\"\n```\n\nAdditionally, most of the primitive value-types define their own methods with specific behaviors inherent to that type. We'll cover these later in this chapter.\n\n| NOTE: |\n| :--- |\n| As already briefly mentioned in Chapter 1, technically, these sorts of property/method accesses on primitive values are facilitated by an implicit coercive behavior called *auto-boxing*. We'll cover this in detail in \"Automatic Objects\" in Chapter 3. |\n\n## Primitive Assignments\n\nAny assignment of a primitive value from one variable/container to another is a *value-copy*:\n\n```js\nmyAge = 42;\n\nyourAge = myAge;        // assigned by value-copy\n\nmyAge;                  // 42\nyourAge;                // 42\n```\n\nHere, the `myAge` and `yourAge` variables each have their own copy of the number value `42`.\n\n| NOTE: |\n| :--- |\n| Inside the JS engine, it *may* be the case that only one `42` value exists in memory, and the engine points both `myAge` and `yourAge` variables at the shared value. Since primitive values are immutable, there's no danger in a JS engine doing so. But what's important to us as JS developers is, in our programs, `myAge` and `yourAge` act as if they have their own copy of that value, rather than sharing it. |\n\nIf we later reassign `myAge` to `43` (when I have a birthday), it doesn't affect the `42` that's still assigned to `yourAge`:\n\n```js\nmyAge++;            // sort of like: myAge = myAge + 1\n\nmyAge;              // 43\nyourAge;            // 42 <-- unchanged\n```\n\n## String Behaviors\n\nString values have a number of specific behaviors that every JS developer should be aware of.\n\n### String Character Access\n\nThough strings are not actually arrays, JS allows `[ .. ]` array-style access of a character at a numeric (`0`-based) index:\n\n```js\ngreeting = \"Hello!\";\n\ngreeting[4];            // \"o\"\n```\n\nIf the value/expression between the `[ .. ]` doesn't resolve to a number, the value will be implicitly coerced to its whole/integer numeric representation (if possible).\n\n```js\ngreeting[\"4\"];          // \"o\"\n```\n\nIf the value/expression resolves to a number outside the integer range of `0` - `length - 1` (or `NaN`), or if it's not a `number` value-type, the access will instead be treated as a property access with the string equivalent property name. If the property access thus fails, the result is `undefined`.\n\n| NOTE: |\n| :--- |\n|  We'll cover coercion in-depth later in the book. |\n\n### Character Iteration\n\nStrings are not arrays, but they certainly mimic arrays closely in many ways. One such behavior is that, like arrays, strings are iterables. This means that the characters (code-units) of a string can be iterated individually:\n\n```js\nmyName = \"Kyle\";\n\nfor (let char of myName) {\n    console.log(char);\n}\n// K\n// y\n// l\n// e\n\nchars = [ ...myName ];\nchars;\n// [ \"K\", \"y\", \"l\", \"e\" ]\n```\n\nValues, such as strings and arrays, are iterables (via `...`, `for..of`, and `Array.from(..)`), if they expose an iterator-producing method at the special symbol property location `Symbol.iterator` (see \"Well-Known Symbols\" in Chapter 1):\n\n```js\nmyName = \"Kyle\";\nit = myName[Symbol.iterator]();\n\nit.next();      // { value: \"K\", done: false }\nit.next();      // { value: \"y\", done: false }\nit.next();      // { value: \"l\", done: false }\nit.next();      // { value: \"e\", done: false }\nit.next();      // { value: undefined, done: true }\n```\n\n| NOTE: |\n| :--- |\n| The specifics of the iterator protocol, including the fact that the `{ value: \"e\" .. }` result still shows `done: false`, are covered in detail in the \"Sync & Async\" title of this series. |\n\n### Length Computation\n\nAs mentioned in Chapter 1, string values have a `length` property that automatically exposes the length of the string; this property can only be accessed; attempts to set it are silently ignored.\n\nThe reported `length` value somewhat corresponds to the number of characters in the string (actually, code-units), but as we saw in Chapter 1, it's more complex when Unicode characters are involved.\n\nMost people visually distinguish symbols as separate characters; this notion of an independent visual symbol is referred to as a *grapheme*, or a *grapheme cluster*. So when counting the \"length\" of a string, we typically mean that we're counting the number of graphemes.\n\nBut that's not how the computer deals with characters.\n\nIn JS, each *character* is a code-unit (16 bits), with a code-point value at or below `65535`. The `length` property of a string always counts the number of code-units in the string value, not code-points. A code-unit might represent a single character by itself, or it may be part of a surrogate pair, or it may be combined with an adjacent *combining* symbol, or part of a grapheme cluster. As such, `length` doesn't match the typical notion of counting visual characters/graphemes.\n\nTo get closer to an expected/intuitive *grapheme length* for a string, the string value first needs to be normalized with `normalize(\"NFC\")` (see \"Normalizing Unicode\" in Chapter 1) to produce any *composed* code-units (where possible), in case any characters were originally stored *decomposed* as separate code-units.\n\nFor example:\n\n```js\nfavoriteItem = \"teléfono\";\nfavoriteItem.length;            // 9 -- uh oh!\n\nfavoriteItem = favoriteItem.normalize(\"NFC\");\nfavoriteItem.length;            // 8 -- phew!\n```\n\nUnfortunately, as we saw in Chapter 1, we'll still have the possibility of characters of code-point greater the `65535`, and thus needing a surrogate pair to be represented. Such characters will count double in the `length`:\n\n```js\n// \"☎\" === \"\\u260E\"\noldTelephone = \"☎\";\noldTelephone.length;            // 1\n\n// \"📱\" === \"\\u{1F4F1}\" === \"\\uD83D\\uDCF1\"\ncellphone = \"📱\";\ncellphone.length;               // 2 -- oops!\n```\n\nSo what do we do?\n\nOne fix is to use character iteration (via `...` operator) as we saw in the previous section, since it automatically returns each combined character from a surrogate pair:\n\n```js\ncellphone = \"📱\";\ncellphone.length;               // 2 -- oops!\n[ ...cellphone ].length;        // 1 -- phew!\n```\n\nBut, unfortunately, grapheme clusters (as explained in Chapter 1) throw yet another wrench into a string's length computation. For example, if we take the thumbs down emoji (`\"\\u{1F44E}\"` and add to it the skin-tone modifier for medium-dark skin (`\"\\u{1F3FE}\"`), we get:\n\n```js\n// \"👎🏾\" = \"\\u{1F44E}\\u{1F3FE}\"\nthumbsDown = \"👎🏾\";\n\nthumbsDown.length;              // 4 -- oops!\n[ ...thumbsDown ].length;       // 2 -- oops!\n```\n\nAs you can see, these are two distinct code-points (not a surrogate pair) that, by virtue of their ordering and adjacency, cause the computer's Unicode rendering to draw the thumbs-down symbol but with a darker skin tone than its default. The computed string length is thus `2`.\n\nIt would take replicating most of a platform's complex Unicode rendering logic to be able to recognize such clusters of code-points as a single \"character\" for length-counting sake. There are libraries that purport to do so, but they're not necessarily perfect, and they come at a hefty cost in terms of extra code.\n\n| NOTE: |\n| :--- |\n| As a Twitter user, you might expect to be able to put 280 thumbs-down emojis into a single tweet, since it looks like a single character. Twitter counts the `\"👎\"` (default thumbs-down), the `\"👎🏾\"` (medium-dark-skintone thumbs-down), and even the `\"👩‍👩‍👦‍👦\"` (family emoji grapheme cluster) all as 2 characters each, even though their respective string lengths (from JS's perspective) are `2`, `4`, and `7`; thus, you can only fit half the number of emojis (140 instead of 280) in a tweet. In fact, Twitter implemented this change in 2018 to specifically level the counting of all Unicode characters, at 2 characters per symbol. [^TwitterUnicode] That was a welcomed change for Twitter users, especially those who want to use emoji characters that are most representative of intended gender, skintone, etc. Still, it *is* curious that Twitter chose to count all Unicode/emoji symbols as 2 characters each, instead of the more intuitive 1 character (grapheme) each. |\n\nCounting the *length* of a string to match our human intuitions is a remarkably challenging task, perhaps more of an art than a science. We can get acceptable approximations in many cases, but there's plenty of other cases that may confound our programs.\n\n### Internationalization (i18n) and Localization (l10n)\n\nTo serve the growing need for JS programs to operate as expected in any international language/culture context, the ECMAScript committee also publishes the ECMAScript Internationalization API. [^INTLAPI]\n\nA JS program defaults to a locale/language according to the environment running the program (web browser page, Node instance, etc). The in-effect locale affects sorting (and value comparisons), formatting, and several other assumed behaviors. Such altered behaviors are perhaps a bit more obvious with strings, but they can also be seen with numbers (and dates!).\n\nBut string characters also can have language/locale information embedded in them, which takes precedence over the environment default. If the string character is ambiguous/shared in terms of its language/locale (such as `\"a\"`), the default environment setting is used.\n\nDepending on the contents of the string, it may be interpreted as being ordered from left-to-right (LTR) or right-to-left (RTL). As such, many of the string methods we'll cover later use logical descriptors in their names, like \"start\", \"end\", \"begin\", \"end\", and \"last\", rather than directional terms like \"left\" and \"right\".\n\nFor example, Hebrew and Arabic are both common RTL languages:\n\n```js\nhebrewHello = \"\\u{5e9}\\u{5dc}\\u{5d5}\\u{5dd}\";\n\nconsole.log(hebrewHello);                       // שלום\n```\n\nNotice that the first listed character in the string literal (`\"\\u{5e9}\"`) is actually the right-most character when the string is rendered?\n\nEven though Hebrew is an RTL language, you don't actually type the characters in the string literal in reversed (RTL) order the way they should be rendered. You enter the characters in logical order, where position `0` is the first character, position `1` is the second character, etc. The rendering layer is where RTL characters are reversed to be shown in their correct order.\n\nThat also means that if you access `hebrewHello[0]` (or `hebrewHello.charAt(0)`) -- to get the character as position `0` -- you get `\"ש\"` because that's logically the first character of the string, not `\"ם\"` (logically the last character of the string). Index-positional access follows the logical position, not the rendered position.\n\nHere's the same example in another RTL language, Arabic:\n\n```js\narabicHello = \"\\u{631}\\u{62d}\\u{628}\\u{627}\";\n\nconsole.log(arabicHello);                       // رحبا\n\nconsole.log(arabicHello[0]);                    // ر\n```\n\nJS programs can force a specific language/locale, using various `Intl` APIs such as `Intl.Collator`: [^INTLCollator]\n\n```js\ngermanStringSorter = new Intl.Collator(\"de\");\n\nlistOfGermanWords = [ /* .. */ ];\n\ngermanStringSorter.compare(\"Hallo\",\"Welt\");\n// -1 (or negative number)\n\n// examples adapted from MDN:\n//\ngermanStringSorter.compare(\"Z\",\"z\");\n// 1 (or positive number)\n\ncaseFirstSorter = new Intl.Collator(\"de\",{ caseFirst: \"upper\", });\ncaseFirstSorter.compare(\"Z\",\"z\");\n// -1 (or negative number)\n```\n\nMultiple-word strings can be segmented using `Intl.Segmenter`: [^INTLSegmenter]\n\n```js\narabicHelloWorld = \"\\u{645}\\u{631}\\u{62d}\\u{628}\\u{627} \\\n\\u{628}\\u{627}\\u{644}\\u{639}\\u{627}\\u{644}\\u{645}\";\n\nconsole.log(arabicHelloWorld);      // مرحبا بالعالم\n\narabicSegmenter = new Intl.Segmenter(\"ar\",{ granularity: \"word\" });\n\nfor (\n    let { segment: word, isWordLike } of\n    arabicSegmenter.segment(arabicHelloWorld)\n) {\n    if (isWordLike) {\n        console.log(word);\n    }\n}\n// مرحبا\n//لعالم\n```\n\n| NOTE: |\n| :--- |\n| The `segment(..)` method (from instances of`Intl.Segmenter`) returns a standard JS iterator, which the `for..of` loop here consumes. More on iteration protocols in the \"Sync & Async\" title of this series. |\n\n### String Comparison\n\nString values can be compared (for both equality and relational ordering) to other string values, using various built-in operators. It's important to keep in mind that such comparisons are sensitive to the actual string contents, including especially the underlying code-points from non-BPM Unicode characters.\n\nBoth equality and relational comparison are case-sensitive, for any characters where uppercase and lowercase are well-defined. To make case-insensitive comparisons, normalize the casing of both values first (with `toUpperCase()` or `toLowerCase()`).\n\n#### String Equality\n\nThe `===` and `==` operators (along with their negated counterparts `!==` and `!=`, respectively) are the most common way equality comparisons are made for primitive values, including string values:\n\n```js\n\"my name\" === \"my n\\x61me\";               // true\n\n\"my name\" !== String.raw`my n\\x61me`;     // true\n```\n\nThe `===` operator[^StrictEquality] -- often referred to as \"strict equality\" -- first checks to see if the types match, and if not, returns `false` right away. If the types match, then it checks to see if the values are the same; for strings, this is a per-code-unit comparison, from start to end.\n\nDespite the \"strict\" naming, there are nuances to `===` (such as `-0` and `NaN` handling), but we'll cover those later.\n\n##### Coercive Equality\n\nBy contrast, the `==` operator[^LooseEquality] -- often referred to as \"loose equality\" -- performs *coercive equality*: if the value-types of the two operands do not match, `==` first coerces one or both operands until the value-types *do* match, and then it hands off the comparison internally to `===`.\n\nCoercion is an extremely important topic -- it's an inherent part of the JS types system, one of the language's 3 pillars -- but we're only going to briefly introduce it here in this chapter, and revisit it in detail later.\n\n| NOTE: |\n| :--- |\n| You may have heard the oft-quoted, but nevertheless inaccurate, explanation that the difference between `==` and `===` is that `==` compares the values while `==` compares both the values and the types. Not true, and you can read the spec yourself to verify -- both `isStrictlyEqual(..)` and `isLooselyEqual(..)` specification algorithms are linked as footnotes in the preceding paragraphs. To summarize, though: both `==` and `===` are aware of and sensitive to the types of the operands. If the operand types are the same, both operators do literally the exact same thing; if the types differ, `==` forces coercion until the types match, whereas `===` returns `false` immediately. |\n\nIt's extremely common for developers to assert that the `==` operator is confusing and too hard to use without surprises (thus the near universal preference for `===`). I think that's totally bogus, and in fact, JS developers should be defaulting to `==` (and avoiding `===` if possible). But we need a lot more discussion to back such a controversial statement; hold onto your objections until we revisit it later.\n\nFor now, to gain some intuition about the coercive nature of `==`, the most illuminating observation is that if the types don't match, `==` *prefers* numeric comparison. That means it will attempt to convert both operands to numbers, and then perform the equality check (the same as `===`).\n\nSo, as it relates to our present discussion, actual string equality can *only be* checked if both operands are already strings:\n\n```js\n// actual string equality check (via === internally):\n\"42\" == \"42\";           // true\n```\n\n`==` does not really perform string equality checks itself. If the operand value-types are both strings, `==` just hands off the comparison to `===`. If they're not both strings, the coercive steps in `==` will reduce the comparison matching to numeric instead of string:\n\n```js\n// numeric (not string!) equality check:\n42 == \"42\";             // true\n```\n\nWe'll cover numeric equality later in this chapter.\n\n##### *Really* Strict Equality\n\nIn addition to `==` and `===`, JS provides the `Object.is(..)` utility, which returns `true` if both arguments are *exactly identical*, and `false` otherwise (no exceptions or nuances):\n\n```js\nObject.is(\"42\",42);             // false\n\nObject.is(\"42\",\"\\x34\\x32\");     // true\n```\n\nSince `===` adds a `=` onto the end of `==` to make it more strict in behavior, I kind of half-joke that the `Object.is(..)` utility is like a `====` (a fourth `=` added) operator, for the really-truly-strict-no-exceptions kind of equality checking!\n\nThat said, `===` (and `==` by virtue of its internal delegation to `===`) are *extremely predictable*, with no weird exceptions, when it comes to comparing two actually-already-string values. I strongly recommend using `==` for such checks (or `===`), and reserve `Object.is(..)` for the corner cases (which are numeric).\n\n#### String Relational Comparisons\n\nIn addition to equality checks between strings, JS supports relational comparisons between primitive values, like strings: `<`, `<=`, `>`, and `>=`.\n\nThe `<` (less-than) and `>` (greater-than) operations compare two string values lexicographically -- like you would sort words in a dictionary -- and should thus be fairly self explanatory:\n\n```js\n\"hello\" < \"world\";          // true\n```\n\n| NOTE: |\n| :--- |\n| As mentioned earlier, the running JS program has a default locale, and these operators compare according to that locale. |\n\nLike `==`, the `<` and `>` operators are numerically coercive. Any non-number values are coerced to numbers. So the only way to do a relational comparison with strings is to ensure both operands are already string values.\n\nPerhaps somewhat surprisingly, the `<` and `>` have no strict-comparison equivalent, the way `===` avoids the coercion of `==`. These operators are always coercive (when the types don't match), and there's no way in JS to avoid that.\n\nSo what happens when both values are *numeric-looking* strings?\n\n```js\n\"100\" < \"11\";               // true\n```\n\nNumerically, of course, `100` should *not be* less than `11`.\n\nBut relational comparisons between two strings use the lexicographic ordering. So the second `\"0\"` character (in `\"100\"`) is less than the second `\"1\"` (in `\"11\"`), and thus `\"100\"` would be sorted in a *dictionary* before `\"11\"`. The relational operators only coerce to numbers if the operand types are not already strings.\n\nThe `<=` (less-than-or-equal) and `>=` (greater-than-or-equal) operators are effectively a shorthand for a compound check.\n\n```js\n\"hello\" <= \"hello\";                             // true\n(\"hello\" < \"hello\") || (\"hello\" == \"hello\");    // true\n\n\"hello\" >= \"hello\";                             // true\n(\"hello\" > \"hello\") || (\"hello\" == \"hello\");    // true\n```\n\n| NOTE: |\n| :--- |\n| Here's an interesting bit of specification nuance: JS doesn't actually define the underlying greater-than (for `>`) or greater-than-or-equal (for `>=`) operations. Instead, it defines them by reversing the arguments to their *less-than* complement counterparts. So `x > y` is treated by JS essentially as `y <= x`, and `x >= y` is treated by JS essentially as `y < x`. So JS only needs to specify how `<` and `==` work, and thus gets `>` and `>=` for free! |\n\n##### Locale-Aware Relational Comparisons\n\nAs I mentioned a moment ago, the relational operators assume and use the current in-effect locale. However, it can sometimes be useful to force a specific locale for comparisons (such as when sorting a list of strings).\n\nJS provides the method `localCompare(..)` on JS strings for this purpose:\n\n```js\n\"hello\".localeCompare(\"world\");\n// -1 (or negative number)\n\n\"world\".localeCompare(\"hello\",\"en\");\n// 1 (or positive number)\n\n\"hello\".localeCompare(\"hello\",\"en\",{ ignorePunctuation: true });\n// 0\n\n// examples from MDN:\n//\n// in German, ä sorts before z\n\"ä\".localeCompare(\"z\",\"de\");\n// -1 (or negative number) // a negative value\n\n// in Swedish, ä sorts after z\n\"ä\".localeCompare(\"z\",\"sv\");\n// 1 (or positive number)\n```\n\nThe optional second and third arguments to `localeCompare(..)` control which locale to use, via the `Intl.Collator` API[^INTLCollatorApi], as covered earlier.\n\nYou might use `localeCompare(..)` when sorting an array of strings:\n\n```js\nstudentNames = [\n    \"Lisa\",\n    \"Kyle\",\n    \"Jason\"\n];\n\n// Array::sort() mutates the array in place\nstudentNames.sort(function alphabetizeNames(name1,name2){\n    return name1.localeCompare(name2);\n});\n\nstudentNames;\n// [ \"Jason\", \"Kyle\", \"Lisa\" ]\n```\n\nBut as discussed earlier, a more straightforward way (and slightly more performant when sorting many strings) is using `Intl.Collator` directly:\n\n```js\nstudentNames = [\n    \"Lisa\",\n    \"Kyle\",\n    \"Jason\"\n];\n\nnameSorter = new Intl.Collator(\"en\");\n\n// Array::sort() mutates the array in place\nstudentNames.sort(nameSorter.compare);\n\nstudentNames;\n// [ \"Jason\", \"Kyle\", \"Lisa\" ]\n```\n\n### String Concatenation\n\nTwo or more string values can be concatenated (combined) into a new string value, using the `+` operator:\n\n```js\ngreeting = \"Hello, \" + \"Kyle!\";\n\ngreeting;               // Hello, Kyle!\n```\n\nThe `+` operator will act as a string concatenation if either of the two operands (values on left or right sides of the operator) are already a string (even an empty string `\"\"`).\n\nIf one operand is a string and the other is not, the one that's not a string will be coerced to its string representation for the purposes of the concatenation:\n\n```js\nuserCount = 7;\n\nstatus = \"There are \" + userCount + \" users online\";\n\nstatus;         // There are 7 users online\n```\n\nString concatenation of this sort is essentially interpolation of data into the string, which is the main purpose of template literals (see Chapter 1). So the following code will have the same outcome but is generally considered to be the more preferred approach:\n\n```js\nuserCount = 7;\n\nstatus = `There are ${userCount} users online`;\n\nstatus;         // There are 7 users online\n```\n\nOther options for string concatenation include `\"one\".concat(\"two\",\"three\")` and `[ \"one\", \"two\", \"three\" ].join(\"\")`, but these kinds of approaches are only preferable when the number of strings to concatenate is dependent on runtime conditions/computation. If the string has a fixed/known set of content, as above, template literals are the better option.\n\n### String Value Methods\n\nString values provide a whole slew of additional string-specific methods (as properties):\n\n* `charAt(..)`: produces a new string value at the numeric index, similar to `[ .. ]`; unlike `[ .. ]`, the result is always a string, either the character at position `0` (if a valid number outside the indices range), or the empty string `\"\"` (if missing/invalid index)\n\n* `at(..)` is similar to `charAt(..)`, but negative indices count backwards from the end of the string\n\n* `charCodeAt(..)`: returns the numeric code-unit (see \"JS Character Encodings\" in Chapter 1) at the specified index\n\n* `codePointAt(..)`: returns the whole code-point starting at the specified index; if a surrogate pair is found there, the whole character (code-point) s returned\n\n* `substr(..)` / `substring(..)` / `slice(..)`: produces a new string value that represents a range of characters from the original string; these differ in how the range's start/end indices are specified or determined\n\n* `toUpperCase()`: produces a new string value that's all uppercase characters\n\n* `toLowerCase()`: produces a new string value that's all lowercase characters\n\n* `toLocaleUpperCase()` / `toLocaleLowerCase()`: uses locale mappings for uppercase or lowercase operations\n\n* `concat(..)`: produces a new string value that's the concatenation of the original string and all of the string value arguments passed in\n\n* `indexOf(..)`: searches for a string value argument in the original string, optionally starting from the position specified in the second argument; returns the `0`-based index position if found, or `-1` if not found\n\n* `lastIndexOf(..)`: like `indexOf(..)` but, from the end of the string (right in LTR locales, left in RTL locales)\n\n* `includes(..)`: similar to `indexOf(..)` but returns a boolean result\n\n* `search(..)`: similar to `indexOf(..)` but with a regular-expression matching as specified\n\n* `trimStart()` / `trimEnd()` / `trim()`: produces a new string value with whitespace trimmed from the start of the string (left in LTR locales, right in RTL locales), or the end of the string (right in LTR locales, left in RTL locales), or both\n\n* `repeat(..)`: produces a new string with the original string value repeated the specified number of times\n\n* `split(..)`: produces an array of string values as split at the specified string or regular-expression boundaries\n\n* `padStart(..)` / `padEnd(..)`: produces a new string value with padding (default \" \" whitespace, but can be overridden) applied to either the start (left in LTR locales, right in RTL locales) or the end (right in LTR locales), left in RTL locales), so that the final string result is at least of a specified length\n\n* `startsWith(..)` / `endsWith(..)`: checks either the start (left in LTR locales, right in RTL locales) or the end (right in LTR locales) of the original string for the string value argument; returns a boolean result\n\n* `match(..)` / `matchAll(..)`: returns an array-like regular-expression matching result against the original string\n\n* `replace(..)`: returns a new string with a replacement from the original string, of one or more matching occurrences of the specified regular-expression match\n\n* `normalize(..)`: produces a new string with Unicode normalization (see \"Unicode Normalization\" in Chapter 1) having been performed on the contents\n\n* `localCompare(..)`: function that compares two strings according to the current locale (useful for sorting); returns a negative number (usually `-1` but not guaranteed) if the original string value is comes before the argument string value lexicographically, a positive number (usually `1` but not guaranteed) if the original string value comes after the argument string value lexicographically, and `0` if the two strings are identical\n\n* `anchor()`, `big()`, `blink()`, `bold()`, `fixed()`, `fontcolor()`, `fontsize()`, `italics()`, `link()`, `small()`, `strike()`, `sub()`, and `sup()`: historically, these were useful in generating HTML string snippets; they're now deprecated and should be avoided\n\n| WARNING: |\n| :--- |\n| Many of the methods described above rely on position indices. As mentioned earlier in the \"Length Computation\" section, these positions are dependent on the internal contents of the string value, which means that if an extended Unicode character is present and takes up two code-unit slots, that will count as two index positions instead of one. Failing to account for *decomposed* code-units, surrogate pairs, and grapheme cluseters is a common source of bugs in JS string handling. |\n\nThese string methods can all be called directly on a literal value, or on a variable/property that's holding a string value. When applicable, they produce a new string value rather than modifying the existing string value (since strings are immutable):\n\n```js\n\"all these letters\".toUpperCase();      // ALL THESE LETTERS\n\ngreeting = \"Hello!\";\ngreeting.repeat(2);                     // Hello!Hello!\ngreeting;                               // Hello!\n```\n\n### Static `String` Helpers\n\nThe following string utility functions are provided directly on the `String` object, rather than as methods on individual string values:\n\n* `String.fromCharCode(..)` / `String.fromCodePoint(..)`: produce a string from one or more arguments representing the code-units (`fromCharCode(..)`) or whole code-points (`fromCodePoint(..)`)\n\n* `String.raw(..)`: a default template-tag function that allows interpolation on a template literal but prevents character escape sequences from being parsed, so they remain in their *raw* individual input characters from the literal\n\nMoreover, most values (especially primitives) can be explicitly coerced to their string equivalent by passing them to the `String(..)` function (no `new` keyword). For example:\n\n```js\nString(true);           // \"true\"\nString(42);             // \"42\"\nString(Infinity);       // \"Infinity\"\nString(undefined);      // \"undefined\"\n```\n\nWe'll cover much more detail about such type coercions in a later chapter.\n\n## Number Behaviors\n\nNumbers are used for a variety of tasks in our programs, but mostly for mathematical computations. Pay close attention to how JS numbers behave, to ensure the outcomes are as expected.\n\n### Floating Point Imprecision\n\nWe need to revisit our discussion of IEEE-754 from Chapter 1.\n\nOne of the classic gotchas of any IEEE-754 number system in any programming language -- NOT UNIQUELY JS! -- is that not all operations and values can fit neatly into the IEEE-754 representations.\n\nThe most common illustration is:\n\n```js\npoint3a = 0.1 + 0.2;\npoint3b = 0.3;\n\npoint3a;                        // 0.30000000000000004\npoint3b;                        // 0.3\n\npoint3a === point3b;            // false <-- oops!\n```\n\nThe operation `0.1 + 0.2` ends up creating floating-point error (drift), where the value stored is actually `0.30000000000000004`.\n\nThe respective bit representations are:\n\n```\n// 0.30000000000000004\n00111111110100110011001100110011\n00110011001100110011001100110100\n\n// 0.3\n00111111110100110011001100110011\n00110011001100110011001100110011\n```\n\nIf you look closely at those bit patterns, only the last 2 bits differ, from `00` to `11`. But that's enough for those two numbers to be unequal!\n\nAgain, just to reinforce: this behavior is **NOT IN ANY WAY** unique to JS. This is exactly how any IEEE-754 conforming programming language will work in the same scenario. As I asserted above, the majority of all programming languages use IEEE-754, and thus they will all suffer this same fate.\n\nThe temptation to make fun of JS for `0.1 + 0.2 !== 0.3` is strong, I know. But here it's completely bogus.\n\n| NOTE: |\n| :--- |\n| Pretty much all programmers need to be aware of IEEE-754 and make sure they are careful about these kinds of gotchas. It's somewhat amazing, in a disappointing way, how few of them have any idea how IEEE-754 works. If you've taken your time reading and understanding these concepts so far, you're now in that rare tiny percentage who actually put in the effort to understand the numbers in their programs! |\n\n#### Epsilon Threshold\n\nA common piece of advice to work around such floating-point imprecision uses this *very small* `number` value defined by JS:\n\n```js\nNumber.EPSILON;                 // 2.220446049250313e-16\n```\n\n*Epsilon* is the smallest difference JS can represent between `1` and the next value greater than `1`. While this value is technically implementation/platform dependent, it's generally about `2.2E-16`, or `2^-52`.\n\nTo those not paying close enough attention to the details here -- including my past self! -- it's generally assumed that any skew in floating point precision from a single operation should never be greater than `Number.EPSILON`. Thus, in theory, we can use `Number.EPSILON` as a *very small* tolerance value to ensure number equality comparisons are *safe*:\n\n```js\nfunction safeNumberEquals(a,b) {\n    return Math.abs(a - b) < Number.EPSILON;\n}\n\npoint3a = 0.1 + 0.2;\npoint3b = 0.3;\n\n// are these safely \"equal\"?\nsafeNumberEquals(point3a,point3b);      // true\n```\n\n| WARNING: |\n| :--- |\n| In the first edition \"Types & Grammar\" book, I indeed recommended exactly this approach. I was wrong. I should have researched the topic more closely. |\n\nBut, it turns out, this approach isn't safe at all:\n\n```js\npoint3a = 10.1 + 0.2;\npoint3b = 10.3;\n\nsafeNumberEquals(point3a,point3b);      // false :(\n```\n\nWell... that's a bummer!\n\nUnfortunately, `Number.EPSILON` only works as a \"safely equal\" error threshold for certain small numbers/operations, and in other cases, it's far too small, and yields false negatives.\n\nYou could scale `Number.EPSILON` by some factor to produce a larger threshold that avoids false negatives but still filters out all the floating point skew in your program. But what factor to use is entirely a manual judgement call based on what magnitude of values, and operations on them, your program will entail. There's no automatic way to compute a reliable, universal threshold.\n\nUnless you really know what you're doing, you should just *not* use this `Number.EPSILON` threshold approach at all.\n\n| TIP: |\n| :--- |\n| If you'd like to read more details and solid advice on this topic, I highly recommend reading this post. [^EpsilonBad] But if we can't use `Number.EPSILON` to avoid the perils of floating-point skew, what do we do? If you can avoid floating-point altogether by scaling all your numbers up so they're all whole number integers (or bigints) while performing math, do so. Only deal with decimal values when you have to output/represent a final value after all the math is done. If that's not possible/practical, use an arbitrary precision decimal emulation library and avoid `number` values entirely. Or do your math in another external programming environment that's not based on IEEE-754. |\n\n### Numeric Comparison\n\nLike strings, number values can be compared (for both equality and relational ordering) using the same operators.\n\nRemember that no matter what form the number value takes when being specified as a literal (base-10, octal, hexadecimal, exponential, etc), the underlying value stored is what will be compared. Also keep in mind the floating point imprecision issues discussed in the previous section, as the comparisons will be sensitive to the exact binary contents.\n\n#### Numeric Equality\n\nJust like strings, equality comparisons for numbers use either the `==` / `===` operators or `Object.is(..)`. Also recall that if the types of both operands are the same, `==` performs identically to `===`.\n\n```js\n42 == 42;                   // true\n42 === 42;                  // true\n\n42 == 43;                   // false\n42 === 43;                  // false\n\nObject.is(42,42);           // true\nObject.is(42,43);           // false\n```\n\nFor `==` coercive equality (when the operand types don't match), if either operand is not a string value, `==` prefers a numeric equality check (meaning both operands are coerced to numbers).\n\n```js\n// numeric (not string!) comparison\n42 == \"42\";                 // true\n```\n\nIn this snippet, the coercive equality coerces `\"42\"` to `42`, not vice versa (`42` to `\"42\"`). Once both types are `number`, then their values are compared for exact equality, the same as `===` would.\n\nRecall that JS doesn't distinguish between values like `42`, `42.0`, and `42.000000`; under the covers, they're all the same. Unsurpisingly, the `==` and `===` equality checks verify that:\n\n```js\n42 == 42.0;                 // true\n42.0 == 42.00000;           // true\n42.00 === 42.000;           // true\n```\n\nThe intuition you likely have is, if two numbers are literally the same, they're equal. And that's how JS interprets it. But `0.3` is not literally the same as the result of `0.1 + 0.2`, because (as we saw earlier), the latter produces an underlying value that's *very close* to `0.3`, but is not exactly identical.\n\nWhat's interesting is, the two values are *so close* that their difference is less than the `Number.EPSILON` threshold, so JS can't actually represent that difference *accurately*.\n\nYou might then think, at least informally, that such JS numbers should be \"equal\", since the difference between them is too small to represent. But notice: JS *can* represent that there *is* a difference, which is why you see that `4` at the very end of the decimal when JS evaluates `0.1 + 0.2`. And you *could* type out the number literal `0.00000000000000004` (aka, `4e-17`), being that difference between `0.3` and `0.1 + 0.2`.\n\nWhat JS cannot do, with its IEEE-754 floating point numbers, is represent a number that small in an *accurate* enough way that operations on it produce expected results. It's too small to be fully and properly represented in the `number` type JS provides.\n\nSo `0.1 + 0.2 == 0.3` resolves to `false`, because there's a difference between the two values, even though JS can't accurately represent or do anything with a value as small as that difference.\n\nAlso like we saw with strings, the `!=` (coercive not-equal) and `!==` (strict-not-equal) operators work with numbers. `x != y` is basically `!(x == y)`, and `x !== y` is basically `!(x === y)`.\n\nThere are two frustrating exceptions in numeric equality (whether you use `==` or `===`):\n\n```js\nNaN === NaN;                // false -- ugh!\n-0 === 0;                   // true -- ugh!\n```\n\n`NaN` is never equal to itself (even with `===`), and `-0` is always equal to `0` (even with `===`). It sometimes surprises folks that even `===` has these two exceptions in it.\n\nHowever, the `Object.is(..)` equality check has neither of these exceptions, so for equality comparisons with `NaN` and `-0`, avoid the `==` / `===` operators and use `Object.is(..)` -- or for `NaN` specifically, `Number.isNaN(..)`.\n\n#### Numeric Relational Comparisons\n\nJust like with string values, the JS relational operators (`<`, `<=`, `>`, and `>=`) operate with numbers. The `<` (less-than) and `>` (greater-than) operations should be fairly self explanatory:\n\n```js\n41 < 42;                    // true\n\n0.1 + 0.2 > 0.3;            // true (ugh, IEEE-754)\n```\n\nRemember: just like `==`, the `<` and `>` operators are also coercive, meaning that any non-number values are coerced to numbers -- unless both operands are already strings, as we saw earlier. There are no strict relational comparison operators.\n\nIf you're doing relational comparisons between numbers, the only way to avoid coercion is to ensure that the comparisons always have two numbers. Otherwise, these operators will do *coercive relational* comparisons similar to how `==` performs *coercive equality* comparisons.\n\n### Mathematical Operators\n\nAs I asserted earlier, the main reason to have numbers in a programming language is to perform mathematical operations with them. So let's talk about how we do so.\n\nThe basic arithmetic operators are `+` (addition), `-` (subtraction), `*` (multiplication), and `/` (division). Also available are the operators `**` (exponentiation) and `%` (modulo, aka *division remainder*). There are also `+=`, `-=`, `*=`, `/=`, `**=`, and `%=` forms of the operators, which additionally assign the result back to the left operand -- must be a valid assignment target like a variable or property.\n\n| NOTE: |\n| :--- |\n| As we've already seen, the `+` operator is overloaded to work with both numbers and strings. When one or both operands is a string, the result is a string concatenation (including coercing either operand to a string if necessary). But if neither operand is a string, the result is a numeric addition, as expected. |\n\nAll these mathematical operators are *binary*, meaning they expect two value operands, one on either side of the operator; they all expect the operands to be number values. If either or both operands are non-numbers, the non-number operand(s) is/are coerced to numbers to perform the operation. We'll cover coercion in detail in a later chapter.\n\nConsider:\n\n```js\n40 + 2;                 // 42\n44 - 2;                 // 42\n21 * 2;                 // 42\n84 / 2;                 // 42\n7 ** 2;                 // 49\n49 % 2;                 // 1\n\n40 + \"2\";               // \"402\" (string concatenation)\n44 - \"2\";               // 42 (because \"2\" is coerced to 2)\n21 * \"2\";               // 42 (..ditto..)\n84 / \"2\";               // 42 (..ditto..)\n\"7\" ** \"2\";             // 49 (both operands are coerced to numbers)\n\"49\" % \"2\";             // 1 (..ditto..)\n```\n\nThe `+` and `-` operators also come in a *unary* form, meaning they only have one operand; again, the operand is expected to be a number, and coerced to a number if not:\n\n```js\n+42;                    // 42\n-42;                    // -42\n\n+\"42\";                  // 42\n-\"42\";                  // -42\n```\n\nYou might have noticed that `-42` looks like it's just a \"negative forty-two\" numeric literal. That's not quite right. A nuance of JS syntax is that it doesn't recognize negative numeric literals. Instead, JS treats this as a positive numeric literal `42` that's preceded, and negated, by the unary `-` operator in front of it.\n\nSomewhat surprisingly, then:\n\n```js\n-42;                    // -42\n- 42;                   // -42\n-\n    42;                 // -42\n```\n\nAs you can see, whitespace (and even new lines) are allowed between the `-` unary operator and its operand; actually, this is true of all operators and operands.\n\n#### Increment and Decrement\n\nThere are two other unary numeric operators: `++` (increment) and `--` decrement. They both perform their respective operation and then reassign the result to the operand -- must be a valid assignment target like a variable or property.\n\nYou may sort of think of `++` as equivalent to `+= 1`, and `--` as equivalent to `-= 1`:\n\n```js\nmyAge = 42;\n\nmyAge++;\nmyAge;                  // 43\n\nnumberOfHeadHairs--;\n```\n\nHowever, these are special operators in that they can appear in a postfix (after the operand) position, as above, or in a prefix (before the operand) position:\n\n```js\nmyAge = 42;\n\n++myAge;\nmyAge;                  // 43\n\n--numberofHeadHairs;\n```\n\nIt may seem peculiar that prefix and postfix positions seem to give the same result (incrementing or decrementing) in such examples. The difference is subtle, and isn't related to the final reassigned result. We'll revisit these particular operators in a later chapter to dig into the positional differences.\n\n### Bitwise Operators\n\nJS provides several bitwise operators to perform bit-level operations on number values.\n\nHowever, these bit operations are not performed against the packed bit-pattern of IEEE-754 numbers (see Chapter 1). Instead, the operand number is first converted to a 32-bit signed *integer*, the bit operation is performed, and then the result is converted back into an IEEE-754 number.\n\nKeep in mind, just like any other primitive operators, these just compute new values, not actually modifying a value in place.\n\n* `&` (bitwise AND): Performs an AND operation with each corresponding bit from the two operands; `42 & 36 === 32` (i.e., `0b00...101010 & 0b00...100100 === 0b00..100000`)\n\n* `|` (bitwise OR): Performs an OR operation with each corresponding bit from the two operands; `42 | 36 === 46` (i.e., `0b00...101010 | 0b00...100100 === 0b00...101110`)\n\n* `^` (bitwise XOR): Performs an XOR (eXclusive-OR) operation with each corresponding bit from the two operands; `42 ^ 36 === 14` (i.e., `0b00...101010 ^ 0b00...100100 === 0b00...001110`)\n\n* `~` (bitwise NOT): Performs a NOT operation against the bits of a single operand; `~42 === -43` (i.e., `~0b00...101010 === 0b11...010101`); using 2's complement, the signed integer has the first bit set to `1` meaning negative, and the rest of the bits (when flipped back, according to 2's complement, which is 1's complement bit flipping and then adding `1`) would be `43` (`0b10...101011`); the equivalent of `~` in decimal number arithmetic is `~x === -(x + 1)`, so `~42 === -43`\n\n* `<<` (left shift): Performs a left-shift of the bits of the left operand by the count of bits specified by the right operand; `42 << 3 == 336` (i.e., `0b00...101010 << 3 === 0b00...101010000`)\n\n* `>>` (right shift): Performs a sign-propagating right-shift of the bits of the left operand by the count of bits specified by the right operand, discarding the bits that fall off the right side; whatever the leftmost bit is (`0`, or `1` is negative) is copied in as bits on the left (thereby preserving the sign of the original value in the result); `42 >> 3 === 5` (i.e., `0b00..101010 >> 3 === 0b00...000101`)\n\n* `>>>` (zero-fill right shift, aka unsigned right shift): Performs the same right-shift as `>>`, but `0` fills on the bits shifted in from the left side instead of copying the leftmost bit (thereby ignoring the sign of the original value in the result); `42 >>> 3 === 5` but `-43 >>> 3 === 536870906` (i.e., `0b11...010101 >>> 3 === 0b0001...111010`)\n\n* `&=`, `|=`, `<<=`, `>>=`, and `>>>=` (bitwise operators with assignment): Performs the corresponding bitwise operation, but then assigns the result to the left operand (which must be a valid assignment target, like a variable or property, not just a literal value); note that `~=` is missing from the list, because there is no such \"binary negate with assignment\" operator\n\nIn all honesty, bitwise operations are not very common in JS. But you may sometimes see a statement like:\n\n```js\nmyGPA = 3.54;\n\nmyGPA | 0;              // 3\n```\n\nSince the bitwise operators act only on 32-bit integers, the `| 0` operation truncates (i.e., `Math.trunc(..)`) any decimal value, leaving only the integer.\n\n| WARNING: |\n| :--- |\n| A common misconception is that `| 0` is like *floor* (i.e., `Math.floor(..)`). The result of `| 0` agrees with `Math.floor(..)` on positive numbers, but differs on negative numbers, because by standard definition, *floor* is an operation that rounds-down towards `-Infinity`. `| 0` merely discards the decimal bits, which is in fact truncation. |\n\n### Number Value Methods\n\nNumber values provide the following methods (as properties) for number-specific operations:\n\n* `toExponential(..)`: produces a string representation of the number using scientific notation (e.g., `\"4.2e+1\"`)\n\n* `toFixed(..)`: produces a non-scientific-notation string representation of the number with the specified number of decimal places (rounding or zero-padding as necessary)\n\n* `toPrecision(..)`: like `toFixed(..)`, except it applies the numeric argument as the number of significant digits (i.e., precision) including both the whole number and decimal places if any\n\n* `toLocaleString(..)`: produces a string representation of the number according to the current locale\n\n```js\nmyAge = 42;\n\nmyAge.toExponential(3);         // \"4.200e+1\"\n```\n\nOne particular nuance of JS syntax is that `.` can be ambiguous when dealing with number literals and property/method access.\n\nIf a `.` comes immediately (no whitespace) after a numeric literal digit, and there's not already a `.` decimal in the number value, the `.` is assumed to be a starting the decimal portion of the number. But if the position of the `.` is unambiguously *not* part of the numeric literal, then it's always treated as a property access.\n\n```js\n42 .toExponential(3);           // \"4.200e+1\"\n```\n\nHere, the whitespace disambiguates the `.`, designating it as a property/method access. It's perhaps more common/preferred to use `(..)` instead of whitespace for such disambiguation:\n\n```js\n(42).toExponential(3);          // \"4.200e+1\"\n```\n\nAn unusual-looking effect of this JS parsing grammar rule:\n\n```js\n42..toExponential(3);           // \"4.200e+1\"\n```\n\nSo called the \"double-dot\" idiom, the first `.` in this expression is a decimal, and thus the second `.` is unambiguously *not* a decimal, but rather a property/method access.\n\nAlso, notice there's no digits after the first `.`; it's perfectly legal syntax to leave a trailing `.` on a numeric literal:\n\n```js\nmyAge = 41. + 1.;\n\nmyAge;                          // 42\n```\n\nValues of `bigint` type cannot have decimals, so the parsing is unambiguous that a `.` after a literal (with the trailing `n`) is always a property access:\n\n```js\n42n.toString();                 // 42\n```\n\n### Static `Number` Properties\n\n* `Number.EPSILON`: The smallest value possible between `1` and the next highest number\n\n* `Number.NaN`: The same as the global `NaN` symbol, the special invalid number\n\n* `Number.MIN_SAFE_INTEGER` / `Number.MAX_SAFE_INTEGER`: The positive and negative integers with the largest absolute value (furthest from `0`)\n\n* `Number.MIN_VALUE` / `Number.MAX_VALUE`: The minimum (positive value closest to `0`) and the maximum (positive value furthest from `0`) representable by the `number` type\n\n* `Number.NEGATIVE_INFINITY` / `Number.POSITIVE_INFINITY`: Same as global `-Infinity` and `Infinity`, the values that represent the largest (non-finite) values furthest from `0`\n\n### Static `Number` Helpers\n\n* `Number.isFinite(..)`: returns a boolean indicating if the value is finite -- a `number` that's not `NaN`, nor one of the two infinities\n\n* `Number.isInteger(..)` / `Number.isSafeInteger(..)`: both return booleans indicating if the value is a whole `number` with no decimal places, and if it's within the *safe* range for integers (`-2^53 + 1` - `2^53 - 1`)\n\n* `Number.isNaN(..)`: The bug-fixed version of the global `isNaN(..)` utility, which identifies if the argument provided is the special `NaN` value\n\n* `Number.parseFloat(..)` / `Number.parseInt(..)`: utilities to parse string values for numeric digits, left-to-right, until the end of the string or the first non-float (or non-integer) character is encountered\n\n### Static `Math` Namespace\n\nSince the main usage of `number` values is for performing mathematical operations, JS includes many standard mathematical constants and operation utilities on the `Math` namespace.\n\nThere's a bunch of these, so I'll omit listing every single one. But here's a few for illustration purposes:\n\n```js\nMath.PI;                        // 3.141592653589793\n\n// absolute value\nMath.abs(-32.6);                // 32.6\n\n// rounding\nMath.round(-32.6);              // -33\n\n// min/max selection\nMath.min(100,Math.max(0,42));   // 42\n```\n\nUnlike `Number`, which is also the `Number(..)` function (for number coercion), `Math` is just an object that holds these properties and static function utilities; it cannot be called as a function.\n\n| WARNING: |\n| :--- |\n| One peculiar member of the `Math` namespace is `Math.random()`, for producing a random floating point value between `0` and `1.0`. It's unusual to consider random number generation -- a task that's inherently stateful/side-effect'ing -- as a mathematical operation. It's also long been a footgun security-wise, as the pseudo-random number generator (PRNG) that JS uses is *not* secure (can be predicted) from a cryptography perspective. The web platform stepped in several years ago with the safer `crypto.getRandomValues(..)` API (based on a better PRNG), which fills a typed-array with random bits that can be interpreted as one or more integers (of type-specified maximum magnitude). Using `Math.random()` is universally discouraged now. |\n\n### BigInts and Numbers Don't Mix\n\nAs we covered in Chapter 1, values of `number` type and `bigint` type cannot mix in the same operations. That can trip you up even if you're doing a simple increment of the value (like in a loop):\n\n```js\nmyAge = 42n;\n\nmyAge + 1;                  // TypeError thrown!\nmyAge += 1;                 // TypeError thrown!\n\nmyAge + 1n;                 // 43n\nmyAge += 1n;                // 43n\n\nmyAge++;\nmyAge;                      // 44n\n```\n\nAs such, if you're using both `number` and `bigint` values in your programs, you'll need to manually coerce one value-type to the other somewhat regularly. The `BigInt(..)` function (no `new` keyword) can coerce a `number` value to `bigint`. Vice versa, to go the other direction from `bigint` to `number`, use the `Number(..)` function (again, no `new` keyword):\n\n```js\nBigInt(42);                 // 42n\n\nNumber(42n);                // 42\n```\n\nKeep in mind though: coercing between these types has some risk:\n\n```js\nBigInt(4.2);                // RangeError thrown!\nBigInt(NaN);                // RangeError thrown!\nBigInt(Infinity);           // RangeError thrown!\n\nNumber(2n ** 1024n);        // Infinity\n```\n\n## Primitives Are Foundational\n\nOver the last two chapters, we've dug deep into how primitive values behave in JS. I bet more than a few readers were, like me, ready to skip over these topics. But now, hopefully, you see the importance of understanding these concepts.\n\nThe story doesn't end here, though. Far from it! In the next chapter, we'll turn our attention to understanding JS's object types (objects, arrays, etc).\n\n[^TwitterUnicode]: \"New update to the Twitter-Text library: Emoji character count\"; Andy Piper; Oct 2018; https://twittercommunity.com/t/new-update-to-the-twitter-text-library-emoji-character-count/114607 ; Accessed July 2022\n\n[^INTLAPI]: ECMAScript 2022 Internationalization API Specification; https://402.ecma-international.org/9.0/ ; Accessed August 2022\n\n[^INTLCollator]: \"Intl.Collator\", MDN; https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Collator ; Accessed August 2022\n\n[^INTLSegmenter]: \"Intl.Segmenter\", MDN; https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Segmenter ; Accessed August 2022\n\n[^StrictEquality]: \"7.2.16 IsStrictlyEqual(x,y)\", ECMAScript 2022 Language Specification; https://262.ecma-international.org/13.0/#sec-isstrictlyequal ; Accessed August 2022\n\n[^LooseEquality]: \"7.2.15 IsLooselyEqual(x,y)\", ECMAScript 2022 Language Specification; https://262.ecma-international.org/13.0/#sec-islooselyequal ; Accessed August 2022\n\n[^EpsilonBad]: \"PLEASE don't follow the code recipe in the accepted answer\", Stack Overflow; Daniel Scott; July 2019; https://stackoverflow.com/a/56967003/228852 ; Accessed August 2022\n"
  },
  {
    "path": "types-grammar/ch3.md",
    "content": "# You Don't Know JS Yet: Types & Grammar - 2nd Edition\n# Chapter 3: Object Values\n\n| NOTE: |\n| :--- |\n| Work in progress |\n\nNow that we're comfortable with the built-in primitive types, we turn our attention to the `object` types in JS.\n\nI could write a whole book talking about objects in-depth; in fact, I already did! The \"Objects & Classes\" title of this series covers objects in-depth already, so make sure you've read that before continuing with this chapter.\n\nRather than repeat that book's content, here we'll focus our attention on how the `object` value-type behaves and interacts with other values in JS.\n\n## Types of Objects\n\nThe `object` value-type comprises several sub-types, each with specialized behaviors, including:\n\n* plain objects\n* fundamental objects (boxed primitives)\n* built-in objects\n* arrays\n* regular expressions\n* functions (aka, \"callable objects\")\n\nBeyond the specialized behaviors, one shared characteristic is that all objects can act as collections (of properties) holding values (including functions/methods).\n\n## Plain Objects\n\nThe general object value-type is sometimes referred to as *plain ol' javascript objects* (POJOs).\n\nPlain objects have a literal form:\n\n```js\naddress = {\n    street: \"12345 Market St\",\n    city: \"San Francisco\",\n    state: \"CA\",\n    zip: \"94114\"\n};\n```\n\nThis plain object (POJO), as defined with the `{ .. }` curly braces, is a collection of named properties (`street`, `city`, `state`, and `zip`). Properties can hold any values, primitives or other objects (including arrays, functions, etc).\n\nThe same object could also have been defined imperatively using the `new Object()` constructor:\n\n```js\naddress = new Object();\naddress.street = \"12345 Market St\";\naddress.city = \"San Francisco\";\naddress.state = \"CA\";\naddress.zip = \"94114\";\n```\n\nPlain objects are by default `[[Prototype]]` linked to `Object.prototype`, giving them delegated access to several general object methods, such as:\n\n* `toString()` / `toLocaleString()`\n* `valueOf()`\n* `isPrototypeOf(..)`\n* `hasOwnProperty(..)` (recently deprecated -- alternative: static `Object.hasOwn(..)` utility)\n* `propertyIsEnumerable(..)`\n* `__proto__` (getter function)\n\n```js\naddress.isPrototypeOf(Object.prototype);    // true\naddress.isPrototypeOf({});                  // false\n```\n\n## Fundamental Objects\n\nJS defines several *fundamental* object types, which are instances of various built-in constructors, including:\n\n* `new String()`\n* `new Number()`\n* `new Boolean()`\n\nNote that these constructors must be used with the `new` keyword to construct instances of the fundamental objects. Otherwise, these functions actually perform type coercion (see Chapter 4).\n\nThese fundamental object constructors create object value-types instead of a primitives:\n\n```js\nmyName = \"Kyle\";\ntypeof myName;                      // \"string\"\n\nmyNickname = new String(\"getify\");\ntypeof myNickname;                  // \"object\"\n```\n\nIn other words, an instance of a fundamental object constructor can actually be seen as a wrapper around the corresponding underlying primitive value.\n\n| WARNING: |\n| :--- |\n| It's nearly universally regarded as *bad practice* to ever directly instantiate these fundamental objects. The primitive counterparts are generally more predictable, more performant, and offer *auto-boxing* (see \"Automatic Objects\" section below) whenever the underlying object-wrapper form is needed for property/method access. |\n\nThe `Symbol(..)` and `BigInt(..)` functions are referred to in the specification as \"constructors\", though they're not used with the `new` keyword, and the values they produce in a JS program are indeed primitives.\n\nHow, there are internal *fundamental objects* for these two types, used for prototype delegation and *auto-boxing*.\n\nBy contrast, for `null` and `undefined` primitive values, there aren't `Null()` or `Undefined()` \"constructors\", nor corresponding fundamental objects or prototypes.\n\n### Prototypes\n\nInstances of the fundamental object constructors are `[[Prototype]]` linked to their constructors' `prototype` objects:\n\n* `String.prototype`: defines `length` property, as well as string-specific methods, like `toUpperCase()`, etc.\n\n* `Number.prototype`: defines number-specific methods, like `toPrecision(..)`, `toFixed(..)`, etc.\n\n* `Boolean.prototype`: defines default `toString()` and `valueOf()` methods.\n\n* `Symbol.prototype`: defines `description` (getter), as well as default `toString()` and `valueOf()` methods.\n\n* `BigInt.prototype`: defines default `toString()`, `toLocaleString()`, and `valueOf()` methods.\n\nAny direct instance of the built-in constructors have `[[Prototype]]` delegated access to its respective `prototype` properties/methods. Moreover, corresponding primitive values also have such delegated access, by way of *auto-boxing*.\n\n### Automatic Objects\n\nI've mentioned *auto-boxing* several times (including Chapters 1 and 2, and a few times so far in this chapter). It's finally time for us to explain that concept.\n\nAccessing a property or method on a value requires that the value be an object. As we've already seen in Chapter 1, primitives *are not* objects, so JS needs to then temporarily convert/wrap such a primitive to its fundamental object counterpart[^AutoBoxing] to perform that access.\n\nFor example:\n\n```js\nmyName = \"Kyle\";\n\nmyName.length;              // 4\n\nmyName.toUpperCase();       // \"KYLE\"\n```\n\nAccessing the `length` property or the `toUpperCase()` method, is only allowed on a primitive string value because JS *auto-boxes* the primitive `string` into a wrapper fundamental object, an instance of `new String(..)`. Otherwise, all such accesses would have to fail, since primitives do not have any properties.\n\nMore importantly, when the primitive value is *auto-boxed* to its fundamental object counterpart, those internally created objects have access to predefined properties/methods (like `length` and `toUpperCase()`) via a `[[Prototype]]` link to their respective fundamental object's prototype.\n\nSo an *auto-boxed* `string` is an instance of `new String()`, and is thus linked to `String.prototype`. Further, the same is true of `number` (wrapped as an instance of `new Number()`) and `boolean` (wrapped as an instance of `new Boolean()`).\n\nEven though the `Symbol(..)` and `BigInt(..)` \"constructors\" (used without `new`produce primitive values, these primitive values can also be *auto-boxed* to their internal fundamental object wrapper forms, for the purposes of delegated access to properties/methods.\n\n| NOTE: |\n| :--- |\n| See the \"Objects & Classes\" book of this series for more on `[[Prototype]]` linkages and delegated/inherited access to the fundamental object constructors' prototype objects. |\n\nSince `null` and `undefined` have no corresponding fundamental objects, there is no *auto-boxing* of these values.\n\nA subjective question to consider: is *auto-boxing* a form of coercion? I say it is, though some disagree. Internally, a primitive is converted to an object, meaning a change in value-type has occurred. Yes, it's temporary, but plenty of coercions are temporary. Moreover, the conversion is rather *implicit* (implied by the property/method access, but only happens internally). We'll revisit the nature of coercion in Chapter 4.\n\n## Other Built-in Objects\n\nIn addition to fundamental object constructors, JS defines a number of other built-in constructors that create further specialized object sub-types:\n\n* `new Date(..)`\n* `new Error(..)`\n* `new Map(..)`, `new Set(..)`, `new WeakMap(..)`, `new WeakSet(..)` -- keyed collections\n* `new Int8Array(..)`, `new Uint32Array(..)`, etc -- indexed, typed-array collections\n* `new ArrayBuffer(..)`, `new SharedArrayBuffer(..)`, etc -- structured data collections\n\n## Arrays\n\nArrays are objects that are specialized to behave as numerically indexed collections of values, as opposed to holding values at named properties like plain objects do.\n\nArrays have a literal form:\n\n```js\nfavoriteNumbers = [ 3, 12, 42 ];\n\nfavoriteNumbers[2];                 // 42\n```\n\nThe same array could also have been defined imperatively using the `new Array()` constructor:\n\n```js\nfavoriteNumbers = new Array();\nfavoriteNumbers[0] = 3;\nfavoriteNumbers[1] = 12;\nfavoriteNumbers[2] = 42;\n```\n\nArrays are `[[Prototype]]` linked to `Array.prototype`, giving them delegated access to a variety of array-oriented methods, such as `map(..)`, `includes(..)`, etc:\n\n```js\nfavoriteNumbers.map(v => v * 2);\n// [ 6, 24, 84 ]\n\nfavoriteNumbers.includes(42);       // true\n```\n\nSome of the methods defined on `Array.prototype` -- for example, `push(..)`, `pop(..)`, `sort(..)`, etc -- behave by modifying the array value in place. Other methods -- for example, `concat(..)`, `map(..)`, `slice(..)` -- behave by creating a new array to return, leaving the original array intact. A third category of array functions -- for example, `indexOf(..)`, `includes(..)`, etc -- merely computes and returns a (non-array) result.\n\n## Regular Expressions\n\n// TODO\n\n## Functions\n\n// TODO\n\n## Proposed: Records/Tuples\n\nAt the time of this writing, a (stage-2) proposal[^RecordsTuplesProposal] exists to add a new set of features to JS, which correspond closely to plain objects and arrays, but with some notable differences.\n\nRecords are similar to plain objects, but are immutable (sealed, read-only), and (unlike objects) are treated as primitive values, for the purposes of value assignment and equality comparison. The syntax difference is a `#` before the `{ }` delimiter. Records can only contain primitive values (including records and tuples).\n\nTuples have exactly the same relationship, but to arrays, including the `#` before the `[ ]` delimiters.\n\nIt's important to note that while these look and seem like objects/arrays, they are indeed primitive (non-object) values.\n\n[^FundamentalObjects]: \"20 Fundamental Objects\", EcamScript 2022 Language Specification; https://262.ecma-international.org/13.0/#sec-fundamental-objects ; Accessed August 2022\n\n[^AutoBoxing]: \"6.2.4.6 PutValue(V,W)\", Step 5.a, ECMAScript 2022 Language Specification; https://262.ecma-international.org/13.0/#sec-putvalue ; Accessed August 2022\n\n[^RecordsTuplesProposal]: \"JavaScript Records & Tuples Proposal\"; Robin Ricard, Rick Button, Nicolò Ribaudo;\nhttps://github.com/tc39/proposal-record-tuple ; Accessed August 2022\n"
  },
  {
    "path": "types-grammar/ch4.md",
    "content": "# You Don't Know JS Yet: Types & Grammar - 2nd Edition\n# Chapter 4: Coercing Values\n\n| NOTE: |\n| :--- |\n| Work in progress |\n\nWe've thoroughly covered all of the different *types* of values in JS. And along the way, more than a few times, we mentioned the notion of converting -- actually, coercing -- from one type of value to another.\n\nIn this chapter, we'll dive deep into coercion and uncover all its mysteries.\n\n## Coercion: Explicit vs Implicit\n\nSome developers assert that when you explicitly indicate a type change in an operation, this doesn't qualify as a *coercion* but just a type-cast or type-conversion. In other words, the claim is that coercion is only implicit.\n\nI disagree with this characterization. I use *coercion* to label any type conversion in a dynamically-typed language, whether it's plainly obvious in the code or not. Here's why: the line between *explicit* and *implicit* is not clear and objective, it's fairly subjective. If you think a type conversion is implicit (and thus *coercion*), but I think it's explicit (and thus not a *coercion*), the distinction becomes irrelevant.\n\nKeep that subjectivity in mind as we explore various *explicit* and *implicit* forms of coercion. In fact, here's a spoiler: most of the coercions could be argued as either, so we'll be looking at them with such balanced perspective.\n\n### Implicit: Bad or ...?\n\nAn extremely common opinion among JS developers is that *coercion is bad*, specifically, that *implicit coercion is bad*; the rise in popularity of type-aware tooling like TypeScript speaks loudly to this sentiment.\n\nBut that feeling is not new. 14+ years ago, Douglas Crockford's book \"The Good Parts\" also famously decried *implicit coercion* as one of the *bad parts*. Even Brendan Eich, creator of JS, regularly claims that *implicit coercion* was a mistake[^EichCoercion] in the early design of the language that he now regrets.\n\nIf you've been around JS for more than a few months, you've almost certainly heard these opinions voiced strongly and predominantly. And if you've been around JS for years or more, you probably have your mind already made up.\n\nIn fact, I think you'd be hard pressed to name hardly any other well-known source of JS teaching that strongly endorses coercion (in virtually all its forms); I do -- and this book definitely does! -- but I feel mostly like a lone voice shouting futilely in the wilderness.\n\nHowever, here's an observation I've made over the years: most of the folks who publicly condemn *implicit coercion*, actually use *implicit coercion* in their own code. Hmmmm...\n\nDouglas Crockford says to avoid the mistake of *implicit coercion*[^CrockfordCoercion], but his code uses `if (..)` statements with non-boolean values evaluated. [^CrockfordIfs] Many have dismissed my pointing that out in the past, with the claim that conversion-to-boolean isn't *really* coercion. Ummm... ok?\n\nBrendan Eich says he regrets *implicit coercion*, but yet he openly endorses[^BrendanToString] idioms like `x + \"\"` (and others!) to coerce the value in `x` to a string (we'll cover this later); and that's most definitely an *implicit coercion*.\n\nSo what do we make of this dissonance? Is it merely a, \"do as I say, not as I do\" minor self-contradiction? Or is there more to it?\n\nI am not going to pass a final judgement here yet, but I want you the reader to deeply ponder that question, as you continue throughout this chapter and book.\n\n## Abstracts\n\nNow that I've challenged you to examine coercion in more depth than you may have ever previously indulged, let's first look at the foundations of how coercion occurs, according to the JS specification.\n\nThe specification details a number of *abstract operations*[^AbstractOperations] that dictate internal conversion from one value-type to another. It's important to be aware of these operations, as coercive mechanics in the language mix and match them in various ways.\n\nThese operations *look* as if they're real functions that could be called, such as `ToString(..)` or `ToNumber(..)`. But by *abstract*, we mean they only exist conceptually by these names; they aren't functions we can *directly* invoke in our programs. Instead, we activate them implicitly/indirectly depending on the statements/expressions in our programs.\n\n### ToBoolean\n\nDecision making (conditional branching) always requires a boolean `true` or `false` value. But it's extremely common to want to make these decisions based on non-boolean value conditions, such as whether a string is empty or has anything in it.\n\nWhen non-boolean values are encountered in a context that requires a boolean -- such as the condition clause of an `if` statement or `for` loop -- the `ToBoolean(..)`[^ToBoolean] abstract operation is activated to facilitate the coercion.\n\nAll values in JS are in one of two buckets: *truthy* or *falsy*. Truthy values coerce via the `ToBoolean()` operation to `true`, whereas falsy values coerce to `false`:\n\n```\n// ToBoolean() is abstract\n\nToBoolean(undefined);               // false\nToBoolean(null);                    // false\nToBoolean(\"\");                      // false\nToBoolean(0);                       // false\nToBoolean(-0);                      // false\nToBoolean(0n);                      // false\nToBoolean(NaN);                     // false\n```\n\nSimple rule: *any other value* that's not in the above list is truthy and coerces via `ToBoolean()` to `true`:\n\n```\nToBoolean(\"hello\");                 // true\nToBoolean(42);                      // true\nToBoolean([ 1, 2, 3 ]);             // true\nToBoolean({ a: 1 });                // true\n```\n\nEven values like `\"   \"` (string with only whitespace), `[]` (empty array), and `{}` (empty object), which may seem intuitively like they're more \"false\" than \"true\", nevertheless coerce to `true`.\n\n| WARNING: |\n| :--- |\n| There *are* narrow, tricky exceptions to this truthy rule. For example, the web platform has deprecated the long-standing `document.all` collection/array feature, though it cannot be removed entirely -- that would break too many sites. Even where `document.all` is still defined, it behaves as a \"falsy object\"[^ExoticFalsyObjects] -- `undefined` which then coerces to `false`; this means legacy conditional checks like `if (document.all) { .. }` no longer pass. |\n\nThe `ToBoolean()` coercion operation is basically a lookup table rather than an algorithm of steps to use in coercions a non-boolean to a boolean. Thus, some developers assert that this isn't *really* coercion the way other abstract coercion operations are. I think that's bogus. `ToBoolean()` converts from non-boolean value-types to a boolean, and that's clear cut type coercion (even if it's a very simple lookup instead of an algorithm).\n\nKeep in mind: these rules of boolean coercion only apply when `ToBoolean()` is actually activated. There are constructs/idioms in the JS language that may appear to involve boolean coercion but which don't actually do so. More on these later.\n\n### ToPrimitive\n\nAny value that's not already a primitive can be reduced to a primitive using the `ToPrimitive()` (specifically, `OrdinaryToPrimitive()`[^OrdinaryToPrimitive]) abstract operation.  Generally, the `ToPrimitive()` is given a *hint* to tell it whether a `number` or `string` is preferred.\n\n```\n// ToPrimitive() is abstract\n\nToPrimitive({ a: 1 },\"string\");          // \"[object Object]\"\n\nToPrimitive({ a: 1 },\"number\");          // NaN\n```\n\nThe `ToPrimitive()` operation will look on the object provided, for either a `toString()` method or a `valueOf()` method; the order it looks for those is controlled by the *hint*. `\"string\"` means check in `toString()` / `valueOf()` order, whereas `\"number\"` (or no *hint*) means check in `valueOf()` / `toString()` order.\n\nIf the method returns a value matching the *hinted* type, the operation is finished. But if the method doesn't return a value of the *hinted* type, `ToPrimitive()` will then look for and invoke the other method (if found).\n\nIf the attempts at method invocation fail to produce a value of the *hinted* type, the final return value is forcibly coerced via the corresponding abstract operation: `ToString()` or `ToNumber()`.\n\n### ToString\n\nPretty much any value that's not already a string can be coerced to a string representation, via `ToString()`. [^ToString] This is usually quite intuitive, especially with primitive values:\n\n```\n// ToString() is abstract\n\nToString(42.0);                 // \"42\"\nToString(-3);                   // \"-3\"\nToString(Infinity);             // \"Infinity\"\nToString(NaN);                  // \"NaN\"\nToString(42n);                  // \"42\"\n\nToString(true);                 // \"true\"\nToString(false);                // \"false\"\n\nToString(null);                 // \"null\"\nToString(undefined);            // \"undefined\"\n```\n\nThere are *some* results that may vary from common intuition. As mentioned in Chapter 2, very large or very small numbers will be represented using scientific notation:\n\n```\nToString(Number.MAX_VALUE);     // \"1.7976931348623157e+308\"\nToString(Math.EPSILON);         // \"2.220446049250313e-16\"\n```\n\nAnother counter-intuitive result comes from `-0`:\n\n```\nToString(-0);                   // \"0\" -- wtf?\n```\n\nThis isn't a bug, it's just an intentional behavior from the earliest days of JS, based on the assumption that developers generally wouldn't want to ever see a negative-zero output.\n\nOne primitive value-type that is *not allowed* to be coerced (implicitly, at least) to string is `symbol`:\n\n```\nToString(Symbol(\"ok\"));         // TypeError exception thrown\n```\n\n| WARNING: |\n| :--- |\n| Calling the `String()`[^StringFunction] concrete function (without `new` operator) is generally thought of as *merely* invoking the `ToString()` abstract operation. While that's mostly true, it's not entirely so. `String(Symbol(\"ok\"))` works, whereas the abstract `ToString(Symbol(..))` itself throws an exception. More on `String(..)` later in this chapter. |\n\n#### Default `toString()`\n\nWhen `ToString()` is activated with an object value-type, it delegates to the `ToPrimitive()` operation (as explained earlier), with `\"string\"` as its *hinted* type:\n\n```\nToString(new String(\"abc\"));        // \"abc\"\nToString(new Number(42));           // \"42\"\n\nToString({ a: 1 });                 // \"[object Object]\"\nToString([ 1, 2, 3 ]);              // \"1,2,3\"\n```\n\nBy virtue of `ToPrimitive(..,\"string\")` delegation, these objects all have their default `toString()` method (inherited via `[[Prototype]]`) invoked.\n\n### ToNumber\n\nNon-number values *that resemble* numbers, such as numeric strings, can generally be coerced to a numeric representation, using `ToNumber()`: [^ToNumber]\n\n```\n// ToNumber() is abstract\n\nToNumber(\"42\");                     // 42\nToNumber(\"-3\");                     // -3\nToNumber(\"1.2300\");                 // 1.23\nToNumber(\"   8.0    \");             // 8\n```\n\nIf the full value doesn't *completely* (other than whitespace) resemble a valid number, the result will be `NaN`:\n\n```\nToNumber(\"123px\");                  // NaN\nToNumber(\"hello\");                  // NaN\n```\n\nOther primitive values have certain designated numeric equivalents:\n\n```\nToNumber(true);                     // 1\nToNumber(false);                    // 0\n\nToNumber(null);                     // 0\nToNumber(undefined);                // NaN\n```\n\nThere are some rather surprising designations for `ToNumber()`:\n\n```\nToNumber(\"\");                       // 0\nToNumber(\"       \");                // 0\n```\n\n| NOTE: |\n| :--- |\n| I call these \"surprising\" because I think it would have made much more sense for them to coerce to `NaN`, the way `undefined` does. |\n\nSome primitive values are *not allowed* to be coerced to numbers, and result in exceptions rather than `NaN`:\n\n```\nToNumber(42n);                      // TypeError exception thrown\nToNumber(Symbol(\"42\"));             // TypeError exception thrown\n```\n\n| WARNING: |\n| :--- |\n| Calling the `Number()`[^NumberFunction] concrete function (without `new` operator) is generally thought of as *merely* invoking the `ToNumber()` abstract operation to coerce a value to a number. While that's mostly true, it's not entirely so. `Number(42n)` works, whereas the abstract `ToNumber(42n)` itself throws an exception. |\n\n#### Other Abstract Numeric Conversions\n\nIn addition to `ToNumber()`, the specification defines `ToNumeric()`, which activates `ToPrimitive()` on a value, then conditionally delegates to `ToNumber()` if the value is *not* already a `bigint` value-type.\n\nThere are also a wide variety of abstract operations related to converting values to very specific subsets of the general `number` type:\n\n* `ToIntegerOrInfinity()`\n* `ToInt32()`\n* `ToUint32()`\n* `ToInt16()`\n* `ToUint16()`\n* `ToInt8()`\n* `ToUint8()`\n* `ToUint8Clamp()`\n\nOther operations related to `bigint`:\n\n* `ToBigInt()`\n* `StringToBigInt()`\n* `ToBigInt64()`\n* `ToBigUint64()`\n\nYou can probably infer the purpose of these operations from their names, and/or from consulting their algorithms in the specification. For most JS operations, it's more likely that a higher-level operation like `ToNumber()` is activated, rather than these specific ones.\n\n#### Default `valueOf()`\n\nWhen `ToNumber()` is activated on an object value-type, it instead delegates to the `ToPrimitive()` operation (as explained earlier), with `\"number\"` as its *hinted* type:\n\n```\nToNumber(new String(\"abc\"));        // NaN\nToNumber(new Number(42));           // 42\n\nToNumber({ a: 1 });                 // NaN\nToNumber([ 1, 2, 3 ]);              // NaN\nToNumber([]);                       // 0\n```\n\nBy virtue of `ToPrimitive(..,\"number\")` delegation, these objects all have their default `valueOf()` method (inherited via `[[Prototype]]`) invoked.\n\n### Equality Comparison\n\nWhen JS needs to determine if two values are the *same value*, it activates the `SameValue()`[^SameValue] operation, which delegates to a variety of related sub-operations.\n\nThis operation is very narrow and strict, and performs no coercion or any other special case exceptions. If two values are *exactly* the same, the result is `true`, otherwise it's `false`:\n\n```\n// SameValue() is abstract\n\nSameValue(\"hello\",\"\\x68ello\");          // true\nSameValue(\"\\u{1F4F1}\",\"\\uD83D\\uDCF1\");  // true\nSameValue(42,42);                       // true\nSameValue(NaN,NaN);                     // true\n\nSameValue(\"\\u00e9\",\"\\u0065\\u0301\");     // false\nSameValue(0,-0);                        // false\nSameValue([1,2,3],[1,2,3]);             // false\n```\n\nA variation of these operations is `SameValueZero()` and its associated sub-operations. The main difference is that these operations treat `0` and `-0` as indistinguishable.\n\n```\n// SameValueZero() is abstract\n\nSameValueZero(0,-0);                    // true\n```\n\nIf the values are numeric (`number` or `bigint`), `SameValue()` and `SameValueZero()` both delegate to sub-operations of the same names, specialized for each `number` and `bigint` type, respectively.\n\nOtherwise, `SameValueNonNumeric()` is the sub-operation delegated to if the values being compared are both non-numeric:\n\n```\n// SameValueNonNumeric() is abstract\n\nSameValueNonNumeric(\"hello\",\"hello\");   // true\n\nSameValueNonNumeric([1,2,3],[1,2,3]);   // false\n```\n\n#### Higher-Abstracted Equality\n\nDifferent from `SameValue()` and its variations, the specification also defines two important higher-abstraction abstract equality comparison operations:\n\n* `IsStrictlyEqual()`[^StrictEquality]\n* `IsLooselyEqual()`[^LooseEquality]\n\nThe `IsStrictlyEqual()` operation immediately returns `false` if the value-types being compared are different.\n\nIf the value-types are the same, `IsStrictlyEqual()` delegates to sub-operations for comparing `number` or `bigint` values. [^NumericAbstractOps] You might logically expect these delegated sub-operations to be the aforementioned numeric-specialized `SameValue()` / `SameValueZero()` operations. However, `IsStrictlyEqual()` instead delegates to `Number:equal()`[^NumberEqual] or `BigInt:equal()`[^BigIntEqual].\n\nThe difference between `Number:SameValue()` and `Number:equal()` is that the latter defines corner cases for `0` vs `-0` comparison:\n\n```\n// all of these are abstract operations\n\nNumber:SameValue(0,-0);             // false\nNumber:SameValueZero(0,-0);         // true\nNumber:equal(0,-0);                 // true\n```\n\nThese operations also differ in `NaN` vs `NaN` comparison:\n\n```\nNumber:SameValue(NaN,NaN);          // true\nNumber:equal(NaN,NaN);              // false\n```\n\n| WARNING: |\n| :--- |\n| So in other words, despite its name, `IsStrictlyEqual()` is not quite as \"strict\" as `SameValue()`, in that it *lies* when comparisons of `-0` or `NaN` are involved. |\n\nThe `IsLooselyEqual()` operation also inspects the value-types being compared; if they're the same, it immediately delegates to `IsStrictlyEqual()`.\n\nBut if the value-types being compared are different, `IsLooselyEqual()` performs a variety of *coercive equality* steps. It's important to note that this algorithm is always trying to reduce the comparison down to where both value-types are the same (and it tends to prefer `number` / `bigint`).\n\nThe steps of the *coercive equality* portion of the algorithm can roughly be summarized as follows:\n\n1. If either value is `null` and the other is `undefined`, `IsLooselyEqual()` returns `true`. In other words, this algorithm applies *nullish* equality, in that `null` and `undefined` are coercively equal to each other (and to no other values).\n\n2. If either value is a `number` and the other is a `string`, the `string` value is coerced to a `number` via `ToNumber()`.\n\n3. If either value is a `bigint` and the other is a `string`, the `string` value is coerced to a `bigint` via `StringToBigInt()`.\n\n4. If either value is a `boolean`, it's coerced to a `number`.\n\n5. If either value is a non-primitive (object, etc), it's coerced to a primitive with `ToPrimitive()`; though a *hint* is not explicitly provided, the default behavior will be as if `\"number\"` was the hint.\n\nEach time a coercion is performed in the above steps, the algorithm is *recursively* reactivated with the new value(s). That process continues until the types are the same, and then the comparison is delegated to the `IsStrictlyEqual()` operation.\n\nWhat can we take from this algorithm? First, we see there is a bias toward `number` (or `bigint`) comparison; it never coerce values to `string` or `boolean` value-types.\n\nImportantly, we see that both `IsLooselyEqual()` and `IsStrictlyEqual()` are type-sensitive. `IsStrictlyEqual()` immediately bails if the types mismatch, whereas `IsLooselyEqual()` performs the extra work to coerce mismatching value-types to be the same value-types (again, ideally, `number` or `bigint`).\n\nMoreover, if/once the types are the same, both operations are identical -- `IsLooselyEqual()` delegates to `IsStrictlyEqual()`.\n\n### Relational Comparison\n\nWhen values are compared relationally -- that is, is one value \"less than\" another? -- there's one specific abstract operation that is activated: `IsLessThan()`. [^LessThan]\n\n```\n// IsLessThan() is abstract\n\nIsLessThan(1,2, /*LeftFirst=*/ true );            // true\n```\n\nThere is no `IsGreaterThan()` operation; instead, the first two arguments to `IsLessThan()` can be reversed to accomplish a \"greater than\" comparison. To preserve left-to-right evaluation semantics (in the case of nuanced side-effects), `isLessThan()` also takes a third argument (`LeftFirst`); if `false`, this indicates a comparison was reversed and the second parameter should be evaluated before the first.\n\n```\nIsLessThan(1,2, /*LeftFirst=*/ true );            // true\n\n// equivalent of a fictional \"IsGreaterThan()\"\nIsLessThan(2,1, /*LeftFirst=*/ false );          // false\n```\n\nSimilar to `IsLooselyEqual()`, the `IsLessThan()` operation is *coercive*, meaning that it first ensures that the value-types of its two values match, and prefers numeric comparisons. There is no `IsStrictLessThan()` for non-coercive relational comparison.\n\nAs an example of coercive relational comparison, if the type of one value is `string` and the type of the other is `bigint`, the `string` is coerced to a `bigint` with the aforementioned `StringToBigInt()` operation. Once the types are the same, `IsLessThan()` proceeds as described in the following sections.\n\n#### String Comparison\n\nWhen both value are type `string`, `IsLessThan()` checks to see if the lefthand value is a prefix (the first *n* characters[^StringPrefix]) of the righthand; if so, `true` is returned.\n\nIf neither string is a prefix of the other, the first character position (start-to-end direction, not left-to-right) that's different between the two strings, is compared for their respective code-unit (numeric) values; the result is then returned.\n\nGenerally, code-units follow intuitive lexicographic (aka, dictionary) order:\n\n```\nIsLessThan(\"a\",\"b\", /*LeftFirst=*/ true );        // true\n```\n\nEven digits are treated as characters (not numbers):\n\n```\nIsLessThan(\"101\",\"12\", /*LeftFirst=*/ true );     // true\n```\n\nThere's even a bit of embedded *humor* in the unicode code-unit ordering:\n\n```\nIsLessThan(\"🐔\",\"🥚\", /*LeftFirst=*/ true );      // true\n```\n\nAt least now we've answered the age old question of *which comes first*?!\n\n#### Numeric Comparison\n\nFor numeric comparisons, `IsLessThan()` defers to either the `Number:lessThan()` or `BigInt:lessThan()` operation[^NumericAbstractOps], respectively:\n\n```\nIsLessThan(41,42, /*LeftFirst=*/ true );         // true\n\nIsLessThan(-0,0, /*LeftFirst=*/ true );          // false\n\nIsLessThan(NaN,1 /*LeftFirst=*/ true );          // false\n\nIsLessThan(41n,42n, /*LeftFirst=*/ true );       // true\n```\n\n## Concrete Coercions\n\nNow that we've covered all the abstract operations JS defines for handling various coercions, it's time to turn our attention to the concrete statements/expressions we can use in our programs that activate these operations.\n\n### To Boolean\n\nTo coerce a value that's not of type `boolean` into that type, we need the abstract `ToBoolean()` operation, as described earlier in this chapter.\n\nBefore we explore *how* to activate it, let's discuss *why* you would want to force a `ToBoolean()` coercion.\n\nFrom a code readability perspective, being *explicit* about type coercions can be preferable (though not universally). But functionally, the most common reason to force a `boolean` is when you're passing data to an external source -- for example, submitting data as JSON to an API endpoint -- and that location expects `true` / `false` without needing to do coercions.\n\nThere's several ways that `ToBoolean()` can be activated. Perhaps the most *explicit* (obvious) is the `Boolean(..)` function:\n\n```js\nBoolean(\"hello\");               // true\nBoolean(42);                    // true\n\nBoolean(\"\");                    // false\nBoolean(0);                     // false\n```\n\nAs mentioned in Chapter 3, keep in mind that `Boolean(..)` is being called without the `new` keyword, to activate the `ToBoolean()` abstract operation.\n\nIt's not terribly common to see JS developers use the `Boolean(..)` function for such explicit coercions. More often, developers will use the double-`!` idiom:\n\n```js\n!!\"hello\";                      // true\n!!42;                           // true\n\n!!\"\";                           // false\n!!0;                            // false\n```\n\nThe `!!` is not its own operator, even though it seems that way. It's actually two usages of the unary `!` operator. This operator first coerces any non-`boolean`, then negates it. To undo the negation, the second `!` flips it back.\n\nSo... which of the two, `Boolean(..)` or `!!`, do you consider to be more of an explicit coercion?\n\nGiven the flipping that `!` does, which must then be undone with another `!`, I'd say `Boolean(..)` is *more* explicit -- at the job of coercing a non-`boolean` to a `boolean` -- than `!!` is. But surveying open-source JS code, the `!!` is used far more often.\n\nIf we're defining *explicit* as, \"most directly and obviously performing an action\", `Boolean(..)` edges out `!!`. But if we're defining *explicit* as, \"most recognizably performing an action\", `!!` might have the edge. Is there a definitive answer here?\n\nWhile you're pondering that question, let's look at another JS mechanism that activates `ToBoolean()` under the covers:\n\n```js\nspecialNumber = 42;\n\nif (specialNumber) {\n    // ..\n}\n```\n\nThe `if` statement requires a `boolean` for the conditional to make its control-flow decision. If you pass it a non-`boolean`, a `ToBoolean()` *coercion* is performed.\n\nUnlike previous `ToBoolean()` coercion expressions, like `Boolean(..)` or `!!`, this `if` coercion is ephemeral, in that our JS program never sees the result of the coercion; it's just used internally by the `if`. Some may feel it's not *really* coercion if the program doesn't preserve/use the value. But I strongly disagree, because the coercion most definitely affects the program's behavior.\n\nMany other statement types also activate the `ToBoolean()` coercion, including the `? :` ternary conditional, and `for` / `while` loops. We also have `&&` (logical-AND) and `||` (logical-OR) operators. For example:\n\n```js\nisLoggedIn = user.sessionID || req.cookie[\"Session-ID\"];\n\nisAdmin = isLoggedIn && (\"admin\" in user.permissions);\n```\n\nFor both operators, the lefthand expression is first evaluated; if it's not already a `boolean`, a `ToBoolean()` coercion is activated to produce a value for the conditional decision.\n\n| NOTE: |\n| :--- |\n| To briefly explain these operators: for `||`, if the lefthand expression value (post-coercion, if necessary) is `true`, the pre-coercion value is returned; otherwise the righthand expression is evaluated and returned (no coercion). For `&&`, if the lefthand expression value (post-coercion, if necessary) is `false`, the pre-coercion value is returned; otherwise, the righthand expression is evaluated and returned (no coercion). In other words, both `&&` and `||` force a `ToBoolean()` coercion of the lefthand operand for making the decision, but neither operator's final result is actually coerced to a `boolean`. |\n\nIn the previous snippet, despite the naming implications, it's unlikely that `isLoggedIn` will actually be a `boolean`; and if it's truthy, `isAdmin` also won't be a `boolean`. That kind of code is quite common, but it's definitely dangerous that the assumed resultant `boolean` types aren't actually there. We'll revisit this example, and these operators, in the next chapter.\n\nAre these kinds of statements/expressions (e.g., `if (..)`, `||`, `&&`, etc) illustrating *explicit* coercion or *implicit* coercion in their conditional decision making?\n\nAgain, I think it depends on your perspective. The specification dictates pretty explicitly that they only make their decisions with `boolean` conditional values, requiring coercion if a non-`boolean` is received. On the other hand, a strong argument can also be made that any internal coercion is a secondary (implicit) effect to the main job of `if` / `&&` / etc.\n\nFurther, as mentioned earlier in the `ToBoolean()` discussion, some folks don't consider *any* activation of `ToBoolean()` to be a coercion.\n\nI think that's too much of a stretch, though. My take: `Boolean(..)` is the most preferable *explicit* coercion form. I think `!!`, `if`, `for`, `while`, `&&`, and `||` are all *implicitly* coercing non-`boolean`s, but I'm OK with that.\n\nSince most developers, including famous names like Doug Crockford, also in practice use implicit (`boolean`) coercions in their code[^CrockfordIfs], I think we can say that at least *some forms* of *implicit* coercion are widely acceptable, regardless of the ubiquitous rhetoric to the contrary.\n\n### To String\n\nAs with `ToBoolean()`, there are a number of ways to activate the `ToString()` coercion (as discussed earlier in the chapter). The decision of which approach is similarly subjective.\n\nLike the `Boolean(..)` function, the `String(..)` function (no `new` keyword) is a primary way of activating *explicit* `ToString()` coercion:\n\n```js\nString(true);                   // \"true\"\nString(42);                     // \"42\"\nString(-0);                     // \"0\"\nString(Infinity);               // \"Infinity\"\n\nString(null);                   // \"null\"\nString(undefined);              // \"undefined\"\n```\n\nHowever, `String(..)` is more than *just* an activation of `ToString()`. For example:\n\n```js\nString(Symbol(\"ok\"));           // \"Symbol(ok)\"\n```\n\nThis works, because *explicit* coercion of `symbol` values is allowed. But in cases where a symbol is *implicitly* coerced to a string (e.g., `Symbol(\"ok\") + \"\"`), the underlying `ToString()` operation throws an exception. That proves that `String(..)` is more than just an activation of `ToString()`. More on *implicit* string coercion of symbols in a bit.\n\nIf you call `String(..)` with an object value (e.g., array, etc), it activates the `ToPrimitive()` operation (via the `ToString()` operation), which then looks for an invokes that value's `toString()` method:\n\n```js\nString([1,2,3]);                // \"1,2,3\"\n\nString(x => x + 1);             // \"x => x + 1\"\n```\n\nAside from `String(..)`, any primitive, non-nullish value (neither `null` nor `undefined`) can be auto-boxed (see Chapter 3) in its respective object wrapper, providing a callable `toString()` method.\n\n```js\ntrue.toString();                // \"true\"\n42..toString();                 // \"42\"\n-0..toString();                 // \"0\"\nInfinity.toString();            // \"Infinity\"\nSymbol(\"ok\").toString();        // \"Symbol(ok)\"\n```\n\n| NOTE: |\n| :--- |\n| Do keep in mind, these `toString()` methods do *not* necessarily activate the `ToString()` operation, they just define their own rules for how to represent the value as a string. |\n\nAs shown with `String(..)` just a moment ago, the various object sub-types -- such as arrays, functions, regular expressions, `Date` and `Error` instances, etc -- all define their own specific `toString()` methods, which can be invoked directly:\n\n```js\n[1,2,3].toString();             // \"1,2,3\"\n\n(x => x + 1).toString();        // \"x => x + 1\"\n```\n\nMoreover, any plain object that's (by default) `[[Prototype]]` linked to `Object.prototype` has a default `toString()` method available:\n\n```js\n({ a : 1 }).toString();         // \"[object Object]\"\n```\n\nIs the `toString()` approach to coercion *explicit* or *implicit*? Again, it depends. It's certainly a self-descriptive mechanism, which leans *explicit*. But it often relies on auto-boxing, which is itself a fairly *implicit* coercion.\n\nLet's take a look at another common -- and famously endorsed! -- idiom for coercing a value to a string. Recall from \"String Concatenation\" in Chapter 2, the `+` operator is overloaded to prefer string concatenation if either operand is already a string, and thus coerces non-string operand to a string if necessary.\n\nConsider:\n\n```js\ntrue + \"\";                      // \"true\"\n42 + \"\";                        // \"42\"\nnull + \"\";                      // \"null\"\nundefined + \"\";                 // \"undefined\"\n```\n\nThe `+ \"\"` idiom for string coercion takes advantage of the `+` overloading, without altering the final coerced string value. By the way, all of these work the same with the operands reversed (i.e., `\"\" + ..`).\n\n| WARNING: |\n| :--- |\n| An extremely common misconception is that `String(x)` and `x + \"\"` are basically equivalent coercions, respectively just *explicit* vs *implicit* in form. But, that's not quite true! We'll revisit this in the \"To Primitive\" section later in this chapter. |\n\nSome feel this is an *explicit* coercion, but I think it's clearly more *implicit*, in that it's taking advantage of the `+` overloading; further, the `\"\"` is indirectly used to activate the coercion without modifying it. Moreover, consider what happens when this idiom is applied with a symbol value:\n\n```js\nSymbol(\"ok\") + \"\";              // TypeError exception thrown\n```\n\n| WARNING: |\n| :--- |\n| Allowing *explicit* coercion of symbols (`String(Symbol(\"ok\"))`, but disallowing *implicit* coercion (`Symbol(\"ok\") + \"\"`), is quite intentional by TC39. [^SymbolString] It was felt that symbols, as primitives often used in places where strings are otherwise used, could too easily be mistaken as strings. As such, they wanted to make sure developers expressed intent to coerce a symbol to a string, hopefully avoiding many of those anticipated confusions. This is one of the *extremely rare* cases where the language design asserts an opinion on, and actually discriminates between, *explicit* vs. *implicit* coercions. |\n\nWhy the exception? JS treats `+ \"\"` as an *implicit* coercion, which is why when activated with a symbol, an exception is thrown. I think that's a pretty ironclad proof.\n\nNevertheless, as I mentioned at the start of this chapter, Brendan Eich endorses `+ \"\"`[^BrendanToString] as the *best* way to coerce values to strings. I think that carries a lot of weight, in terms of him supporting at least a subset of *implicit* coercion practices. His views on *implicit* coercion must be a bit more nuanced than, \"it's all bad.\"\n\n### To Number\n\nNumeric coercions are a bit more complicated than string coercions, since we can be talking about either `number` or `bigint` as the target type. There's also a much smaller set of values that can be validly represented numerically (everything else becomes `NaN`).\n\nLet's start with the `Number(..)` and `BigInt(..)` functions (no `new` keywords):\n\n```js\nNumber(\"42\");                   // 42\nNumber(\"-3.141596\");            // -3.141596\nNumber(\"-0\");                   // -0\n\nBigInt(\"42\");                   // 42n\nBigInt(\"-0\");                   // 0n\n```\n\n`Number` coercion which fails (not recognized) results in `NaN` (see \"Invalid Number\" in Chapter 1), whereas `BigInt` throws an exception:\n\n```js\nNumber(\"123px\");                // NaN\n\nBigInt(\"123px\");\n// SyntaxError: Cannot convert 123px to a BigInt\n```\n\nMoreover, even though `42n` is valid syntax as a literal `bigint`, the string `\"42n\"` is never a recognized string representation of a `bigint`, by either of the coercive function forms:\n\n```js\nNumber(\"42n\");                  // NaN\n\nBigInt(\"42n\");\n// SyntaxError: Cannot convert 42n to a BigInt\n```\n\nHowever, we *can* coerce numeric strings with other representations of the numbers than typical base-10 decimals (see Chapter 1 for more information):\n\n```js\nNumber(\"0b101010\");             // 42\n\nBigInt(\"0b101010\");             // 42n\n```\n\nTypically, `Number(..)` and `BigInt(..)` receive string values, but that's not actually required. For example, `true` and `false` coerce to their typical numeric equivalents:\n\n```js\nNumber(true);                   // 1\nNumber(false);                  // 0\n\nBigInt(true);                   // 1n\nBigInt(false);                  // 0n\n```\n\nYou can also generally coerce between `number` and `bigint` types:\n\n```js\nNumber(42n);                    // 42\nNumber(42n ** 1000n);           // Infinity\n\nBigInt(42);                     // 42n\n```\n\nWe can also use the `+` unary operator, which is commonly assumed to coerce the same as the `Number(..)` function:\n\n```js\n+\"42\";                          // 42\n+\"0b101010\";                    // 42\n```\n\nBe careful though. If the coercions are unsafe/invalid in certain ways, exceptions are thrown:\n\n```js\nBigInt(3.141596);\n// RangeError: The number 3.141596 cannot be converted to a BigInt\n\n+42n;\n// TypeError: Cannot convert a BigInt value to a number\n```\n\nClearly, `3.141596` does not safely coerce to an integer, let alone a `bigint`.\n\nBut `+42n` throwing an exception is an interesting case. By contrast, `Number(42n)` works fine, so it's a bit surprising that `+42n` fails.\n\n| WARNING: |\n| :--- |\n| That surprise is especially palpable since prepending a `+` in front of a number is typically assumed to just mean a \"positive number\", the same way `-` in front a number is assumed to mean a \"negative number\". As explained in Chapter 1, however, JS numeric syntax (`number` and `bigint`) recognize no syntax for \"negative values\". All numeric literals are parsed as \"positive\" by default. If a `+` or `-` is prepended, those are treated as unary operators applied against the parsed (positive) number. |\n\nOK, so `+42n` is parsed as `+(42n)`. But still... why is `+` throwing an exception here?\n\nYou might recall earlier when we showed that JS allows *explicit* string coercion of symbol values, but disallows *implicit* string coercions? The same thing is going on here. JS language design interprets unary `+` in front of a `bigint` value as an *implicit* `ToNumber()` coercion (thus disallowed!), but `Number(..)` is interpreted as an *explicit* `ToNumber()` coercion (thus allowed!).\n\nIn other words, contrary to popular assumption/assertion, `Number(..)` and `+` are not interchangable. I think `Number(..)` is the safer/more reliable form.\n\n#### Mathematical Operations\n\nMathematical operators (e.g., `+`, `-`, `*`, `/`, `%`, and `**`) expect their operands to be numeric. If you use a non-`number` with them, that value will be coerced to a `number` for the purposes of the mathematical computation.\n\nSimilar to how `x + \"\"` is an idiom for coercing `x` to a string, an expression like `x - 0` safely coerces `x` to a number.\n\n| WARNING: |\n| :--- |\n| `x + 0` isn't quite as safe, since the `+` operator is overloaded to perform string concatenation if either operand is already a string. The `-` minus operator isn't overloaded like that, so the only coercion will be to `number`. Of course, `x * 1`, `x / 1`, and even `x ** 1` would also generally be equivalent mathematically, but those are much less common, and probably should be avoided as likely confusing to readers of your code. Even `x % 1` seems like it should be safe, but it can introduce floating-point skew (see \"Floating Point Imprecision\" in Chapter 2). |\n\nRegardless of what mathematical operator is used, if the coercion fails, a `NaN` is the result, and all of these operators will propagate the `NaN` out as their result.\n\n#### Bitwise Operations\n\nBitwise operators (e.g., `|`, `&`, `^`, `>>`, `<<`, and `<<<`) all expect number operands, but specifically they clamp these values to 32-bit integers.\n\nIf you're sure the numbers you're dealing with are safely within the 32-bit integer range, `x | 0` is another common expression idiom that has the effect of coercing `x` to a `number` if necessary.\n\nMoreover, since JS engines know these values will be integers, there's potential for them to optimize for integer-only math if they see `x | 0`. This is one of several recommended \"type annotations\" from the ASM.js[^ASMjs] efforts from years ago.\n\n#### Property Access\n\nProperty access of objects (and index access of arrays) is another place where implicit coercion can occur.\n\nConsider:\n\n```js\nmyObj = {};\n\nmyObj[3] = \"hello\";\nmyObj[\"3\"] = \"world\";\n\nconsole.log( myObj );\n```\n\nWhat do you expect from the contents of this object? Do you expect two different properties, numeric `3` (holding `\"hello\"`) and string `\"3\"` (holding `\"world\"`)? Or do you think both properties are in the same location?\n\nIf you try that code, you'll see that indeed we get an object with a single property, and it holds the `\"world\"` value. That means that JS is internally coercing either the `3` to `\"3\"`, or vice versa, when those properties accesses are made.\n\nInterestingly, the developer console may very well represent the object sort of like this:\n\n```js\nconsole.log( myObj );\n// {3: 'world'}\n```\n\nDoes that `3` there indicate the property is a numeric `3`? Not quite. Try adding another property to `myObj`:\n\n```js\nmyObj.something = 42;\n\nconsole.log( myObj )\n// {3: 'world', something: 42}\n```\n\nWe can see that this developer console doesn't quote string property keys, so we can't infer anything from `3` versus if the console had used `\"3\"` for the key name.\n\nLet's instead try consulting the specification for the object value[^ObjectValue], where we find:\n\n> A property key value is either an ECMAScript String value or a Symbol value. All String and Symbol values, including the empty String, are valid as property keys. A property name is a property key that is a String value.\n\nOK! So, in JS, objects only hold string (or symbol) properties. That must mean that the numeric `3` is coerced to a string `\"3\"`, right?\n\nIn the same section of the specification, we further read:\n\n> An integer index is a String-valued property key that is a canonical numeric String (see 7.1.21) and whose numeric value is either +0𝔽 or a positive integral Number ≤ 𝔽(253 - 1). An array index is an integer index whose numeric value i is in the range +0𝔽 ≤ i < 𝔽(232 - 1).\n\nIf a property key (like `\"3\"`) *looks* like a number, it's treated as an integer index. Hmmm... that almost seems to suggest the opposite of what we just posited, right?\n\nNevertheless, we know from the previous quote that property keys are *only* strings (or symbols). So it must be that \"integer index\" here is not describing the actual location, but rather the intentional usage of `3` in JS code, as a developer-expressed \"integer index\"; JS must still then actually store it at the location of the \"canonical numeric String\".\n\nConsider attempts to use other value-types, like `true`, `null`, `undefined`, or even non-primitives (other objects):\n\n```js\nmyObj[true] = 100;\nmyObj[null] = 200;\nmyObj[undefined] = 300;\nmyObj[ {a:1} ] = 400;\n\nconsole.log(myObj);\n// {3: 'world', something: 42, true: 100, null: 200,\n// undefined: 300, [object Object]: 400}\n```\n\nAs you can see, all of those other value-types were coerced to strings for the purposes of object property names.\n\nBut before we convince ourselves of this interpretation that everything (even numbers) is coerced to strings, let's look at an array example:\n\n```js\nmyArr = [];\n\nmyArr[3] = \"hello\";\nmyArr[\"3\"] = \"world\";\n\nconsole.log( myArr );\n// [empty × 3, 'world']\n```\n\nThe developer console will likely represent an array a bit differently than a plain object. Nevertheless, we still see that this array only has the single `\"world\"` value in it, at the numeric index position corresponding to `3`.\n\nThat kind of output sort of implies the opposite of our previous interpretation: that the values of an array are being stored only at numeric positions. If we add another string property-name to `myArr`:\n\n```js\nmyArr.something = 42;\nconsole.log( myArr );\n// [empty × 3, 'world', something: 42]\n```\n\nNow we see that this developer console represents the numerically indexed positions in the array *without* the property names (locations), but the `something` property is named in the output.\n\nIt's also true that JS engines like v8 tend to, for performance optimization reasons, special-case object properties that are numeric-looking strings as actually being stored in numeric positions as if they were arrays. So even if the JS program acts as if the property name is `\"3\"`, in fact under the covers, v8 might be treating it as if coerced to `3`!\n\nWhat can take from all this?\n\nThe specification clearly tells us that the behavior of object properties is for them to be treated like strings (or symbols). That means we can assume that using `3` to access a location on an object will have the internal effect of coercing that property name to `\"3\"`.\n\nBut with arrays, we observe a sort of opposite semantic: using `\"3\"` as a property name has the effect of accessing the numerically indexed `3` position, as if the string was coerced to the number. But that's mostly just an offshot of the fact that arrays always tend to behave as numerically indexed, and/or perhaps a reflection of underlying implementation/optimization details in the JS engine.\n\nThe important part is, we need to recognize that objects cannot simply use any value as a property name. If it's anything other than a string or a number, we can expect that there *will be* a coercion of that value.\n\nWe need to expect and plan for that rather than allowing it to surprise us with bugs down the road!\n\n### To Primitive\n\nMost operators in JS, including those we've seen with coercions to `string` and `number`, are designed to run against primitive values. When any of these operators is used instead against an object value, the abstract `ToPrimitive` algorithm (as described earlier) is activated to coerce the object to a primitive.\n\nLet's set up an object we can use to inspect how different operations behave:\n\n```js\nspyObject = {\n    toString() {\n        console.log(\"toString() invoked!\");\n        return \"10\";\n    },\n    valueOf() {\n        console.log(\"valueOf() invoked!\");\n        return 42;\n    },\n};\n```\n\nThis object defines both the `toString()` and `valueOf()` methods, and each one returns a different type of value (`string` vs `number`).\n\nLet's try some of the coercion operations we've already seen:\n\n```js\nString(spyObject);\n// toString() invoked!\n// \"10\"\n\nspyObject + \"\";\n// valueOf() invoked!\n// \"42\"\n```\n\nWhoa! I bet that surprised a few of you readers; it certainly did me. It's so common for people to assert that `String(..)` and `+ \"\"` are equivalent forms of activating the `ToString()` operation. But they're clearly not!\n\nThe difference comes down to the *hint* that each operation provides to `ToPrimitive()`. `String(..)` clearly provides `\"string\"` as the *hint*, whereas the `+ \"\"` idiom provides no *hint* (similar to *hinting* `\"number\"`). But don't miss this detail: even though `+ \"\"` invokes `valueOf()`, when that returns a `number` primitive value of `42`, that value is then coerced to a string (via `ToString()`), so we get `\"42\"` instead of `42`.\n\nLet's keep going:\n\n```js\nNumber(spyObject);\n// valueOf() invoked!\n// 42\n\n+spyObject;\n// valueOf() invoked!\n// 42\n```\n\nThis example implies that `Number(..)` and the unary `+` operator both perform the same `ToPrimitive()` coercion (with *hint* of `\"number\"`), which in our case returns `42`. Since that's already a `number` as requested, the value comes out without further ado.\n\nBut what if a `valueOf()` returns a `bigint`?\n\n```js\nspyObject2 = {\n    valueOf() {\n        console.log(\"valueOf() invoked!\");\n        return 42n;  // bigint!\n    }\n};\n\nNumber(spyObject2);\n// valueOf() invoked!\n// 42     <--- look, not a bigint!\n\n+spyObject2;\n// valueOf() invoked!\n// TypeError: Cannot convert a BigInt value to a number\n```\n\nWe saw this difference earlier in the \"To Number\" section. JS allows an *explicit* coercion of the `42n` bigint value to the `42` number value, but it disallows what it considers to be an *implicit* coercion form.\n\nWhat about the `BigInt(..)` (no `new` keyword) coercion function?\n\n```js\nBigInt(spyObject);\n// valueOf() invoked!\n// 42n    <--- look, a bigint!\n\nBigInt(spyObject2);\n// valueOf() invoked!\n// 42n\n\n// *******************************\n\nspyObject3 = {\n    valueOf() {\n        console.log(\"valueOf() invoked!\");\n        return 42.3;\n    }\n};\n\nBigInt(spyObject3);\n// valueOf() invoked!\n// RangeError: The number 42.3 cannot be converted to a BigInt\n```\n\nAgain, as we saw in the \"To Number\" section, `42` can safely be coerced to `42n`. On the other hand, `42.3` cannot safely be coerced to a `bigint`.\n\nWe've seen that `toString()` and `valueOf()` are invoked, variously, as certain `string` and `number` / `bigint` coercions are performed.\n\n#### No Primitive Found?\n\nIf `ToPrimitive()` fails to produce a primitive value, an exception will be thrown:\n\n```js\nspyObject4 = {\n    toString() {\n        console.log(\"toString() invoked!\");\n        return [];\n    },\n    valueOf() {\n        console.log(\"valueOf() invoked!\");\n        return {};\n    }\n};\n\nString(spyObject4);\n// toString() invoked!\n// valueOf() invoked!\n// TypeError: Cannot convert object to primitive value\n\nNumber(spyObject4);\n// valueOf() invoked!\n// toString() invoked!\n// TypeError: Cannot convert object to primitive value\n```\n\nIf you're going to define custom to-primitive coercions via `toString()` / `valueOf()`, make sure to return a primitive from at least one of them!\n\n#### Object To Boolean\n\nWhat about `boolean` coercions of objects?\n\n```js\nBoolean(spyObject);\n// true\n\n!spyObject;\n// false\n\nif (spyObject) {\n    console.log(\"if!\");\n}\n// if!\n\nresult = spyObject ? \"ternary!\" : \"nope\";\n// \"ternary!\"\n\nwhile (spyObject) {\n    console.log(\"while!\");\n    break;\n}\n// while!\n```\n\nEach of these are activating `ToBoolean()`. But if you recall from earlier, *that* algorithm never delegates to `ToPrimitive()`; thus, we don't see \"valueOf() invoked!\" being logged out.\n\n#### Unboxing: Wrapper To Primitive\n\nA special form of objects that are often `ToPrimitive()` coerced: boxed/wrapped primitives (as seen in Chapter 3). This particular object-to-primitive coercion is often referred to as *unboxing*.\n\nConsider:\n\n```js\nhello = new String(\"hello\");\nString(hello);                  // \"hello\"\nhello + \"\";                     // \"hello\"\n\nfortyOne = new Number(41);\nNumber(fortyOne);               // 41\nfortyOne + 1;                   // 42\n```\n\nThe object wrappers `hello` and `fortyOne` above have `toString()` and `valueOf()` methods configured on them, to behave similarly to the `spyObject` / etc objects from our previous examples.\n\nA special case to be careful of with wrapped-object primitives is with `Boolean()`:\n\n```js\nnope = new Boolean(false);\nBoolean(nope);                  // true   <--- oops!\n!!nope;                         // true   <--- oops!\n```\n\nRemember, this is because `ToBoolean()` does *not* reduce an object to its primitive form with `ToPrimitive`; it merely looks up the value in its internal table, and since normal (non-exotic[^ExoticFalsyObjects]) objects are always truthy, `true` comes out.\n\n| NOTE: |\n| :--- |\n| It's a nasty little gotcha. A case could certainly be made that `new Boolean(false)` should configure itself internally as an exotic \"falsy object\". [^ExoticFalsyObjects] Unfortunately, that change now, 25 years into JS's history, could easily create breakage in programs. As such, JS has left this gotcha untouched. |\n\n#### Overriding Default `toString()`\n\nAs we've seen, you can always define a `toString()` on an object to have *it* invoked by the appropriate `ToPrimitive()` coercion. But another option is to override the `Symbol.toStringTag`:\n\n```js\nspyObject5a = {};\nString(spyObject5a);\n// \"[object Object]\"\nspyObject5a.toString();\n// \"[object Object]\"\n\nspyObject5b = {\n    [Symbol.toStringTag]: \"my-spy-object\"\n};\nString(spyObject5b);\n// \"[object my-spy-object]\"\nspyObject5b.toString();\n// \"[object my-spy-object]\"\n\nspyObject5c = {\n    get [Symbol.toStringTag]() {\n        return `myValue:${this.myValue}`;\n    },\n    myValue: 42\n};\nString(spyObject5c);\n// \"[object myValue:42]\"\nspyObject5c.toString();\n// \"[object myValue:42]\"\n```\n\n`Symbol.toStringTag` is intended to define a custom string value to describe the object whenever its default `toString()` operation is invoked directly, or implicitly via coercion; in its absence, the value used is `\"Object\"` in the common `\"[object Object]\"` output.\n\nThe `get ..` syntax in `spyObject5c` is defining a *getter*. That means when JS tries to access this `Symbol.toStringTag` as a property (as normal), this getter code instead causes the function we specify to be invoked to compute the result. We can run any arbitrary logic inside this getter to dynamically determine a string *tag* for use by the default `toString()` method.\n\n#### Overriding `ToPrimitive`\n\nYou can alternately override the whole default `ToPrimitive()` operation for any object, by setting the special symbol property `Symbol.toPrimitive` to hold a function:\n\n```js\nspyObject6 = {\n    [Symbol.toPrimitive](hint) {\n        console.log(`toPrimitive(${hint}) invoked!`);\n        return 25;\n    },\n    toString() {\n        console.log(\"toString() invoked!\");\n        return \"10\";\n    },\n    valueOf() {\n        console.log(\"valueOf() invoked!\");\n        return 42;\n    },\n};\n\nString(spyObject6);\n// toPrimitive(string) invoked!\n// \"25\"   <--- not \"10\"\n\nspyObject6 + \"\";\n// toPrimitive(default) invoked!\n// \"25\"   <--- not \"42\"\n\nNumber(spyObject6);\n// toPrimitive(number) invoked!\n// 25     <--- not 42 or \"25\"\n\n+spyObject6;\n// toPrimitive(number) invoked!\n// 25\n```\n\nAs you can see, if you define this function on an object, it's used entirely in replacement of the default `ToPrimitive()` abstract operation. Since `hint` is still provided to this invoked function (`[Symbol.toPrimitive](..)`), you could in theory implement your own version of the algorithm, invoking a `toString()`, `valueOf()`, or any other method on the object (`this` context reference).\n\nOr you can just manually define a return value as shown above. Regardless, JS will *not* automatically invoke either `toString()` or `valueOf()` methods.\n\n| WARNING: |\n| :--- |\n| As discussed prior in \"No Primitive Found?\", if the defined `Symbol.toPrimitive` function does not actually return a value that's a primitive, an exception will be thrown about being unable to \"...convert object to primitive value\". Make sure to always return an actual primitive value from such a function! |\n\n### Equality\n\nThus far, the coercions we've seen have been focused on single values. We turn out attention now to equality comparisons, which inherently involve two values, either or both of which may be subject to coercion.\n\nEarlier in this chapter, we talked about several abstract operations for value equality comparison.\n\nFor example, the `SameValue()` operation[^SameValue] is the strictest of the equality comparisons, with absolutely no coercion. The most obvious JS operation that relies on `SameValue()` is:\n\n```js\nObject.is(42,42);                   // true\nObject.is(-0,-0);                   // true\nObject.is(NaN,NaN);                 // true\n\nObject.is(0,-0);                    // false\n```\n\nThe `SameValueZero()` operation -- recall, it only differs from `SameValue()` by treating `-0` and `0` as indistinguishable -- is used in quite a few more places, including:\n\n```js\n[ 1, 2, NaN ].includes(NaN);        // true\n```\n\nWe can see the `0` / `-0` misdirection of `SameValueZero()` here:\n\n```js\n[ 1, 2, -0 ].includes(0);           // true  <--- oops!\n\n(new Set([ 1, 2, 0 ])).has(-0);     // true  <--- ugh\n\n(new Map([[ 0, \"ok\" ]])).has(-0);   // true  <--- :(\n```\n\nIn these cases, there's a *coercion* (of sorts!) that treats `-0` and `0` as indistinguishable. No, that's not technically a \"coercion\" in that the type is not being changed, but I'm sort of fudging the definition to *include* this case in our broader discussion of coercion here.\n\nContrast the `includes()` / `has()` methods here, which activate `SameValueZero()`, with the good ol' `indexOf(..)` array utility, which instead activates `IsStrictlyEqual()` instead. This algorithm is slightly more \"coercive\" than `SameValueZero()`, in that it prevents `NaN` values from ever being treated as equal to each other:\n\n```js\n[ 1, 2, NaN ].indexOf(NaN);         // -1  <--- not found\n```\n\nIf these nuanced quirks of `includes(..)` and `indexOf(..)` bother you, when searching -- looking for an equality match within -- for a value in an array, you can avoid any \"coercive\" quicks and *force* the strictest `SameValue()` equality matching, via `Object.is(..)`:\n\n```js\nvals = [ 0, 1, 2, -0, NaN ];\n\nvals.find(v => Object.is(v,-0));            // -0\nvals.find(v => Object.is(v,NaN));           // NaN\n\nvals.findIndex(v => Object.is(v,-0));       // 3\nvals.findIndex(v => Object.is(v,NaN));      // 4\n```\n\n#### Equality Operators: `==` vs `===`\n\nThe most obvious place where *coercion* is involved in equality checks is with the `==` operator. Despite any pre-conceived notions you may have about `==`, it behaves extremely predictably, ensuring that both operands match types before performing its equality check.\n\nTo state something that may or may not be super obvious: the `==` (and `===`) operators always return a `boolean` (`true` or `false`), indicating the result of the equality check; they never return anything else, regardless of what coercion may happen.\n\nNow, recall and review the steps discussed earlier in the chapter for the `IsLooselyEqual()` operation. [^LooseEquality] Its behavior, and thus how `==` acts, can be pragmatically intuited with just these two facts in mind:\n\n1. If the types of both operands are the same, `==` has the exact same behavior as `===` -- `IsLooselyEqual()` immediately delegates to `IsStrictlyEqual()`. [^StrictEquality]\n\n    For example, when both operands are object references:\n\n    ```js\n    myObj = { a: 1 };\n    anotherObj = myObj;\n\n    myObj == anotherObj;                // true\n    myObj === anotherObj;               // true\n    ```\n\n    Here, `==` and `===` determine that both of their respective operands are of the `object` reference type, so both equality checks behave identically; they compare the object references for equality.\n\n2. But if the operand types differ, `==` allows coercion until they match, and prefers numeric comparison; it attempts to coerce both operands to numbers, if possible:\n\n    ```js\n    42 == \"42\";                         // true\n    ```\n\n    Here, the `\"42\"` string is coerced to a `42` number (not vice versa), and thus the comparison is then `42 == 42`, and must clearly return `true`.\n\n\nArmed with this knowledge, we'll now dispel the common myth that only `===` checks the type and value, while `==` checks only the value. Not true!\n\nIn fact, `==` and `===` are both type-sensitive, each checking the types of their operands. The `==` operator allows coercion of mismatched types, whereas `===` disallows any coercion.\n\nIt's a nearly universally held opinion that `==` should be avoided in favor of `===`. I may be one of the only developers who publicly advocates a clear and straight-faced case for the opposite. I think the main reason people instead prefer `===`, beyond simply conforming to the status quo, is a lack of taking the time to actually understand `==`.\n\nI'll be revisiting this topic to make the case for preferring `==` over `===`, later in this chapter, in \"Type Aware Equality\". All I ask is, no matter how strongly you currently disagree with me, try to keep an open mindset.\n\n#### Nullish Coercion\n\nWe've already seen a number of JS operations that are nullish -- treating `null` and `undefined` as coercively equal to each other, including the `?.` optional-chaining operator and the `??` nullish-coalescing operator (see \"Null'ish\" in Chapter 1).\n\nBut `==` is the most obvious place that JS exposes nullish coercive equality:\n\n```js\nnull == undefined;              // true\n```\n\nNeither `null` nor `undefined` will ever be coercively equal to any other value in the language, other than to each other. That means `==` makes it ergonomic to treat these two values as indistinguishable.\n\nYou might take advantage of this capability as such:\n\n```js\nif (someData == null) {\n    // `someData` is \"unset\" (either null or undefined),\n    // so set it to some default value\n}\n\n// OR:\n\nif (someData != null) {\n    // `someData` is set (neither null nor undefined),\n    // so use it somehow\n}\n```\n\nRemember that `!=` is the negation of `==`, whereas `!==` is the negation of `===`. Don't match the count of `=`s unless you want to confuse yourself!\n\nCompare these two approaches:\n\n```js\nif (someData == null) {\n    // ..\n}\n\n// vs:\n\nif (someData === null || someData === undefined) {\n    // ..\n}\n```\n\nBoth `if` statements will behave exactly identically. Which one would you rather write, and which one would you rather read later?\n\nTo be fair, some of you prefer the more verbose `===` equivalent. And that's OK. I disagree, I think the `==` version of this check is *much* better. And I also maintain that the `==` version is more consistent in stylistic spirit with how the other nullish operators like `?.` and `??` act.\n\nBut another minor fact you might consider: in performance benchmarks I've run many times, JS engines can perform the single `== null` check as shown *slightly faster* than the combination of two `===` checks. In other words, there's a tiny but measurable benefit to letting JS's `==` perform the *implicit* nullish coercion than in trying to *explicitly* list out both checks yourself.\n\nI'd observe that even many diehard `===` fans tend to concede that `== null` is at least one such case where `==` is preferable.\n\n#### `==` Boolean Gotcha\n\nAside from some coercive corner cases we'll address in the next section, probably the biggest gotcha to be aware of with `==` has to do with booleans.\n\nPay very close attention here, as it's one of the biggest reasons people get bitten by, and then come to despise, `==`. If you take my simple advice (at the end of this section), you'll never be a victim!\n\nConsider the following snippet, and let's assume for a minute that `isLoggedIn` is *not* holding a `boolean` value (`true` or `false`):\n\n```js\nif (isLoggedIn) {\n    // ..\n}\n\n// vs:\n\nif (isLoggedIn == true) {\n    // ..\n}\n```\n\nWe've already covered the first `if` statement form. We know `if` expects a `boolean`, so in this case `isLoggedIn` will be coerced to a `boolean` using the lookup table in the `ToBoolean()` abstract operation. Pretty straightforward to predict, right?\n\nBut take a look at the `isLoggedIn == true` expression. Do you think it's going to behave the same way?\n\nIf your instinct was *yes*, you've just fallen into a tricky little trap. Recall early in this chapter when I warned that the rules of `ToBoolean()` coercion only apply if the JS operation is actually activating that algorithm. Here, it seems like JS must be doing so, because `== true` seems so clearly a \"boolean related\" type of comparison.\n\nBut nope. Go re-read the `IsLooselyEqual()` algorithm (for `==`) earlier in the chapter. Go on, I'll wait. If you don't like my summary, go read the specification algorithm[^LooseEquality] itself.\n\nOK, do you see anything in there that mentions invoking `ToBoolean()` under any circumstance?\n\nNope!\n\nRemember: when the types of the two `==` operands are not the same, it prefers to coerce them both to numbers.\n\nWhat might be in `isLoggedIn`, if it's not a `boolean`? Well, it could be a string value like `\"yes\"`, for example. In that form, `if (\"yes\") { .. }` would clearly pass the conditional check and execute the block.\n\nBut what's going to happen with the `==` form of the `if` conditional? It's going to act like this:\n\n```js\n// (1)\n\"yes\" == true\n\n// (2)\n\"yes\" == 1\n\n// (3)\nNaN == 1\n\n// (4)\nNaN === 1           // false\n```\n\nSo in other words, if `isLoggedIn` holds a value like `\"yes\"`, the `if (isLoggedIn) { .. }` block will pass the conditional check, but the `if (isLoggedIn == true)` check will not. Ugh!\n\nWhat if `isLoggedIn` held the string `\"true\"`?\n\n```js\n// (1)\n\"true\" == true\n\n// (2)\n\"true\" == 1\n\n// (3)\nNaN == 1\n\n// (4)\nNaN === 1           // false\n```\n\nFacepalm.\n\nHere's a pop quiz: what value would `isLoggedIn` need to hold for both forms of the `if` statement conditional to pass?\n\n...\n\n...\n\n...\n\n...\n\nWhat if `isLoggedIn` was holding the number `1`? `1` is truthy, so the `if (isLoggedIn)` form passes. And the other `==` form that involves coercion:\n\n```js\n// (1)\n1 == true\n\n// (2)\n1 == 1\n\n// (3)\n1 === 1             // true\n```\n\nBut if `isLoggedIn` was instead holding the string `\"1\"`? Again, `\"1\"` is truthy, but what about the `==` coercion?\n\n```js\n// (1)\n\"1\" == true\n\n// (2)\n\"1\" == 1\n\n// (3)\n1 == 1\n\n// (4)\n1 === 1             // true\n```\n\nOK, so `1` and `\"1\"` are two values that `isLoggedIn` can hold that are safe to coerce along with `true` in a `==` equality check. But basically almost no other values are safe for `isLoggedIn` to hold.\n\nWe have a similar gotcha if the check is `== false`. What values are safe in such a comparison? `\"\"` and `0` work. But:\n\n```js\nif ([] == false) {\n    // this will run!\n}\n```\n\n`[]` is a truthy value, but it's also coercively equal to `false`?! Ouch.\n\nWhat are we to make of these gotchas with `== true` and `== false` checks? I have a plain and simple answer.\n\nNever, ever, under any circumstances, perform a `==` check if either side of the comparison is a `true` or `false` value. It looks like it's going to behave as a nice `ToBoolean()` coercion, but it slyly won't, and will instead be ensnared in a variety of coercion corner cases (addressed in the next section). And avoid the `===` forms, too.\n\nWhen you're dealing with booleans, stick to the implicitly coercive forms that are genuinely activating `ToBoolean()`, such as `if (isLoggedIn)`, and stay away from the `==` / `===` forms.\n\n## Coercion Corner Cases\n\nI've been clear in expressing my pro-coercion opinion thus far. And it *is* just an opinion, though it's based on interpreting facts gleaned from studying the language specification and observable JS behaviors.\n\nThat's not to say that coercion is perfect. There's several frustrating corner cases we need to be aware of, so we avoid tripping into those potholes. In case it's not clear, my following characterizations of these corner cases are just more of my opinions. Your mileage may vary.\n\n### Strings\n\nWe already saw that the string coercion of an array looks like this:\n\n```js\nString([ 1, 2, 3 ]);                // \"1,2,3\"\n```\n\nI personally find that super annoying, that it doesn't include the surrounding `[ ]`. In particular, that leads to this absurdity:\n\n```js\nString([]);                         // \"\"\n```\n\nSo we can't tell that it's even an array, because all we get is an empty string? Great, JS. That's just stupid. Sorry, but it is. And it gets worse:\n\n```js\nString([ null, undefined ]);        // \",\"\n```\n\nWAT!? We know that `null` coerces to the string `\"null\"`, and `undefined` coerces to the string `\"undefined\"`. But if those values are in an array, they magically just *disappear* as empty strings in the array-to-string coercion. Only the `\",\"` remains to even hint to us there was anything at all in the array! That's just silly town, right there.\n\nWhat about objects? Almost as aggravating, though in the opposite direction:\n\n```js\nString({});                         // \"[object Object]\"\n\nString({ a: 1 });                   // \"[object Object]\"\n```\n\nUmm... OK. Sure, thanks JS for no help at all in understanding what the object value is.\n\n### Numbers\n\nI'm about to reveal what I think is *the* worst root of all coercion corner case evil. Are you ready for it?!?\n\n```js\nNumber(\"\");                         // 0\nNumber(\"       \");                  // 0\n```\n\nI'm still shaking my head at this one, and I've known about it for nearly 20 years. I still don't get what Brendan was thinking with this one.\n\nThe empty string is devoid of any contents; it has nothing in it with which to determine a numeric representation. `0` is absolutely ***NOT*** the numeric equivalent of missing/invalid numeric value. You know what number value we have that is well-suited to communicate that? `NaN`. Don't even get me started on how whitespace is stripped from strings when coercing to a number, so the very-much-not-empty `\"       \"` string is still treated the same as `\"\"` for numeric coercion purposes.\n\nEven worse, recall how `[]` coerces to the string `\"\"`? By extension:\n\n```js\nNumber([]);                         // 0\n```\n\nDoh! If `\"\"` didn't coerce to `0` -- remember, this is the root of all coercion evil! --, then `[]` wouldn't coerce to `0` either.\n\nThis is just absurd, upside-down universe territory.\n\nMuch more tame, but still mildly annoying:\n\n```js\nNumber(\"NaN\");                      // NaN  <--- accidental!\n\nNumber(\"Infinity\");                 // Infinity\nNumber(\"infinity\");                 // NaN  <--- oops, watch case!\n```\n\nThe string `\"NaN\"` is not parsed as a recognizable numeric value, so the coercion fails, producing (accidentally!) the `NaN` value. `\"Infinity\"` is explicitly parseable for the coercion, but any other casing, including `\"infinity\"`, will fail, again producing `NaN`.\n\nThis next example, you may not think is a corner case at all:\n\n```js\nNumber(false);                      // 0\nNumber(true);                       // 1\n```\n\nIt's merely programmer convention, legacy from languages that didn't originally have boolean `true` and `false` values, that we treat `0` as `false`, and `1` as `true`. But does it *really* make sense to go the other direction?\n\nThink about it this way:\n\n```js\nfalse + true + false + false + true;        // 2\n```\n\nReally? I don't think there's any case where treating a `boolean` as its `number` equivalent makes any rational sense in a program. I can understand the reverse, for historical reasons: `Boolean(0)` and `Boolean(1)`.\n\nBut I genuniely feel that `Number(false)` and `Number(true)` (as well as any implicit coercion forms) should produce `NaN`, not `0` / `1`.\n\n### Coercion Absurdity\n\nTo prove my point, let's take the absurdity up to level 11:\n\n```js\n[] == ![];                          // true\n```\n\nHow!? That seems beyond credibility that a value could be coercively equal to its negation, right!?\n\nBut follow down the coercion rabbit hole:\n\n1. `[] == ![]`\n2. `[] == false`\n3. `\"\" == false`\n4. `0 == false`\n5. `0 == 0`\n6. `0 === 0`  ->  `true`\n\nWe've got three different absurdities conspiring against us: `String([])`, `Number(\"\")`, and `Number(false)`; if any of these weren't true, this nonsense corner case outcome wouldn't occur.\n\nLet me make something absolutely clear, though: none of this is `==`'s fault. It gets the blame here, of course. But the real culprits are the underlying `string` and `number` corner cases.\n\n## Type Awareness\n\nWe've now sliced and diced and examined coercion from every conceivable angle, starting from the abstract internals of the specification, then moving to the concrete expressions and statements that actually trigger the coercions.\n\nBut what's the point of all this? Is the detail in this chapter, and indeed this whole book up to this point, mostly just trivia? Eh, I don't think so.\n\nLet's return to the observations/questions I posed way back at the beginning of this long chapter.\n\nThere's no shortage of opinions (especially negative) about coercion. The nearly universally held position is that coercion is mostly/entirely a *bad part* of JS's language design. But inspite of that reality, most every developer, in most every JS program ever written, faces the reality that coercion cannot be avoided.\n\nIn other words, no matter what you do, you won't be able to get away from the need to be aware of, understand, and manage JS's value-types and the conversions them. Contrary to common assumptions, embracing a dynamically-typed (or even a weakly-typed) language, does *not* mean being careless or unaware of types.\n\nType-aware programming is always, always better than type ignorant/agnostic programming.\n\n### Uhh... TypeScript?\n\nSurely you're thinking at this moment: \"Why can't I just use TypeScript and declare all my types statically, avoiding all the confusion of dynamic typing and coercion?\"\n\n| NOTE: |\n| :--- |\n| I have many more detailed thoughts on TypeScript and the larger role it plays in our ecosystem; I'll save those opinions for the appendix (\"Thoughts on TypeScript\"). |\n\nLet's start by addressing head on the ways TypeScript does, and does not, aid in type-aware programming, as I'm advocating.\n\nTypeScript is both **statically-typed** (meaning types are declared at author time and checked at compile-time) and **strongly-typed** (meaning variables/containers are typed, and these associations are enforced; strongly-typed systems also disallow *implicit* coercion). The greatest strength of TypeScript is that it typically forces both the author of the code, and the reader of the code, to confront the types comprising most (ideally, all!) of a program. That's definitely a good thing.\n\nBy contrast, JS is **dynamically-typed** (meaning types are discovered and managed purely at runtime) and **weakly-typed** (meaning variables/containers are not typed, so there's no associations to enforce, and variables can thus hold any value-types; weakly-typed systems allow any form of coercion).\n\n| NOTE: |\n| :--- |\n| I'm hand-waving at a pretty high level here, and intentionally not diving deeply into lots of nuance on the static/dynamic and strong/weak typing spectrums. If you're feeling the urge to \"Well, actually...\" me at this moment, please just hold on a bit and let me lay out my arguments. |\n\n### Type-Awareness *Without* TypeScript\n\nDoes a dynamically-typed system automatically mean you're programming with less type-awareness? Many would argue that, but I disagree.\n\nI do not at all think that declaring static types (annotations, as in TypeScript) is the only way to accomplish effective type-awareness. Clearly, though, proponents of static-typing believe that is the *best* way.\n\nLet me illustrate type-awareness without TypeScript's static typing. Consider this variable declaration:\n\n```js\nlet API_BASE_URL = \"https://some.tld/api/2\";\n```\n\nIs that statement in any way *type-aware*? Sure, there's no `: string` annotation after `API_BASE_URL`. But I definitely think it *is* still type-aware! We clearly see the value-type (`string`) of the value being assigned to `API_BASE_URL`.\n\n| WARNING: |\n| :--- |\n| Don't get distracted by the `let` declaration being re-assignable (as opposed to a `const`). JS's `const` is *not* a first-class feature of its type system. We don't really gain additional type-awareness simply because we know that reassignment of a `const` variable is disallowed by the JS engine. If the code is structured well -- ahem, structured with type-awareness as a priority -- we can just read the code and see clearly that `API_BASE_URL` is *not* reassigned and is thus still the value-type it was previously assigned. From a type-awareness perspective, that's effectively the same thing as if it *couldn't* be reassigned. |\n\nIf I later want to do something like:\n\n```js\n// are we using the secure API URL?\nisSecureAPI = /^https/.test(API_BASE_URL);\n```\n\nI know the regular-expression `test(..)` method expects a string, and since I know `API_BASE_URL` is holding a string, I know that operation is type-safe.\n\nSimilarly, since I know the simple rules of `ToBoolean()` coercion as it relates to string values, I know this kind of statement is also type-safe:\n\n```js\n// do we have an API URL determined yet?\nif (API_BASE_URL) {\n    // ..\n}\n```\n\nBut if later, I start to type something like this:\n\n```js\nAPIVersion = Number(API_BASE_URL);\n```\n\nA warning siren triggers in my head. Since I know there's some very specific rules about how string values coerce to numbers, I recognize that this operation is **not** type-safe. So I instead approach it differently:\n\n```js\n// pull out the version number from API URL\nversionDigit = API_BASE_URL.match(/\\/api\\/(\\d+)$/)[1];\n\n// make sure the version is actually a number\nAPIVersion = Number(versionDigit);\n```\n\nI know that `API_BASE_URL` is a string, and I further know the format of its contents includes `\".../api/{digits}\"` at the end. That lets me know that the regular expression match will succeed, so the `[1]` array access is type-safe.\n\nI also know that `versionDigit` will hold a string, because that's what regular-expression matches return. Now, I know it's safe to coerce that numeric-digit string into a number with `Number(..)`.\n\nBy my definition, that kind of thinking, and that style of coding, is type-aware. Type-awareness in coding means thinking carefully about whether or not such things will be *clear* and *obvious* to the reader of the code.\n\n### Type-Awareness *With* TypeScript\n\nTypeScript fans will point out that TypeScript can, via type inference, do static typing (enforcement) without ever needing a single type annotation in the program. So all the code examples I shared in the previous section, TypeScript can also handle, and provide its flavor of compile-time static type enforcement.\n\nIn other words, TypeScript will give us the same kind of benefit in type checking, whichever of these two we write:\n\n```ts\nlet API_BASE_URL: string = \"https://some.tld/api/2\";\n\n// vs:\n\nlet API_BASE_URL = \"https://some.tld/api/2\";\n```\n\nBut there's no free-lunch. We have some issues we need to confront. First of all, TypeScript does *not* trigger an error here:\n\n```js\nAPI_BASE_URL = \"https://some.tld/api/2\";\n\nAPIVersion = Number(API_BASE_URL);\n// NaN\n```\n\nIntuitively, *I* want a type-aware system to understand why that's unsafe. But maybe that's just too much to ask. Or perhaps if we actually define a more narrow/specific type for that `API_BASE_URL` variable, than simply `string`, it might help? We can use a TypeScript trick called \"Template Literal Types\": [^TSLiteralTypes]\n\n```ts\ntype VersionedURL = `https://some.tld/api/${number}`;\n\nAPI_BASE_URL: VersionedURL = \"https://some.tld/api/2\";\n\nAPIVersion = Number(API_BASE_URL);\n// NaN\n```\n\nNope, TypeScript still doesn't see any problem with that. Yes, I know there's an explanation for why (how `Number(..)` itself is typed).\n\n| NOTE: |\n| :--- |\n| I imagine the really smart folks who *know* TypeScript well have creative ideas on how we can contort ourselves into raising an error there. Maybe there's even a dozen different ways to force TypeScript to trigger on that code. But that's not really the point. |\n\nMy point is, we cannot fully rely on TypeScript types to solve all our problems, letting us check out and remain blissfully unaware of the nuances of types and, in this case, coercion behaviors.\n\nBut! You're surely objecting to this line of argument, desperate to assert that even if TypeScript can't understand some specific situation, surely using TypeScript doesn't make it *worse*! Right!?\n\nLet's look at what TypeScript has to say[^TSExample1] about this line:\n\n```ts\ntype VersionedURL = `https://some.tld/api/${number}`;\n\nlet API_BASE_URL: VersionedURL = \"https://some.tld/api/2\";\n\nlet versionDigit = API_BASE_URL.match(/\\/api\\/(\\d+)$/)[1];\n// Object is possibly 'null'.\n```\n\nThe error indicates that the `[1]` access isn't type-safe, because if the regular expression fails to find any match on the string, `match(..)` returns `null`.\n\nYou see, even though *I* can reason about the contents of the string compared to how the regular expression is written, and even if *I* went to the trouble to make it super clear to TypeScript exactly what those specific string contents are, it's not quite smart enough to line those two up to see that it's actually fully type-safe to assume the match happens.\n\n| TIP: |\n| :--- |\n| Is it really the job of, and best use of, a type-aware tool to be contorted to express every single possible nuance of type-safety? We don't need perfect and universal tools to derive immense amounts of benefit from the stuff they *can* do. |\n\nMoreover, comparing the code style in the previous section to the code in this section (with or without the annotations), is TypeScript actually making our coding more type-aware?\n\nLike, does that `type VersionedURL = ..` and `API_BASE_URL: VersionedURL` stuff *actually* make our code more clearly type-aware? I don't necessarily think so.\n\n### TypeScript Intelligence\n\nYes, I hear you screaming at me through the computer screen. Yes, I know that TypeScript provides what type information it discovers (or infers) to your code editor, which comes through in the form of intelligent autocompletes, helpful inline warning markers, etc.\n\nBut I'm arguing that even *those* don't, in and of themselves, make you more type-aware as a developer\n\nWhy? Because type-awareness is *not* just about the authoring experience. It's also about the reading experience, maybe even more so. And not all places/mechanisms where code is read, have access to benefit from all the extra intelligence.\n\nLook, the magic of a language-server pumping intelligence into your code editor is unquestionably amazing. It's cool and super helpful.\n\nAnd I don't begrudge TypeScript as a tool inferring things about my **JS code** and giving me hints and suggestions through delightful code editor integrations. I just don't necessarily want to *have* to annotate type information in some extremely specific way just to silence the tool's complaints.\n\n### The Bar Above TypeScript\n\nBut even if I did/had all that, it's still not ***sufficient*** for me to be fully type-aware, both as a code-author and as a code-reader.\n\nThese tools don't catch every type error that can happen, no matter how much we want to tell ourselves they can, and no matter how many hoops and contortions we endure to wish it so. All the efforts to coax and *coerce* a tool into catching those nuanced errors, through endlessly increasing complexity of type syntax tricks, is... at best, misplaced effort.\n\nMoreover, no such tool is immune to false positives, complaining about things which aren't actually errors; these tools will never be as smart as we are as humans. You're really wasting your time in chasing down some quirky syntax trick to quite down the tool's complaints.\n\nThere's just no substitute, if you want to truly be a type-aware code-author and code-reader, from learning how the language's built-in type systems work. And yes, that means every single developer on your team needs to spend the efforts to learn it. You can't water this stuff down just to be more attainable for less experienced developers on the project/team.\n\nEven if we granted that you could avoid 100% of all *implicit* coercions -- you can't -- you are absolutely going to face the need to *explicit* coercions -- all programs do!\n\nAnd if your response to that fact is to suggest that you'll just offload the mental burden of understanding them to a tool like TypeScript... then I'm sorry to tell you, but you're plainly and painfully falling short of the *type-aware* bar that I'm challenging all developers to strive towards.\n\nI'm not advocating, here, for you to ditch TypeScript. If you like it, fine. But I am very explicitly and passionately challenging you: stop using TypeScript as a crutch. Stop prostrating yourself to appease the TypeScript engine overlords. Stop foolishly chasing every type rabbit down every syntactic hole.\n\nFrom my observation, there's a tragic, inverse relationship between usage of type-aware tooling (like TypeScript) and the desire/effort to pursue actual type-awareness as a code-author and code-reader. The more you rely on TypeScript, the more it seems you're tempted and encouraged to shift your attention away from JS's type system (and especially, from coercion) to the alternate TypeScript type system.\n\nUnfortunately, TypeScript can never fully escape JS's type system, because TypeScript's types are *erased* by the compiler, and what's left is just JS that the JS engine has to contend with.\n\n| TIP: |\n| :--- |\n| Imagine if someone handed you a cup of filtered water to drink. And just before you took a sip, they said, \"We extracted that water from the ground near a waste dump. But don't worry, we used a perfectly great filter, and that water is totally safe!\" How much do you trust that filter? More to my overall point, wouldn't you feel more comfortable drinking that water if you understood everything about the source of the water, all the processes of filtration, and everything that was *in* the water of the glass in your hand!? Or is trusting that filter good enough? |\n\n### Type Aware Equality\n\nI'll close this long, winding chapter with one final illustration, modeling how I think developers should -- armed with more critical thinking than bandwagon conformism -- approach type-aware coding, whether you use a tool like TypeScript or not.\n\nWe'll yet again revisit equality comparisons (`==` vs `===`), from the perspective of type-awareness. Earlier in this chapter, I promised that I would make the case for `==` over `===`, so here it goes.\n\nLet's restate/summarize what we know about `==` and `===` so far:\n\n1. If the types of the operands for `==` match, it behaves *exactly the same* as `===`.\n\n2. If the types of the operands for `===` do not match, it will always return `false`.\n\n3. If the types of the operands for `==` do not match, it will allow coercion of either operand (generally preferring numeric type-values), until the types finally match; once they match, see (1).\n\nOK, so let's take those facts and analyze how they might interact in our program.\n\nIf you are making an equality comparison of `x` and `y` like this:\n\n```js\nif ( /* are x and y equal */ ) {\n    // ..\n}\n```\n\nWhat are the possible conditions we may be in, with respect to the types of `x` and `y`?\n\n1. We might know exactly what type(s) `x` and `y` could be, because we know how those variables are getting assigned.\n\n2. Or we might not be able to tell what those types could be. It could be that `x` or `y` could be any type, or at least any of several different types, such that the possible combinations of types in the comparison are too complex to understand/predict.\n\nCan we agree that (1) is far preferable to (2)? Can we further agree that (1) represents having written our code in a type-aware fashion, whereas (2) represents code that is decidedly type-*unaware*?\n\nIf you're using TypeScript, you're very likely to be aware of the types of `x` and `y`, right? Even if you're not using TypeScript, we've already shown that you can take intentional steps to write your code in such a way that the types of `x` and `y` are known and obvious.\n\n#### (2) Unknown Types\n\nIf you're in scenario (2), I'm going to assert that your code is in a problem state. Your code is less-than-ideal. Your code needs to be refactored. The best thing to do, if you find code in this state, is... fix it!\n\nChange the code so it's type-aware. If that means using TypeScript, and even inserting some type annotations, do so. Or if you feel you can get to the type-aware state with *just JS*, do that. Either way, do whatever you can to get to scenario (1).\n\nIf you cannot ensure the code doing this equality comparison between `x` and `y` is type-aware, and you have no other options, then you absolutely *must* use the `===` strict-equality operator. Not doing so would be supremely irresponsible.\n\n```js\nif (x === y) {\n    // ..\n}\n```\n\nIf you don't know anything about the types, how could you (or any other future reader of your code) have any idea how the coercive steps in `==` are going to behave!? You can't.\n\nThe only responsible thing to do is, avoid coercion and use `===`.\n\nBut don't lose sight of this fact: you're only picking `===` as a last resort, when your code is so type-unaware -- ahem, type-broken! -- as to have no other choice.\n\n#### (1) Known Types\n\nOK, let's instead assume you're in scenario (1). You know the types of `x` and `y`. It's very clear in the code what this narrow set of types participating in the equality check can be.\n\nGreat!\n\nBut there's still two possible sub-conditions you may be in:\n\n* (1a): `x` and `y` might already be of the same type, whether that be both are `string`s, `number`s, etc.\n\n* (1b): `x` and `y` might be of different types.\n\nLet's consider each of these cases individually.\n\n##### (1a) Known Matching Types\n\nIf the types in the equality comparison match (whatever they are), we already know for certain that `==` and `===` do exactly the same thing. There's absolutely no difference.\n\nExcept, `==` *is* shorter by one character. Most developers feel instinctively that the most terse but equivalent version of something is often most preferable. That's not universal, of course, but it's a general preference at least.\n\n```js\n// this is best\nif (x == y) {\n    // ..\n}\n```\n\nIn this particular case, an extra `=` would do nothing for us to make the code more clear. In fact, it actually would make the comparison worse!\n\n```js\n// this is strictly worse here!\nif (x === y) {\n    // ..\n}\n```\n\nWhy is it worse?\n\nBecause in scenario (2), we already established that `===` is used for the last-resort when we don't know enough/anything about the types to be able to predict the outcome. We use `===` when we want to make sure we're avoiding coercion when we know coercion could occur.\n\nBut that doesn't apply here! We already know that no coercion would occur. There's no reason to confuse the reader with a `===` here. If you use `===` in a place where you already *know* the types -- and moreover, they're matched! -- that actually might send a mixed signal to the reader. They might have assumed they knew what would happen in the equality check, but then they see the `===` and they second guess themselves!\n\nAgain, to state it plainly, if you know the types of an equality comparison, and you know they match, there's only one right choice: `==`.\n\n```js\n// stick to this option\nif (x == y) {\n    // ..\n}\n```\n\n##### (1b) Known Mismatched Types\n\nOK, we're in our final scenario. We need to compare `x` and `y`, and we know their types, but we also know their types are **NOT** the same.\n\nWhich operator should we use here?\n\nIf you pick `===`, you've made a huge mistake. Why!? Because `===` used with known-mismatched types will never, ever, ever return `true`. It will always fail.\n\n```js\n// `x` and `y` have different types?\nif (x === y) {\n    // congratulations, this code in here will NEVER run\n}\n```\n\nOK. So, `===` is out when the types are known and mismatched. What's our only other choice?\n\nWell, actually, we again have two options. We *could* decide:\n\n* (1b-1): Let's change the code so we're not trying to do an equality check with known mismatched types; that could involve explicitly coercing one or both values so they types now match, in which case pop back up to scenario (1a).\n\n* (1b-2): If we're going to compare known mismatched types for equality, and we want any hope of that check ever passing, we *must* used `==`, because it's the only one of the equality operators which can coerce one or both operands until the types match.\n\n```js\n// `x` and `y` have different types,\n// so let's allow JS to coerce them\n// for equality comparison\nif (x == y) {\n    // .. (so, you're saying there's a chance?)\n}\n```\n\nThat's it. We're done. We've looked at every possible type-sensitive equality comparison condition (between `x` and `y`).\n\n#### Summarizing Type-Sensitive Equality Comparison\n\nThe case for always preferring `==` over `===` is as follows:\n\n1. Whether you use TypeScript or not -- but especially if you *do* use TypeScript -- the goal should be to have every single part of the code, including all equality comparisons, be *type-aware*.\n\n2. If you know the types, you should always prefer `==`.\n\n    - In the case where the types match, `==` is both shorter and more proper for the check.\n\n    - In the case where the types are not matched, `==` is the only operator that can coerce operand(s) until the types match, so it's the only way such a check could ever hope to pass\n\n3. Finally, only if you *can't* know/predict the types, for some frustrating reason, and you have no other option, fall back to using `===` as a last resort. And probably add a code comment there admitting why `===` is being used, and maybe prompting some future developer to later change the code to fix that deficiency and remove the crutch of `===`.\n\n#### TypeScript's Inconsistency Problem\n\nLet me be super clear: if you're using TypeScript properly, and you know the types of an equality comparison, using `===` for that comparison is just plain *wrong*! Period.\n\nThe problem is, TypeScript strangely and frustratingly still requires you to use `===`, unless it already knows that the types are matched.\n\nThat's because TypeScript either doesn't fully understand type-awareness and coercion, or -- and this is even more infuriating! -- it fully understands but it still despises JS's type system so much as to eschew even the most basic of type-aware reasoning.\n\nDon't believe me? Think I'm being too harsh? Try this in TypeScript: [^TSExample2]\n\n```js\nlet result = (42 == \"42\");\n// This condition will always return 'false' since\n// the types 'number' and 'string' have no overlap.\n```\n\nI am at a loss for words to describe how aggravating that is to me. If you've paid attention to this long, heavy chapter, you know that TypeScript is basically telling a lie here. Of course `42 == \"42\"` will produce `true` in JS.\n\nWell, it's not a lie, but it's exposing a fundamental truth that so many still don't fully appreciate: TypeScript completely tosses out the normal rules of JS's type system, because TypeScript's position is that JS's type system -- and especially, implicit coercion -- are bad, and need to be replaced.\n\nIn TypeScript's world, `42` and `\"42\"` can never be equal to each other. Hence the error message. But in JS land, `42` and `\"42\"` are absolutely coercively equal to each other. And I believe I've made a strong case here that they *should be* assumed to be safely coercively equivalent.\n\nWhat bothers me even more is, TypeScript has a variety of inconsistencies in this respect. TypeScript is perfectly fine with the *implicit* coercion in this code:\n\n```js\nirony = `The value '42' and ${42} are coercively equal.`;\n```\n\nThe `42` gets implicitly coerced to a string when interpolating it into the sentence. Why is TypeScript ok with this implicit coercion, but not the `42 == \"42\"` implicit coercion?\n\nTypeScript has no complaints about this code, either:\n\n```js\nAPI_BASE_URL = \"https://some.tld/api/2\";\nif (API_BASE_URL) {\n    // ..\n}\n```\n\nWhy is `ToBoolean()` an OK implicit coercion, but `ToNumber()` in the `==` algorithm is not?\n\nI will leave you to ponder this: do you really think it's a good idea to write code that will ultimately run in a JS engine, but use a tool and style of code that has intentionally ejected most of an entire pillar of the JS language? Moreover, is it fine that it's also flip-flopped with a variety of inconsistent exceptions, simply to cater to the old habits of JS developers?\n\n## What's Left?\n\nI hope by now you're feeling a lot more informed about how JS's type system works, from primitive value types to the object types, to how type coercions are performed by the engine.\n\nMore importantly, you also now have a much more complete picture of the pros/cons of the choices we make using JS's type system, such as choosing *implicit* or *explicit* coercions at different points.\n\nBut we haven't fully covered the context in which the type system operates. For the remainder of this book, we'll turn our attention to the syntax/grammar rules of JS that govern how operators and statements behave.\n\n[^EichCoercion]: \"The State of JavaScript - Brendan Eich\", comment thread, Hacker News; Oct 9 2012; https://news.ycombinator.com/item?id=4632704 ; Accessed August 2022\n\n[^CrockfordCoercion]: \"JavaScript: The World's Most Misunderstood Programming Language\"; 2001; https://www.crockford.com/javascript/javascript.html ; Accessed August 2022\n\n[^CrockfordIfs]: \"json2.js\", Github; Apr 21 2018; https://github.com/douglascrockford/JSON-js/blob/8e8b0407e475e35942f7e9461dab81929fcc7321/json2.js#L336 ; Accessed August 2022\n\n[^BrendanToString]: ESDiscuss mailing list; Aug 26 2014; https://esdiscuss.org/topic/string-symbol#content-15 ; Accessed August 2022\n\n[^AbstractOperations]: \"7.1 Type Conversion\", ECMAScript 2022 Language Specification; https://262.ecma-international.org/13.0/#sec-type-conversion ; Accessed August 2022\n\n[^ToBoolean]: \"7.1.2 ToBoolean(argument)\", ECMAScript 2022 Language Specification; https://262.ecma-international.org/13.0/#sec-toboolean ; Accessed August 2022\n\n[^ExoticFalsyObjects]: \"B.3.6 The [[IsHTMLDDA]] Internal Slot\", ECMAScript 2022 Language Specification; https://262.ecma-international.org/13.0/#sec-IsHTMLDDA-internal-slot ; Accessed August 2022\n\n[^OrdinaryToPrimitive]: \"7.1.1.1 OrdinaryToPrimitive(O,hint)\", ECMAScript 2022 Language Specification; https://262.ecma-international.org/13.0/#sec-ordinarytoprimitive ; Accessed August 2022\n\n[^ToString]: \"7.1.17 ToString(argument)\", ECMAScript 2022 Language Specification; https://262.ecma-international.org/13.0/#sec-tostring ; Accessed August 2022\n\n[^StringConstructor]: \"22.1.1 The String Constructor\", ECMAScript 2022 Language Specification; https://262.ecma-international.org/13.0/#sec-string-constructor ; Accessed August 2022\n\n[^StringFunction]: \"22.1.1.1 String(value)\", ECMAScript 2022 Language Specification; https://262.ecma-international.org/13.0/#sec-string-constructor-string-value ; Accessed August 2022\n\n[^ToNumber]: \"7.1.4 ToNumber(argument)\", ECMAScript 2022 Language Specification; https://262.ecma-international.org/13.0/#sec-tonumber ; Accessed August 2022\n\n[^ToNumeric]: \"7.1.3 ToNumeric(argument)\", ECMAScript 2022 Language Specification; https://262.ecma-international.org/13.0/#sec-tonumeric ; Accessed August 2022\n\n[^NumberConstructor]: \"21.1.1 The Number Constructor\", ECMAScript 2022 Language Specification; https://262.ecma-international.org/13.0/#sec-number-constructor ; Accessed August 2022\n\n[^NumberFunction]: \"21.1.1.1 Number(value)\", ECMAScript 2022 Language Specification; https://262.ecma-international.org/13.0/#sec-number-constructor-number-value ; Accessed August 2022\n\n[^SameValue]: \"7.2.11 SameValue(x,y)\", ECMAScript 2022 Language Specification; https://262.ecma-international.org/13.0/#sec-samevalue ; Accessed August 2022\n\n[^StrictEquality]: \"7.2.16 IsStrictlyEqual(x,y)\", ECMAScript 2022 Language Specification; https://262.ecma-international.org/13.0/#sec-isstrictlyequal ; Accessed August 2022\n\n[^LooseEquality]: \"7.2.15 IsLooselyEqual(x,y)\", ECMAScript 2022 Language Specification; https://262.ecma-international.org/13.0/#sec-islooselyequal ; Accessed August 2022\n\n[^NumericAbstractOps]: \"6.1.6 Numeric Types\", ECMAScript 2022 Language Specification; https://262.ecma-international.org/13.0/#sec-numeric-types ; Accessed August 2022\n\n[^NumberEqual]: \"6.1.6.1.13 Number:equal(x,y)\", ECMAScript 2022 Language Specification; https://262.ecma-international.org/13.0/#sec-numeric-types-number-equal ; Accessed August 2022\n\n[^BigIntEqual]: \"6.1.6.2.13 BigInt:equal(x,y)\", ECMAScript 2022 Language Specification; https://262.ecma-international.org/13.0/#sec-numeric-types-bigint-equal ; Accessed August 2022\n\n[^LessThan]: \"7.2.14 IsLessThan(x,y,LeftFirst)\", ECMAScript 2022 Language Specification; https://262.ecma-international.org/13.0/#sec-islessthan ; Accessed August 2022\n\n[^StringPrefix]: \"7.2.9 IsStringPrefix(p,q)\", ECMAScript 2022 Language Specification; https://262.ecma-international.org/13.0/#sec-isstringprefix ; Accessed August 2022\n\n[^SymbolString]: \"String(symbol)\", ESDiscuss mailing list; Aug 12 2014; https://esdiscuss.org/topic/string-symbol ; Accessed August 2022\n\n[^ASMjs]: \"ASM.js - Working Draft\"; Aug 18 2014; http://asmjs.org/spec/latest/ ; Accessed August 2022\n\n[^TSExample1]: \"TypeScript Playground\"; https://tinyurl.com/ydkjs-ts-example-1 ; Accessed August 2022\n\n[^TSExample2]: \"TypeScript Playground\"; https://tinyurl.com/ydkjs-ts-example-2 ; Accessed August 2022\n\n[^TSLiteralTypes]: \"TypeScript 4.1, Template Literal Types\"; https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-1.html#template-literal-types ; Accessed August 2022\n"
  },
  {
    "path": "types-grammar/foreword.md",
    "content": "# You Don't Know JS Yet: Types & Grammar - 2nd Edition\n# Foreword\n\n| NOTE: |\n| :--- |\n| Work in progress |\n"
  },
  {
    "path": "types-grammar/thanks.md",
    "content": "# You Don't Know JS Yet: Types & Grammar - 2nd Edition\n# Thank You!\n\nThe following 371 Kickstarter backers generously backed the campaign to write/publish the four remaining books of the second edition. Without their faithful and patient support, these books would not have happened.\n\nI am deeply grateful to each of you!\n\n> Marc at Frontend Masters, Bassim, Tasos Tsournos, Lauren Clark, Simon, Appgrader, Marcos S., Noah Rodenbeek, Lichtjaeger, Jon Miller, Anil, Greg Gerard, Frank Deberle, Davide Bonifacio, Brandon Leichty, Rowdy Rabouw, Gaspar Radu, Sukumar Vaddi, Gordon, jakecodes, Leo Furze-Waddock, Nick de Jong, D. Vinci, Brian Vogel, Gareth loot, Simon Taylor, Chris O’Brien, Nayana Davis, Mark Kramer, Sunil Samuel, @nestor.j.g, Ryan McDaniel, Mert Even, Haim Yulzari, Josh Marks, Chiril Sarajiu, Barnabas Jovanovics, LynchyC, Yahya Jideh, Chris Weber, Dan Cortes, Johnny Tordgeman, Ky Lee, Brian Wisti, Steven Marrocco, Thomas Randolph, Petri Lindholm, John Cole, github, @denysmarkov, Jacob Scherber, Pierre-Yves Lebrun, mcekiera, Matthew Wasbrough, Génicot Jean-Baptiste, Adam Zając, Lenny Erlesand, Samuel Gustafsson, Hunter Jansen, Theo Armour, Nate Hargitt, Anon, Github repo, cawel, mpelikan, @farisaziz12, Ojars, Camilo Segura, Sean Seagren, Michael Vendivel, Evan, Eric Schwertfeger, Gene Garbutt, Elena Rogleva, Fiona Cheung, Anton Levholm, Lorenzo Bersano, Ando NARY, Ruben Krbashyan, Anonymous please, @jcubic, Bhavin Dave, A. Hitchcock, H0rn0chse, Yaniv Wainer, Zach, Raúl Pineda, Rohan Gupta, Karthik, Kapil, Ricardo Trejos, InvisibleLuis, BruceRobertson, Neil Lupton, Chris Schweda, Luca Mezzalira, antonio molinari, David Pinezich, Jon Barson, Nick Kaufmann, Just Andrew, Rock Kayode Winner, @omar12, Page Han, Aurélien Bottazini, Michael, Petr Siegl, Ilya Sarantsev, Alfredo Delgado, aharvard, Jannaee, Aaron McBride, Toma, epmatsw, Igor \"kibertoad\" Savin, Christian Rackerseder, NC Patro, Kevin, Brian Holt, Brian Ashenfelter, Selina Chang, cwavedave, Alex Grant, Craig Robertson, Eduardo Sanz Martin, oieduardorabelo, Esteban Massuh, tedhexaflow, Gershon Gerchikov, Harika Yedidi, Brad Dougherty, Nitin, Leo Balter, Syed Ahmad, Kaz de Groot, Pinnemouche Studio, Jerome Amos, Dan Poynor, John Liu, @thedavefulton, Madeline Bernard, Ikigai42, Antonio Chillaron, Sachin, Prakasam Venkatachalam, jmarti705, Mihailo23, Mihailo Pantovic, Magloire, samrudh, Mykenzie Rogers, Len, Lyza Danger Gardner, Ryan, Roman, Radojica Radivojevic, Gabrien Symons, Ryan Parker, Andrés, Merlin, rushabh_badani, notacouch, Anna Borja, Steve Albers, Marc at Frontend Masters, Bala Vemula, @chrismcdonald84, stern9, Janne Hellsten, Alexandre Madurell, Tanner Hodges, Joe Chellman, Joachim Kliemann, Stefano Frasson Pianizzola, Sergey Kochergan, Spiridonov Dmitriy, IonutBihari, Alexandru Olteanu, Javi, Marlee Peters, @vadocondes1, Gerardo Leal, Albert Sebastian, Atish Raina, Andreas Gebhardt, David Deren, Maksym Gerashchenko, Alexandru, Matt Peck, William Lacroix, Pavlo, Jon, Brett Walker, Iosif Psychas, Ferran Buireu, crs1138, Emiliano anichini, Max Koretskyi, Sander Elias, Michael Romanov, Barkóczi Dávid, Daw-Chih Liou, Dale Caffull, Amanda Dillon, Mike, Justin Hefko, Muhammad Ali Shah, Ketan Srivastav, redeemefy, Stefan Trivunčić, Manuel Juan Fosela Águila, Dragan Majstorović, Harsha C G, Himanshu, Luke, Sai Ponnada, Mark Franco, David Whittaker, Dr. Teresa Vasquez, Ian Wright, Lora Rusinouskaya, Petar, Harish, Mairead, shimon simo moyal, Sunny Puri, Максим Кочанов, Alex Georoceanu, Nicolas Carreras, damijanc, zach.dev, Coati, Brian Whitton, Denis Ciccale, Piotr Seefeld, Chase Hagwood, Amritha K, Κώστας Μηναϊδης, Trey Aughenbaugh, J David Eisenberg, Paul Thaden, Corina S, Chris Dhanaraj, Nahid Hossain, Justin McCullough, Arseny, Mark Trostler, Lucy Barker, Maaz Syed Adeeb, mcginkel, Derick Rodriguez, Helen Tsui, Rus Ustyugov, Vassilis Mastorostergios, Ryan Ewing, Rob Huelga, jinujj, ultimateoverload, Chaos, Andy Howell (spacebeers), Archana, AG Grid, theblang, Coyotiv School of Software Engineering, Ayush Rajniwal, Manish Bhatt, Shea Leslein, Jordan Chipman, jg0x42, Arvind Kumar, Eduardo Grigolo, Peter Svegrup, Jakub Kotula, William Richardson, Jonah and Ali, nicciwill, Lauren Hodges, Travis Sauer, Alexandros, Abhas, Kirankumar Ambati, Gopalakrishnan, Mika Rehman, Sreeram Sama, Shubhamsatyam Verma, Heejae Chang, Andrico karoulla, Niek Heezemans, Stanislav Horáček, Luis Ibanhi, Jasmine Wang, Yunier, Brian Barrow, Matteo Hertel, Aleksandar Milicevic, achung89, kushavi, Ahmed Fouad, Venkat Kaluva, Ian Wotkun, Andreas Näsman, ivan-siachoque, Paul Gain, Santhosh R, Gustavo Morales, ScottAwseome, Fredrik Thorkildsen, Manvel, holleB, James Sullivan, Adam Kaźmierczak, carlottosson, Alvee, Alex Reardon, Olie Chan, Fredrik S, Brett.Buskirk, Rui Sereno, Nathan Strong, lostdesign, ppseprus, James, anthonybsd, Alena Charnova, Kevin K, @codingthirty, Tim Davis, Jonathan Yee, Christa, Fabian Merchan, Nathanael McDaniel, Dave N, Brian Chirgwin, Abdulrahman (Abdu) Assabri, rmeja, Jan Václavek, Phillip Hogan, Adhithya Rajagopalan (xadhix), Jason Humphrey, Antoinette Smith, Elliot Redhead, zokocx, John Sims, Michalis Garganourakis, Adarsh Konchady, Anton Oleg Dobrovolskyy, George Tharakan, syd, Ryan D., Iris Nathan, Srishti Gupta, Miguel Rivero, @saileshraghavan, Yojan, @bgollum, Junyts, Like Ezugworie, Vsh13, LocalPCGuy, DMGabriel, Juan Tincho, William Greenlaw, atisbacsi, cris ryan tan, Jonathan Clifron, Daniel Dolich, Praj, Caisman, Michał, Mark C, 3xpedia\n\nA special thanks to:\n\n* A. Hitchcock\n* Alexandru\n* Appgrader\n* Coyotiv School of Software Engineering\n* Gaspar Radu\n* IonutBihari\n* jmarti705\n* John Liu\n* Syed Ahmad\n* Travis Sauer\n* William Greenlaw\n\nAll of you are fantastic!\n"
  },
  {
    "path": "types-grammar/toc.md",
    "content": "# You Don't Know JS Yet: Types & Grammar - 2nd Edition\n\n| NOTE: |\n| :--- |\n| Work in progress |\n\n## Table of Contents\n\n* Foreword\n* Preface\n* Chapter 1: Primitive Values\n\t* Value Types\n    * Empty Values\n    * Boolean Values\n    * String Values\n    * Number Values\n    * BigInteger Values\n    * Symbol Values\n    * Primitives Are Built-In Types\n* Chapter 2: Primitive Behaviors\n    * Primitive Immutability\n    * Primitive Assignments\n    * String Behaviors\n    * Number Behaviors\n    * Primitives Are Foundational\n* Chapter 3: Object Values\n    * Types of Objects\n    * Plain Objects\n    * Fundamental Objects\n    * Other Built-in Objects\n    * Arrays\n    * Regular Expressions\n    * Functions\n    * Proposed: Records/Tuples\n    * TODO\n* Chapter 4: Coercing Values\n    * Coercion: Explicit vs Implicit\n    * Abstracts\n    * Concrete Coercions\n    * Coercion Corner Cases\n    * Type Awareness\n    * What's Left?\n* Thank You!\n"
  }
]