├── .gitignore
├── LICENSE.txt
├── README.md
├── async & performance
├── README.md
├── apA.md
├── apB.md
├── apC.md
├── ch1.md
├── ch2.md
├── ch3.md
├── ch4.md
├── ch5.md
├── ch6.md
├── cover.jpg
├── foreword.md
└── toc.md
├── es6 & beyond
├── README.md
├── apA.md
├── ch1.md
├── ch2.md
├── ch3.md
├── ch4.md
├── ch5.md
├── ch6.md
├── ch7.md
├── ch8.md
├── fig1.png
├── foreword.md
└── toc.md
├── kickstarter-survey-site
├── Gruntfile.js
├── build-templates.js
├── csv
│ ├── $0.00.csv
│ └── $5.00.csv
├── email-invite.grips.html
├── generate.js
├── package.json
├── sample.secret.js
├── server.js
├── templates
│ ├── index.grips.html
│ ├── master.grips.html
│ ├── profile.grips.html
│ └── tmpls-wrapper.js
└── web
│ ├── css
│ └── site.css
│ └── js
│ ├── Format.js
│ ├── Notify.js
│ ├── Pages.js
│ ├── Tmpls.js
│ ├── Util.js
│ ├── Validate.js
│ ├── external
│ ├── asq.js
│ ├── grips.debug.min.js
│ ├── grips.min.js
│ ├── h5ive.bundle.js
│ └── history.js
│ ├── load.js
│ ├── pages
│ ├── index.js
│ └── profile.js
│ └── site.js
├── preface.md
├── scope & closures
├── README.md
├── apA.md
├── apB.md
├── apC.md
├── apD.md
├── ch1.md
├── ch2.md
├── ch3.md
├── ch4.md
├── ch5.md
├── cover.jpg
├── fig1.png
├── fig2.png
└── toc.md
├── this & object prototypes
├── README.md
├── apA.md
├── apB.md
├── ch1.md
├── ch2.md
├── ch3.md
├── ch4.md
├── ch5.md
├── ch6.md
├── cover.jpg
├── fig1.png
├── fig2.png
├── fig3.png
├── fig4.png
├── fig5.png
├── fig6.png
├── foreword.md
└── toc.md
├── types & grammar
├── README.md
├── apA.md
├── apB.md
├── ch1.md
├── ch2.md
├── ch3.md
├── ch4.md
├── ch5.md
├── cover.jpg
├── fig1.png
├── foreword.md
└── toc.md
└── up & going
├── README.md
├── apA.md
├── ch1.md
├── ch2.md
├── ch3.md
├── cover.jpg
├── fig1.png
├── fig2.png
├── fig3.png
├── fig4.png
├── fig5.png
├── fig6.png
├── foreword.md
└── toc.md
/.gitignore:
--------------------------------------------------------------------------------
1 | Thumbs.db
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 你不知道的JavaScript
2 |
3 | ## 翻译计划
4 |
5 | 开始翻译这个非常经典的JavaScript语言丛书,希望大家可以多多关注和参与帮忙。
6 |
7 | 对于现有的翻译内容,可以适当参考,如果有照抄照搬行为请先征求原作者同意,如引发纠纷,本仓库及相关负责人员不负责。
8 |
9 | 以下为部分翻译原则:
10 |
11 | - 优先翻译目前没有参考的干货;
12 | - 力求语义通顺,可以不要求字字对译;
13 | - 如准备翻译某部分,请先在issue中认领,以免重复劳动;
14 | - 对于没有公认较好翻译的专业术语,请在旁边以中文括号()加上英文原文,或直接使用英文原文。
15 |
16 | 所有参考内容,均需要写在下面的参考文献中:
17 |
18 | 参考文献:
19 |
20 | - [图灵社区公开的翻译内容](http://www.ituring.com.cn/book/1488)
21 |
22 | This is a series of books diving deep into the core mechanisms of the JavaScript language.
23 |
24 |
25 |
26 |
27 |
28 |
29 | ...(more coming soon!)
30 |
31 | Please feel free to contribute to the quality of this content by submitting PR's for improvements to code snippets, explanations, etc. While typo fixes are welcomed, they will likely be caught through normal editing processes, and are thus not necessarily as important for this repository.
32 |
33 | **To read more about the motivations and perspective behind this book series, check out the [Preface](preface.md).**
34 |
35 | ## Titles
36 |
37 | * Read online (free!): ["Up & Going"](up & going/README.md#you-dont-know-js-up--going), Published: [Buy Now](http://shop.oreilly.com/product/0636920039303.do), ebook format is free!
38 | * Read online (free!): ["Scope & Closures"](scope & closures/README.md#you-dont-know-js-scope--closures), Published: [Buy Now](http://shop.oreilly.com/product/0636920026327.do)
39 | * Read online (free!): ["this & Object Prototypes"](this & object prototypes/README.md#you-dont-know-js-this--object-prototypes), Published: [Buy Now](http://shop.oreilly.com/product/0636920033738.do)
40 | * Read online (free!): ["Types & Grammar"](types & grammar/README.md#you-dont-know-js-types--grammar), Published: [Buy Now](http://shop.oreilly.com/product/0636920033745.do)
41 | * Read online (free!): ["Async & Performance"](async & performance/README.md#you-dont-know-js-async--performance), Published: [Buy Now](http://shop.oreilly.com/product/0636920033752.do)
42 | * Read online (free!): ["ES6 & Beyond"](es6 & beyond/README.md#you-dont-know-js-es6--beyond) (in production)
43 |
44 | ## Publishing
45 |
46 | These books are being released here as drafts, free to read, but are also being edited, produced, and published through O'Reilly.
47 |
48 | If you like the content you find here, and want to support more content like it, please purchase the books once they are available for sale, through your normal book sources. :)
49 |
50 | If you'd like to contribute financially towards the effort (or any of my other OSS work) aside from purchasing the books, I do have a [patreon](https://www.patreon.com/getify) that I would always appreciate your generosity towards.
51 |
52 |
53 |
54 | ## In-person Training
55 |
56 | The content for these books derives heavily from a series of training materials I teach professionally (in both public and private-corporate workshop format), called "Advanced JS: The 'What You Need To Know' Parts".
57 |
58 | If you like this content and would like to contact me regarding conducting training on these, or other various JS/HTML5/node.js topics, please reach out to me through any of these channels listed here:
59 |
60 | [http://getify.me](http://getify.me)
61 |
62 | ## Online Video Training
63 |
64 | I also have some JS training material available in on-demand video format. I teach courses through [Frontend Masters](https://FrontendMasters.com), like my [Advanced JS](https://frontendmasters.com/courses/advanced-javascript/) workshop (more courses coming soon!).
65 |
66 | That same course is also [available through Pluralsight](http://www.pluralsight.com/courses/advanced-javascript).
67 |
68 | ## Content Contributions
69 |
70 | Any contributions you make to this effort **are of course greatly appreciated**.
71 |
72 | However, if you choose to contribute content (not just typo corrections) to this repo, you agree that you're giving me a non-exclusive license to use that content for the book series, as I (and O'Reilly) deem appropriate. You probably guessed that already, but we just have to make the lawyers happy by explicitly stating it.
73 |
74 | So: blah, blah, blah... :)
75 |
76 | ## License & Copyright
77 |
78 | The materials herein are all (c) 2013-2015 Kyle Simpson.
79 |
80 | This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.
81 |
--------------------------------------------------------------------------------
/async & performance/README.md:
--------------------------------------------------------------------------------
1 | # You Don't Know JS: Async & Performance
2 |
3 |
4 |
5 | -----
6 |
7 | **[Purchase digital/print copy from O'Reilly](http://shop.oreilly.com/product/0636920033752.do)**
8 |
9 | -----
10 |
11 | [Table of Contents](toc.md)
12 |
13 | * [Foreword](foreword.md) (by [Jake Archibald](http://jakearchibald.com))
14 | * [Preface](../preface.md)
15 | * [Chapter 1: Asynchrony: Now & Later](ch1.md)
16 | * [Chapter 2: Callbacks](ch2.md)
17 | * [Chapter 3: Promises](ch3.md)
18 | * [Chapter 4: Generators](ch4.md)
19 | * [Chapter 5: Program Performance](ch5.md)
20 | * [Chapter 6: Benchmarking & Tuning](ch6.md)
21 | * [Appendix A: Library: asynquence](apA.md)
22 | * [Appendix B: Advanced Async Patterns](apB.md)
23 | * [Appendix C: Thank You's!](apC.md)
24 |
--------------------------------------------------------------------------------
/async & performance/apC.md:
--------------------------------------------------------------------------------
1 | # You Don't Know JS: Async & Performance
2 | # Appendix C: Acknowledgments
3 |
4 | I have many people to thank for making this book title and the overall series happen.
5 |
6 | First, I must thank my wife Christen Simpson, and my two kids Ethan and Emily, for putting up with Dad always pecking away at the computer. Even when not writing books, my obsession with JavaScript glues my eyes to the screen far more than it should. That time I borrow from my family is the reason these books can so deeply and completely explain JavaScript to you, the reader. I owe my family everything.
7 |
8 | I'd like to thank my editors at O'Reilly, namely Simon St.Laurent and Brian MacDonald, as well as the rest of the editorial and marketing staff. They are fantastic to work with, and have been especially accommodating during this experiment into "open source" book writing, editing, and production.
9 |
10 | Thank you to the many folks who have participated in making this book series better by providing editorial suggestions and corrections, including Shelley Powers, Tim Ferro, Evan Borden, Forrest L. Norvell, Jennifer Davis, Jesse Harlin, Kris Kowal, Rick Waldron, Jordan Harband, Benjamin Gruenbaum, Vyacheslav Egorov, David Nolen, and many others. A big thank you to Jake Archibald for writing the Foreword for this title.
11 |
12 | Thank you to the countless folks in the community, including members of the TC39 committee, who have shared so much knowledge with the rest of us, and especially tolerated my incessant questions and explorations with patience and detail. John-David Dalton, Juriy "kangax" Zaytsev, Mathias Bynens, Axel Rauschmayer, Nicholas Zakas, Angus Croll, Reginald Braithwaite, Dave Herman, Brendan Eich, Allen Wirfs-Brock, Bradley Meck, Domenic Denicola, David Walsh, Tim Disney, Peter van der Zee, Andrea Giammarchi, Kit Cambridge, Eric Elliott, and so many others, I can't even scratch the surface.
13 |
14 | The *You Don't Know JS* book series was born on Kickstarter, so I also wish to thank all my (nearly) 500 generous backers, without whom this book series could not have happened:
15 |
16 | > Jan Szpila, nokiko, Murali Krishnamoorthy, Ryan Joy, Craig Patchett, pdqtrader, Dale Fukami, ray hatfield, R0drigo Perez [Mx], Dan Petitt, Jack Franklin, Andrew Berry, Brian Grinstead, Rob Sutherland, Sergi Meseguer, Phillip Gourley, Mark Watson, Jeff Carouth, Alfredo Sumaran, Martin Sachse, Marcio Barrios, Dan, AimelyneM, Matt Sullivan, Delnatte Pierre-Antoine, Jake Smith, Eugen Tudorancea, Iris, David Trinh, simonstl, Ray Daly, Uros Gruber, Justin Myers, Shai Zonis, Mom & Dad, Devin Clark, Dennis Palmer, Brian Panahi Johnson, Josh Marshall, Marshall, Dennis Kerr, Matt Steele, Erik Slagter, Sacah, Justin Rainbow, Christian Nilsson, Delapouite, D.Pereira, Nicolas Hoizey, George V. Reilly, Dan Reeves, Bruno Laturner, Chad Jennings, Shane King, Jeremiah Lee Cohick, od3n, Stan Yamane, Marko Vucinic, Jim B, Stephen Collins, Ægir Þorsteinsson, Eric Pederson, Owain, Nathan Smith, Jeanetteurphy, Alexandre ELISÉ, Chris Peterson, Rik Watson, Luke Matthews, Justin Lowery, Morten Nielsen, Vernon Kesner, Chetan Shenoy, Paul Tregoing, Marc Grabanski, Dion Almaer, Andrew Sullivan, Keith Elsass, Tom Burke, Brian Ashenfelter, David Stuart, Karl Swedberg, Graeme, Brandon Hays, John Christopher, Gior, manoj reddy, Chad Smith, Jared Harbour, Minoru TODA, Chris Wigley, Daniel Mee, Mike, Handyface, Alex Jahraus, Carl Furrow, Rob Foulkrod, Max Shishkin, Leigh Penny Jr., Robert Ferguson, Mike van Hoenselaar, Hasse Schougaard, rajan venkataguru, Jeff Adams, Trae Robbins, Rolf Langenhuijzen, Jorge Antunes, Alex Koloskov, Hugh Greenish, Tim Jones, Jose Ochoa, Michael Brennan-White, Naga Harish Muvva, Barkóczi Dávid, Kitt Hodsden, Paul McGraw, Sascha Goldhofer, Andrew Metcalf, Markus Krogh, Michael Mathews, Matt Jared, Juanfran, Georgie Kirschner, Kenny Lee, Ted Zhang, Amit Pahwa, Inbal Sinai, Dan Raine, Schabse Laks, Michael Tervoort, Alexandre Abreu, Alan Joseph Williams, NicolasD, Cindy Wong, Reg Braithwaite, LocalPCGuy, Jon Friskics, Chris Merriman, John Pena, Jacob Katz, Sue Lockwood, Magnus Johansson, Jeremy Crapsey, Grzegorz Pawłowski, nico nuzzaci, Christine Wilks, Hans Bergren, charles montgomery, Ariel בר-לבב Fogel, Ivan Kolev, Daniel Campos, Hugh Wood, Christian Bradford, Frédéric Harper, Ionuţ Dan Popa, Jeff Trimble, Rupert Wood, Trey Carrico, Pancho Lopez, Joël kuijten, Tom A Marra, Jeff Jewiss, Jacob Rios, Paolo Di Stefano, Soledad Penades, Chris Gerber, Andrey Dolganov, Wil Moore III, Thomas Martineau, Kareem, Ben Thouret, Udi Nir, Morgan Laupies, jory carson-burson, Nathan L Smith, Eric Damon Walters, Derry Lozano-Hoyland, Geoffrey Wiseman, mkeehner, KatieK, Scott MacFarlane, Brian LaShomb, Adrien Mas, christopher ross, Ian Littman, Dan Atkinson, Elliot Jobe, Nick Dozier, Peter Wooley, John Hoover, dan, Martin A. Jackson, Héctor Fernando Hurtado, andy ennamorato, Paul Seltmann, Melissa Gore, Dave Pollard, Jack Smith, Philip Da Silva, Guy Israeli, @megalithic, Damian Crawford, Felix Gliesche, April Carter Grant, Heidi, jim tierney, Andrea Giammarchi, Nico Vignola, Don Jones, Chris Hartjes, Alex Howes, john gibbon, David J. Groom, BBox, Yu 'Dilys' Sun, Nate Steiner, Brandon Satrom, Brian Wyant, Wesley Hales, Ian Pouncey, Timothy Kevin Oxley, George Terezakis, sanjay raj, Jordan Harband, Marko McLion, Wolfgang Kaufmann, Pascal Peuckert, Dave Nugent, Markus Liebelt, Welling Guzman, Nick Cooley, Daniel Mesquita, Robert Syvarth, Chris Coyier, Rémy Bach, Adam Dougal, Alistair Duggin, David Loidolt, Ed Richer, Brian Chenault, GoldFire Studios, Carles Andrés, Carlos Cabo, Yuya Saito, roberto ricardo, Barnett Klane, Mike Moore, Kevin Marx, Justin Love, Joe Taylor, Paul Dijou, Michael Kohler, Rob Cassie, Mike Tierney, Cody Leroy Lindley, tofuji, Shimon Schwartz, Raymond, Luc De Brouwer, David Hayes, Rhys Brett-Bowen, Dmitry, Aziz Khoury, Dean, Scott Tolinski - Level Up, Clement Boirie, Djordje Lukic, Anton Kotenko, Rafael Corral, Philip Hurwitz, Jonathan Pidgeon, Jason Campbell, Joseph C., SwiftOne, Jan Hohner, Derick Bailey, getify, Daniel Cousineau, Chris Charlton, Eric Turner, David Turner, Joël Galeran, Dharma Vagabond, adam, Dirk van Bergen, dave ♥♫★ furf, Vedran Zakanj, Ryan McAllen, Natalie Patrice Tucker, Eric J. Bivona, Adam Spooner, Aaron Cavano, Kelly Packer, Eric J, Martin Drenovac, Emilis, Michael Pelikan, Scott F. Walter, Josh Freeman, Brandon Hudgeons, vijay chennupati, Bill Glennon, Robin R., Troy Forster, otaku_coder, Brad, Scott, Frederick Ostrander, Adam Brill, Seb Flippence, Michael Anderson, Jacob, Adam Randlett, Standard, Joshua Clanton, Sebastian Kouba, Chris Deck, SwordFire, Hannes Papenberg, Richard Woeber, hnzz, Rob Crowther, Jedidiah Broadbent, Sergey Chernyshev, Jay-Ar Jamon, Ben Combee, luciano bonachela, Mark Tomlinson, Kit Cambridge, Michael Melgares, Jacob Adams, Adrian Bruinhout, Bev Wieber, Scott Puleo, Thomas Herzog, April Leone, Daniel Mizieliński, Kees van Ginkel, Jon Abrams, Erwin Heiser, Avi Laviad, David newell, Jean-Francois Turcot, Niko Roberts, Erik Dana, Charles Neill, Aaron Holmes, Grzegorz Ziółkowski, Nathan Youngman, Timothy, Jacob Mather, Michael Allan, Mohit Seth, Ryan Ewing, Benjamin Van Treese, Marcelo Santos, Denis Wolf, Phil Keys, Chris Yung, Timo Tijhof, Martin Lekvall, Agendine, Greg Whitworth, Helen Humphrey, Dougal Campbell, Johannes Harth, Bruno Girin, Brian Hough, Darren Newton, Craig McPheat, Olivier Tille, Dennis Roethig, Mathias Bynens, Brendan Stromberger, sundeep, John Meyer, Ron Male, John F Croston III, gigante, Carl Bergenhem, B.J. May, Rebekah Tyler, Ted Foxberry, Jordan Reese, Terry Suitor, afeliz, Tom Kiefer, Darragh Duffy, Kevin Vanderbeken, Andy Pearson, Simon Mac Donald, Abid Din, Chris Joel, Tomas Theunissen, David Dick, Paul Grock, Brandon Wood, John Weis, dgrebb, Nick Jenkins, Chuck Lane, Johnny Megahan, marzsman, Tatu Tamminen, Geoffrey Knauth, Alexander Tarmolov, Jeremy Tymes, Chad Auld, Sean Parmelee, Rob Staenke, Dan Bender, Yannick derwa, Joshua Jones, Geert Plaisier, Tom LeZotte, Christen Simpson, Stefan Bruvik, Justin Falcone, Carlos Santana, Michael Weiss, Pablo Villoslada, Peter deHaan, Dimitris Iliopoulos, seyDoggy, Adam Jordens, Noah Kantrowitz, Amol M, Matthew Winnard, Dirk Ginader, Phinam Bui, David Rapson, Andrew Baxter, Florian Bougel, Michael George, Alban Escalier, Daniel Sellers, Sasha Rudan, John Green, Robert Kowalski, David I. Teixeira (@ditma, Charles Carpenter, Justin Yost, Sam S, Denis Ciccale, Kevin Sheurs, Yannick Croissant, Pau Fracés, Stephen McGowan, Shawn Searcy, Chris Ruppel, Kevin Lamping, Jessica Campbell, Christopher Schmitt, Sablons, Jonathan Reisdorf, Bunni Gek, Teddy Huff, Michael Mullany, Michael Fürstenberg, Carl Henderson, Rick Yoesting, Scott Nichols, Hernán Ciudad, Andrew Maier, Mike Stapp, Jesse Shawl, Sérgio Lopes, jsulak, Shawn Price, Joel Clermont, Chris Ridmann, Sean Timm, Jason Finch, Aiden Montgomery, Elijah Manor, Derek Gathright, Jesse Harlin, Dillon Curry, Courtney Myers, Diego Cadenas, Arne de Bree, João Paulo Dubas, James Taylor, Philipp Kraeutli, Mihai Păun, Sam Gharegozlou, joshjs, Matt Murchison, Eric Windham, Timo Behrmann, Andrew Hall, joshua price, Théophile Villard
17 |
18 | This book series is being produced in an open source fashion, including editing and production. We owe GitHub a debt of gratitude for making that sort of thing possible for the community!
19 |
20 | Thank you again to all the countless folks I didn't name but who I nonetheless owe thanks. May this book series be "owned" by all of us and serve to contribute to increasing awareness and understanding of the JavaScript language, to the benefit of all current and future community contributors.
21 |
--------------------------------------------------------------------------------
/async & performance/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarStudio/You-Dont-Know-JS/f4b83f540033904867311c597d16232bd08a984e/async & performance/cover.jpg
--------------------------------------------------------------------------------
/async & performance/foreword.md:
--------------------------------------------------------------------------------
1 | # You Don't Know JS: Async & Performance
2 | # Foreword
3 |
4 | Over the years, my employer has trusted me enough to conduct interviews. If we're looking for someone with skills in JavaScript, my first line of questioning… actually that's not true, I first check if the candidate needs the bathroom and/or a drink, because comfort is important, but once I'm past the bit about the candidate's fluid in/out-take, I set about determining if the candidate knows JavaScript, or just jQuery.
5 |
6 | Not that there's anything wrong with jQuery. It lets you do a lot without really knowing JavaScript, and that's a feature not a bug. But if the job calls for advanced skills in JavaScript performance and maintainability, you need someone who knows how libraries such as jQuery are put together. You need to be able to harness the core of JavaScript the same way they do.
7 |
8 | If I want to get a picture of someone's core JavaScript skill, I'm most interested in what they make of closures (you've read that book of this series already, right?) and how to get the most out of asynchronicity, which brings us to this book.
9 |
10 | For starters, you'll be taken through callbacks, the bread and butter of asynchronous programming. Of course, bread and butter does not make for a particularly satisfying meal, but the next course is full of tasty tasty promises!
11 |
12 | If you don't know promises, now is the time to learn. Promises are now the official way to provide async return values in both JavaScript and the DOM. All future async DOM APIs will use them, many already do, so be prepared! At the time of writing, Promises have shipped in most major browsers, with IE shipping soon. Once you've finished that, I hope you left room for the next course, Generators.
13 |
14 | Generators snuck their way into stable versions of Chrome and Firefox without too much pomp and ceremony, because, frankly, they're more complicated than they are interesting. Or, that's what I thought until I saw them combined with promises. There, they become an important tool in readability and maintenance.
15 |
16 | For dessert, well, I won't spoil the surprise, but prepare to gaze into the future of JavaScript! Features that give you more and more control over concurrency and asynchronicity.
17 |
18 | Well, I won't block your enjoyment of the book any longer, on with the show! If you've already read part of the book before reading this Foreword, give yourself 10 asynchronous points! You deserve them!
19 |
20 | Jake Archibald
21 | [jakearchibald.com](http://jakearchibald.com), [@jaffathecake](http://twitter.com/jaffathecake)
22 | Developer Advocate at Google Chrome
23 |
--------------------------------------------------------------------------------
/async & performance/toc.md:
--------------------------------------------------------------------------------
1 | # You Don't Know JS: Async & Performance
2 |
3 | ## Table of Contents
4 |
5 | * Foreword
6 | * Preface
7 | * Chapter 1: Asynchrony: Now & Later
8 | * A Program In Chunks
9 | * Event Loop
10 | * Parallel Threading
11 | * Concurrency
12 | * Jobs
13 | * Statement Ordering
14 | * Chapter 2: Callbacks
15 | * Continuations
16 | * Sequential Brain
17 | * Trust Issues
18 | * Trying To Save Callbacks
19 | * Chapter 3: Promises
20 | * What is a Promise?
21 | * Thenable Duck-Typing
22 | * Promise Trust
23 | * Chain Flow
24 | * Error Handling
25 | * Promise Patterns
26 | * Promise API Recap
27 | * Promise Limitations
28 | * Chapter 4: Generators
29 | * Breaking Run-to-completion
30 | * Generator'ing Values
31 | * Iterating Generators Asynchronously
32 | * Generators + Promises
33 | * Generator Delegation
34 | * Generator Concurrency
35 | * Thunks
36 | * Pre-ES6 Generators
37 | * Chapter 5: Program Performance
38 | * Web Workers
39 | * SIMD
40 | * asm.js
41 | * Chapter 6: Benchmarking & Tuning
42 | * Benchmarking
43 | * Context Is King
44 | * jsPerf.com
45 | * Writing Good Tests
46 | * Microperformance
47 | * Tail Call Optimization (TCO)
48 | * Appendix A: *asynquence* Library
49 | * Appendix B: Advanced Async Patterns
50 | * Appendix C: Acknowledgments
51 |
52 |
--------------------------------------------------------------------------------
/es6 & beyond/README.md:
--------------------------------------------------------------------------------
1 | # You Don't Know JS: ES6 & Beyond
2 |
3 | -----
4 |
5 | **[Purchase digital/print copy from O'Reilly](http://shop.oreilly.com/product/0636920033769.do)**
6 |
7 | -----
8 |
9 | [Table of Contents](toc.md)
10 |
11 | * [Foreword](foreword.md) (by [Rick Waldron](http://bocoup.com/weblog/author/rick-waldron/))
12 | * [Preface](../preface.md)
13 | * [Chapter 1: ES? Now & Future](ch1.md)
14 | * [Chapter 2: Syntax](ch2.md)
15 | * [Chapter 3: Organization](ch3.md)
16 | * [Chapter 4: Async Flow Control](ch4.md)
17 | * [Chapter 5: Collections](ch5.md)
18 | * [Chapter 6: API Additions](ch6.md)
19 | * [Chapter 7: Meta Programming](ch7.md)
20 | * [Chapter 8: Beyond ES6](ch8.md)
21 | * [Appendix A: Thank You's!](apA.md)
22 |
--------------------------------------------------------------------------------
/es6 & beyond/apA.md:
--------------------------------------------------------------------------------
1 | # You Don't Know JS: ES6 & Beyond
2 | # Appendix A: Acknowledgments
3 |
4 | I have many people to thank for making this book title and the overall series happen.
5 |
6 | First, I must thank my wife Christen Simpson, and my two kids Ethan and Emily, for putting up with Dad always pecking away at the computer. Even when not writing books, my obsession with JavaScript glues my eyes to the screen far more than it should. That time I borrow from my family is the reason these books can so deeply and completely explain JavaScript to you, the reader. I owe my family everything.
7 |
8 | I'd like to thank my editors at O'Reilly, namely Simon St.Laurent and Brian MacDonald, as well as the rest of the editorial and marketing staff. They are fantastic to work with, and have been especially accommodating during this experiment into "open source" book writing, editing, and production.
9 |
10 | Thank you to the many folks who have participated in making this book series better by providing editorial suggestions and corrections, including Shelley Powers, Tim Ferro, Evan Borden, Forrest L. Norvell, Jennifer Davis, Jesse Harlin, and many others. A big thank you to Rick Waldron for writing the Foreword for this title.
11 |
12 | Thank you to the countless folks in the community, including members of the TC39 committee, who have shared so much knowledge with the rest of us, and especially tolerated my incessant questions and explorations with patience and detail. John-David Dalton, Juriy "kangax" Zaytsev, Mathias Bynens, Axel Rauschmayer, Nicholas Zakas, Angus Croll, Reginald Braithwaite, Dave Herman, Brendan Eich, Allen Wirfs-Brock, Bradley Meck, Domenic Denicola, David Walsh, Tim Disney, Peter van der Zee, Andrea Giammarchi, Kit Cambridge, Eric Elliott, André Bargull, Caitlin Potter, Brian Terlson, Ingvar Stepanyan, Chris Dickinson, Luke Hoban, and so many others, I can't even scratch the surface.
13 |
14 | The *You Don't Know JS* book series was born on Kickstarter, so I also wish to thank all my (nearly) 500 generous backers, without whom this book series could not have happened:
15 |
16 | > Jan Szpila, nokiko, Murali Krishnamoorthy, Ryan Joy, Craig Patchett, pdqtrader, Dale Fukami, ray hatfield, R0drigo Perez [Mx], Dan Petitt, Jack Franklin, Andrew Berry, Brian Grinstead, Rob Sutherland, Sergi Meseguer, Phillip Gourley, Mark Watson, Jeff Carouth, Alfredo Sumaran, Martin Sachse, Marcio Barrios, Dan, AimelyneM, Matt Sullivan, Delnatte Pierre-Antoine, Jake Smith, Eugen Tudorancea, Iris, David Trinh, simonstl, Ray Daly, Uros Gruber, Justin Myers, Shai Zonis, Mom & Dad, Devin Clark, Dennis Palmer, Brian Panahi Johnson, Josh Marshall, Marshall, Dennis Kerr, Matt Steele, Erik Slagter, Sacah, Justin Rainbow, Christian Nilsson, Delapouite, D.Pereira, Nicolas Hoizey, George V. Reilly, Dan Reeves, Bruno Laturner, Chad Jennings, Shane King, Jeremiah Lee Cohick, od3n, Stan Yamane, Marko Vucinic, Jim B, Stephen Collins, Ægir Þorsteinsson, Eric Pederson, Owain, Nathan Smith, Jeanetteurphy, Alexandre ELISÉ, Chris Peterson, Rik Watson, Luke Matthews, Justin Lowery, Morten Nielsen, Vernon Kesner, Chetan Shenoy, Paul Tregoing, Marc Grabanski, Dion Almaer, Andrew Sullivan, Keith Elsass, Tom Burke, Brian Ashenfelter, David Stuart, Karl Swedberg, Graeme, Brandon Hays, John Christopher, Gior, manoj reddy, Chad Smith, Jared Harbour, Minoru TODA, Chris Wigley, Daniel Mee, Mike, Handyface, Alex Jahraus, Carl Furrow, Rob Foulkrod, Max Shishkin, Leigh Penny Jr., Robert Ferguson, Mike van Hoenselaar, Hasse Schougaard, rajan venkataguru, Jeff Adams, Trae Robbins, Rolf Langenhuijzen, Jorge Antunes, Alex Koloskov, Hugh Greenish, Tim Jones, Jose Ochoa, Michael Brennan-White, Naga Harish Muvva, Barkóczi Dávid, Kitt Hodsden, Paul McGraw, Sascha Goldhofer, Andrew Metcalf, Markus Krogh, Michael Mathews, Matt Jared, Juanfran, Georgie Kirschner, Kenny Lee, Ted Zhang, Amit Pahwa, Inbal Sinai, Dan Raine, Schabse Laks, Michael Tervoort, Alexandre Abreu, Alan Joseph Williams, NicolasD, Cindy Wong, Reg Braithwaite, LocalPCGuy, Jon Friskics, Chris Merriman, John Pena, Jacob Katz, Sue Lockwood, Magnus Johansson, Jeremy Crapsey, Grzegorz Pawłowski, nico nuzzaci, Christine Wilks, Hans Bergren, charles montgomery, Ariel בר-לבב Fogel, Ivan Kolev, Daniel Campos, Hugh Wood, Christian Bradford, Frédéric Harper, Ionuţ Dan Popa, Jeff Trimble, Rupert Wood, Trey Carrico, Pancho Lopez, Joël kuijten, Tom A Marra, Jeff Jewiss, Jacob Rios, Paolo Di Stefano, Soledad Penades, Chris Gerber, Andrey Dolganov, Wil Moore III, Thomas Martineau, Kareem, Ben Thouret, Udi Nir, Morgan Laupies, jory carson-burson, Nathan L Smith, Eric Damon Walters, Derry Lozano-Hoyland, Geoffrey Wiseman, mkeehner, KatieK, Scott MacFarlane, Brian LaShomb, Adrien Mas, christopher ross, Ian Littman, Dan Atkinson, Elliot Jobe, Nick Dozier, Peter Wooley, John Hoover, dan, Martin A. Jackson, Héctor Fernando Hurtado, andy ennamorato, Paul Seltmann, Melissa Gore, Dave Pollard, Jack Smith, Philip Da Silva, Guy Israeli, @megalithic, Damian Crawford, Felix Gliesche, April Carter Grant, Heidi, jim tierney, Andrea Giammarchi, Nico Vignola, Don Jones, Chris Hartjes, Alex Howes, john gibbon, David J. Groom, BBox, Yu 'Dilys' Sun, Nate Steiner, Brandon Satrom, Brian Wyant, Wesley Hales, Ian Pouncey, Timothy Kevin Oxley, George Terezakis, sanjay raj, Jordan Harband, Marko McLion, Wolfgang Kaufmann, Pascal Peuckert, Dave Nugent, Markus Liebelt, Welling Guzman, Nick Cooley, Daniel Mesquita, Robert Syvarth, Chris Coyier, Rémy Bach, Adam Dougal, Alistair Duggin, David Loidolt, Ed Richer, Brian Chenault, GoldFire Studios, Carles Andrés, Carlos Cabo, Yuya Saito, roberto ricardo, Barnett Klane, Mike Moore, Kevin Marx, Justin Love, Joe Taylor, Paul Dijou, Michael Kohler, Rob Cassie, Mike Tierney, Cody Leroy Lindley, tofuji, Shimon Schwartz, Raymond, Luc De Brouwer, David Hayes, Rhys Brett-Bowen, Dmitry, Aziz Khoury, Dean, Scott Tolinski - Level Up, Clement Boirie, Djordje Lukic, Anton Kotenko, Rafael Corral, Philip Hurwitz, Jonathan Pidgeon, Jason Campbell, Joseph C., SwiftOne, Jan Hohner, Derick Bailey, getify, Daniel Cousineau, Chris Charlton, Eric Turner, David Turner, Joël Galeran, Dharma Vagabond, adam, Dirk van Bergen, dave ♥♫★ furf, Vedran Zakanj, Ryan McAllen, Natalie Patrice Tucker, Eric J. Bivona, Adam Spooner, Aaron Cavano, Kelly Packer, Eric J, Martin Drenovac, Emilis, Michael Pelikan, Scott F. Walter, Josh Freeman, Brandon Hudgeons, vijay chennupati, Bill Glennon, Robin R., Troy Forster, otaku_coder, Brad, Scott, Frederick Ostrander, Adam Brill, Seb Flippence, Michael Anderson, Jacob, Adam Randlett, Standard, Joshua Clanton, Sebastian Kouba, Chris Deck, SwordFire, Hannes Papenberg, Richard Woeber, hnzz, Rob Crowther, Jedidiah Broadbent, Sergey Chernyshev, Jay-Ar Jamon, Ben Combee, luciano bonachela, Mark Tomlinson, Kit Cambridge, Michael Melgares, Jacob Adams, Adrian Bruinhout, Bev Wieber, Scott Puleo, Thomas Herzog, April Leone, Daniel Mizieliński, Kees van Ginkel, Jon Abrams, Erwin Heiser, Avi Laviad, David newell, Jean-Francois Turcot, Niko Roberts, Erik Dana, Charles Neill, Aaron Holmes, Grzegorz Ziółkowski, Nathan Youngman, Timothy, Jacob Mather, Michael Allan, Mohit Seth, Ryan Ewing, Benjamin Van Treese, Marcelo Santos, Denis Wolf, Phil Keys, Chris Yung, Timo Tijhof, Martin Lekvall, Agendine, Greg Whitworth, Helen Humphrey, Dougal Campbell, Johannes Harth, Bruno Girin, Brian Hough, Darren Newton, Craig McPheat, Olivier Tille, Dennis Roethig, Mathias Bynens, Brendan Stromberger, sundeep, John Meyer, Ron Male, John F Croston III, gigante, Carl Bergenhem, B.J. May, Rebekah Tyler, Ted Foxberry, Jordan Reese, Terry Suitor, afeliz, Tom Kiefer, Darragh Duffy, Kevin Vanderbeken, Andy Pearson, Simon Mac Donald, Abid Din, Chris Joel, Tomas Theunissen, David Dick, Paul Grock, Brandon Wood, John Weis, dgrebb, Nick Jenkins, Chuck Lane, Johnny Megahan, marzsman, Tatu Tamminen, Geoffrey Knauth, Alexander Tarmolov, Jeremy Tymes, Chad Auld, Sean Parmelee, Rob Staenke, Dan Bender, Yannick derwa, Joshua Jones, Geert Plaisier, Tom LeZotte, Christen Simpson, Stefan Bruvik, Justin Falcone, Carlos Santana, Michael Weiss, Pablo Villoslada, Peter deHaan, Dimitris Iliopoulos, seyDoggy, Adam Jordens, Noah Kantrowitz, Amol M, Matthew Winnard, Dirk Ginader, Phinam Bui, David Rapson, Andrew Baxter, Florian Bougel, Michael George, Alban Escalier, Daniel Sellers, Sasha Rudan, John Green, Robert Kowalski, David I. Teixeira (@ditma, Charles Carpenter, Justin Yost, Sam S, Denis Ciccale, Kevin Sheurs, Yannick Croissant, Pau Fracés, Stephen McGowan, Shawn Searcy, Chris Ruppel, Kevin Lamping, Jessica Campbell, Christopher Schmitt, Sablons, Jonathan Reisdorf, Bunni Gek, Teddy Huff, Michael Mullany, Michael Fürstenberg, Carl Henderson, Rick Yoesting, Scott Nichols, Hernán Ciudad, Andrew Maier, Mike Stapp, Jesse Shawl, Sérgio Lopes, jsulak, Shawn Price, Joel Clermont, Chris Ridmann, Sean Timm, Jason Finch, Aiden Montgomery, Elijah Manor, Derek Gathright, Jesse Harlin, Dillon Curry, Courtney Myers, Diego Cadenas, Arne de Bree, João Paulo Dubas, James Taylor, Philipp Kraeutli, Mihai Păun, Sam Gharegozlou, joshjs, Matt Murchison, Eric Windham, Timo Behrmann, Andrew Hall, joshua price, Théophile Villard
17 |
18 | This book series is being produced in an open source fashion, including editing and production. We owe GitHub a debt of gratitude for making that sort of thing possible for the community!
19 |
20 | Thank you again to all the countless folks I didn't name but who I nonetheless owe thanks. May this book series be "owned" by all of us and serve to contribute to increasing awareness and understanding of the JavaScript language, to the benefit of all current and future community contributors.
21 |
--------------------------------------------------------------------------------
/es6 & beyond/ch1.md:
--------------------------------------------------------------------------------
1 | # You Don't Know JS: ES6 & Beyond
2 | # Chapter 1: ES? Now & Future
3 |
4 | Before you dive into this book, you should have a solid working proficiency over JavaScript up to the most recent standard (at the time of this writing), which is commonly called *ES5* (technically ES 5.1). Here, we plan to talk squarely about the upcoming *ES6*, as well as cast our vision beyond to understand how JS will evolve moving forward.
5 |
6 | If you are still looking for confidence with JavaScript, I highly recommend you read the other titles in this series first:
7 |
8 | * *Up & Going*: Are you new to programming and JS? This is the roadmap you need to consult as you start your learning journey.
9 | * *Scope & Closures*: Did you know that JS lexical scope is based on compiler (not interpreter!) semantics? Can you explain how closures are a direct result of lexical scope and functions as values?
10 | * *this & Object Prototypes*: Can you recite the four simple rules for how `this` is bound? Have you been muddling through fake "classes" in JS instead of adopting the simpler "behavior delegation" design pattern? Ever heard of *objects linked to other objects* (OLOO)?
11 | * *Types & Grammar*: Do you know the built-in types in JS, and more importantly, do you know how to properly and safely use coercion between types? How comfortable are you with the nuances of JS grammar/syntax?
12 | * *Async & Performance*: Are you still using callbacks to manage your asynchrony? Can you explain what a promise is and why/how it solves "callback hell"? Do you know how to use generators to improve the legibility of async code? What exactly constitutes mature optimization of JS programs and individual operations?
13 |
14 | If you've already read all those titles and you feel pretty comfortable with the topics they cover, it's time we dive into the evolution of JS to explore all the changes coming not only soon but farther over the horizon.
15 |
16 | Unlike ES5, ES6 is not just a modest set of new APIs added to the language. It incorporates a whole slew of new syntactic forms, some of which may take quite a bit of getting used to. There's also a variety of new organization forms and new API helpers for various data types.
17 |
18 | ES6 is a radical jump forward for the language. Even if you think you know JS in ES5, ES6 is full of new stuff you *don't know yet*, so get ready! This book explores all the major themes of ES6 that you need to get up to speed on, and even gives you a glimpse of future features coming down the track that you should be aware of.
19 |
20 | **Warning:** All code in this book assumes an ES6+ environment. At the time of this writing, ES6 support varies quite a bit in browsers and JS environments (like Node.js), so your mileage may vary.
21 |
22 | ## Versioning
23 |
24 | The JavaScript standard is referred to officially as "ECMAScript" (abbreviated "ES"), and up until just recently has been versioned entirely by ordinal number (i.e., "5" for "5th edition").
25 |
26 | The earliest versions, ES1 and ES2, were not widely known or implemented. ES3 was the first widespread baseline for JavaScript, and constitutes the JavaScript standard for browsers like IE6-8 and older Android 2.x mobile browsers. For political reasons beyond what we'll cover here, the ill-fated ES4 never came about.
27 |
28 | In 2009, ES5 was officially finalized (later ES5.1 in 2011), and settled as the widespread standard for JS for the modern revolution and explosion of browsers, such as Firefox, Chrome, Opera, Safari, and many others.
29 |
30 | Leading up to the expected *next* version of JS (slipped from 2013 to 2014 and then 2015), the obvious and common label in discourse has been ES6.
31 |
32 | However, late into the ES6 specification timeline, suggestions have surfaced that versioning may in the future switch to a year-based schema, such as ES2016 (aka ES7) to refer to whatever version of the specification is finalized before the end of 2016. Some disagree, but ES6 will likely maintain its dominant mindshare over the late-change substitute ES2015. However, ES2016 may in fact signal the new year-based schema.
33 |
34 | It has also been observed that the pace of JS evolution is much faster even than single-year versioning. As soon as an idea begins to progress through standards discussions, browsers start prototyping the feature, and early adopters start experimenting with the code.
35 |
36 | Usually well before there's an official stamp of approval, a feature is de facto standardized by virtue of this early engine/tooling prototyping. So it's also valid to consider the future of JS versioning to be per-feature rather than per-arbitrary-collection-of-major-features (as it is now) or even per-year (as it may become).
37 |
38 | The takeaway is that the version labels stop being as important, and JavaScript starts to be seen more as an evergreen, living standard. The best way to cope with this is to stop thinking about your code base as being "ES6-based," for instance, and instead consider it feature by feature for support.
39 |
40 | ## Transpiling
41 |
42 | Made even worse by the rapid evolution of features, a problem arises for JS developers who at once may both strongly desire to use new features while at the same time being slapped with the reality that their sites/apps may need to support older browsers without such support.
43 |
44 | The way ES5 appears to have played out in the broader industry, the typical mindset was that code bases waited to adopt ES5 until most if not all pre-ES5 environments had fallen out of their support spectrum. As a result, many are just recently (at the time of this writing) starting to adopt things like `strict` mode, which landed in ES5 over five years ago.
45 |
46 | It's widely considered to be a harmful approach for the future of the JS ecosystem to wait around and trail the specification by so many years. All those responsible for evolving the language desire for developers to begin basing their code on the new features and patterns as soon as they stabilize in specification form and browsers have a chance to implement them.
47 |
48 | So how do we resolve this seeming contradiction? The answer is tooling, specifically a technique called *transpiling* (transformation + compiling). Roughly, the idea is to use a special tool to transform your ES6 code into equivalent (or close!) matches that work in ES5 environments.
49 |
50 | For example, consider shorthand property definitions (see "Object Literal Extensions" in Chapter 2). Here's the ES6 form:
51 |
52 | ```js
53 | var foo = [1,2,3];
54 |
55 | var obj = {
56 | foo // means `foo: foo`
57 | };
58 |
59 | obj.foo; // [1,2,3]
60 | ```
61 |
62 | But (roughly) here's how that transpiles:
63 |
64 | ```js
65 | var foo = [1,2,3];
66 |
67 | var obj = {
68 | foo: foo
69 | };
70 |
71 | obj.foo; // [1,2,3]
72 | ```
73 |
74 | This is a minor but pleasant transformation that lets us shorten the `foo: foo` in an object literal declaration to just `foo`, if the names are the same.
75 |
76 | Transpilers perform these transformations for you, usually in a build workflow step similar to how you perform linting, minification, and other similar operations.
77 |
78 | ### Shims/Polyfills
79 |
80 | Not all new ES6 features need a transpiler. Polyfills (aka shims) are a pattern for defining equivalent behavior from a newer environment into an older environment, when possible. Syntax cannot be polyfilled, but APIs often can be.
81 |
82 | For example, `Object.is(..)` is a new utility for checking strict equality of two values but without the nuanced exceptions that `===` has for `NaN` and `-0` values. The polyfill for `Object.is(..)` is pretty easy:
83 |
84 | ```js
85 | if (!Object.is) {
86 | Object.is = function(v1, v2) {
87 | // test for `-0`
88 | if (v1 === 0 && v2 === 0) {
89 | return 1 / v1 === 1 / v2;
90 | }
91 | // test for `NaN`
92 | if (v1 !== v1) {
93 | return v2 !== v2;
94 | }
95 | // everything else
96 | return v1 === v2;
97 | };
98 | }
99 | ```
100 |
101 | **Tip:** Pay attention to the outer `if` statement guard wrapped around the polyfill. This is an important detail, which means the snippet only defines its fallback behavior for older environments where the API in question isn't already defined; it would be very rare that you'd want to overwrite an existing API.
102 |
103 | There's a great collection of ES6 shims called "ES6 Shim" (https://github.com/paulmillr/es6-shim/) that you should definitely adopt as a standard part of any new JS project!
104 |
105 | It is assumed that JS will continue to evolve constantly, with browsers rolling out support for features continually rather than in large chunks. So the best strategy for keeping updated as it evolves is to just introduce polyfill shims into your code base, and a transpiler step into your build workflow, right now and get used to that new reality.
106 |
107 | If you decide to keep the status quo and just wait around for all browsers without a feature supported to go away before you start using the feature, you're always going to be way behind. You'll sadly be missing out on all the innovations designed to make writing JavaScript more effective, efficient, and robust.
108 |
109 | ## Review
110 |
111 | ES6 (some may try to call it ES2015) is just landing as of the time of this writing, and it has lots of new stuff you need to learn!
112 |
113 | But it's even more important to shift your mindset to align with the new way that JavaScript is going to evolve. It's not just waiting around for years for some official document to get a vote of approval, as many have done in the past.
114 |
115 | Now, JavaScript features land in browsers as they become ready, and it's up to you whether you'll get on the train early or whether you'll be playing costly catch-up games years from now.
116 |
117 | Whatever labels that future JavaScript adopts, it's going to move a lot quicker than it ever has before. Transpilers and shims/polyfills are important tools to keep you on the forefront of where the language is headed.
118 |
119 | If there's any narrative important to understand about the new reality for JavaScript, it's that all JS developers are strongly implored to move from the trailing edge of the curve to the leading edge. And learning ES6 is where that all starts!
120 |
--------------------------------------------------------------------------------
/es6 & beyond/fig1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarStudio/You-Dont-Know-JS/f4b83f540033904867311c597d16232bd08a984e/es6 & beyond/fig1.png
--------------------------------------------------------------------------------
/es6 & beyond/foreword.md:
--------------------------------------------------------------------------------
1 | # You Don't Know JS: ES6 & Beyond
2 | # Foreword
3 |
4 | Kyle Simpson is a thorough pragmatist.
5 |
6 | I can't think of higher praise than this. To me, these are two of the most important qualities that a software developer must have. That's right: *must*, not *should*. Kyle's keen ability to tease apart layers of the JavaScript programming language and present them in understandable and meaningful portions is second to none.
7 |
8 | *ES6 & Beyond* will be familiar to readers of the *You Don't Know JS* series: they can expect to be deeply immersed in everything from the obvious, to the very subtle -- revealing semantics that were either taken for granted or never even considered. Until now, the *You Don't Know JS* book series has covered material that has at least some degree of familiarity to its readers. They have either seen or heard about the subject matter; they may even have experience with it. This volume covers material that only a very small portion of the JavaScript developer community has been exposed to: the evolutionary changes to the language introduced in the ECMAScript 2015 Language Specification.
9 |
10 | Over the last couple years, I've witnessed Kyle's tireless efforts to familiarize himself with this material to a level of expertise that is rivaled by only a handful of his professional peers. That's quite a feat, considering that at the time of this writing, the language specification document hasn't been formally published! But what I've said is true, and I've read every word that Kyle's written for this book. I've followed every change, and each time, the content only gets better and provides yet a deeper level of understanding.
11 |
12 | This book is about shaking up your sense of understanding by exposing you to the new and unknown. The intention is to evolve your knowledge in step with your tools by bestowing you with new capabilities. It exists to give you the confidence to fully embrace the next major era of JavaScript programming.
13 |
14 | Rick Waldron
15 | [@rwaldron](http://twitter.com/rwaldron)
16 | Open Web Engineer at Bocoup
17 | Ecma/TC39 Representative for jQuery
18 |
--------------------------------------------------------------------------------
/es6 & beyond/toc.md:
--------------------------------------------------------------------------------
1 | # You Don't Know JS: ES6 & Beyond
2 |
3 | ## Table of Contents
4 |
5 | * Foreword
6 | * Preface
7 | * Chapter 1: ES? Now & Future
8 | * Versioning
9 | * Transpiling
10 | * Chapter 2: Syntax
11 | * Block-Scoped Declarations
12 | * Spread / Rest
13 | * Default Parameter Values
14 | * Destructuring
15 | * Object Literal Extensions
16 | * Template Literals
17 | * Arrow Functions
18 | * `for..of` Loops
19 | * Regular Expression Extensions
20 | * Number Literal Extensions
21 | * Unicode
22 | * Symbols
23 | * Chapter 3: Organization
24 | * Iterators
25 | * Generators
26 | * Modules
27 | * Classes
28 | * Chapter 4: Async Flow Control
29 | * Promises
30 | * Generators + Promises
31 | * Chapter 5: Collections
32 | * TypedArrays
33 | * Maps
34 | * WeakMaps
35 | * Sets
36 | * WeakSets
37 | * Chapter 6: API Additions
38 | * `Array`
39 | * `Object`
40 | * `Math`
41 | * `Number`
42 | * `String`
43 | * Chapter 7: Meta Programming
44 | * Function Names
45 | * Meta Properties
46 | * Well Known Symbols
47 | * Proxies
48 | * `Reflect` API
49 | * Feature Testing
50 | * Tail Call Optimization (TCO)
51 | * Chapter 8: Beyond ES6
52 | * `async function`s
53 | * `Object.observe(..)`
54 | * Exponentiation Operator
55 | * Object Properties and `...`
56 | * `Array#includes(..)`
57 | * SIMD
58 | * Appendix A: Acknowledgments
59 |
--------------------------------------------------------------------------------
/kickstarter-survey-site/Gruntfile.js:
--------------------------------------------------------------------------------
1 | module.exports = function(grunt) {
2 | var path = require("path"), previous_force_state = grunt.option("force");
3 |
4 | // Project configuration.
5 | grunt.initConfig({
6 | pkg: grunt.file.readJSON("package.json"),
7 |
8 | forever: {
9 | options: {
10 | index: path.join(__dirname,"server.js"),
11 | logDir: ".",
12 | logFile: "output.txt",
13 | errFile: "error.txt"
14 | }
15 | },
16 | watch: {
17 | templates: {
18 | files: [
19 | path.join("templates","**","*.html"),
20 | path.join("templates","**","*.js")
21 | ],
22 | tasks: ["shell:build_templates"]
23 | }
24 | },
25 | shell: {
26 | build_templates: {
27 | options: {
28 | failOnError: true,
29 | stderr: true,
30 | stdout: true
31 | },
32 | command: path.join(__dirname, "build-templates.js")
33 | }
34 | }
35 | });
36 |
37 | // Load the plugins
38 | grunt.loadNpmTasks("grunt-contrib-watch");
39 | grunt.loadNpmTasks("grunt-shell");
40 | grunt.loadNpmTasks('grunt-forever');
41 |
42 | // define tasks
43 | grunt.registerTask("server-shutdown-listener",function(step){
44 | var name = this.name;
45 | if (step === "exit") {
46 | process.exit();
47 | }
48 | else {
49 | process.on("SIGINT",function(){
50 | grunt.log.writeln("").writeln("Shutting down server...");
51 | grunt.task.run([
52 | "force:on",
53 | "forever:stop",
54 | name + ":exit"
55 | ]);
56 | grunt.task.current.async()();
57 | });
58 | }
59 | });
60 |
61 | grunt.registerTask("default",function(){
62 | grunt.log.writeln("Please either run 'dev' or 'prod' target.");
63 | return false;
64 | });
65 |
66 | grunt.registerTask("force",function(set){
67 | if (set === "on") {
68 | grunt.option("force",true);
69 | }
70 | else if (set === "off") {
71 | grunt.option("force",false);
72 | }
73 | else if (set === "restore") {
74 | grunt.option("force",previous_force_state);
75 | }
76 | });
77 |
78 | grunt.registerTask("dev", [
79 | "shell:build_templates",
80 | "force:on", // temporary hack to turn on --force state
81 | "forever:stop",
82 | "force:restore", // temporary hack to restore previous --force state
83 | "forever:start",
84 | "server-shutdown-listener",
85 | "watch"
86 | ]);
87 |
88 | grunt.registerTask("set-prod-env",function(){
89 | process.env.NODE_ENV = "production";
90 | });
91 |
92 | grunt.registerTask("prod", [
93 | "set-prod-env",
94 | "shell:build_templates",
95 | "force:on", // temporary hack to turn on --force state
96 | "forever:stop",
97 | "force:restore", // temporary hack to restore previous --force state
98 | "forever:start"
99 | ]);
100 | };
101 |
--------------------------------------------------------------------------------
/kickstarter-survey-site/build-templates.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | // process the templates and build the template bundle
4 |
5 | function processTemplates(dir,collectionPrefix) {
6 | var files = fs.readdirSync(dir);
7 |
8 | files.forEach(function(file){
9 | var st = fs.statSync(path.join(dir,file)),
10 | contents, collection_id
11 | ;
12 |
13 | // template file to read contents and compile?
14 | if (st.isFile() && /\.grips\.html$/.test(file)) {
15 | console.log("Processing template: " + (collectionPrefix ? collectionPrefix + "/" : "") + file);
16 |
17 | contents = fs.readFileSync(path.join(dir,file),{ encoding: "utf8" });
18 |
19 | try {
20 | bundle_str += grips.compileCollection(
21 | /*source=*/contents,
22 | /*collectionID=*/collectionPrefix+"/"+(file.replace(/(?:\.?index)?\.grips\.html$/,"")),
23 | /*initialize=*/false
24 | );
25 | }
26 | catch (err) {
27 | console.error(err.stack || err.toString());
28 | process.exit(1);
29 | }
30 | }
31 | else if (st.isDirectory()) {
32 | processTemplates(path.join(dir,file),collectionPrefix+"/"+file);
33 | }
34 | });
35 | }
36 |
37 | var path = require("path"),
38 | fs = require("fs"),
39 |
40 | PROD = (process.env.NODE_ENV === "production"),
41 |
42 | grips = require("grips")[
43 | // either pull in production or debug of grips engine
44 | PROD ? "grips" : "debug"
45 | ],
46 |
47 | bundle_str = "",
48 |
49 | bundle_wrapper = fs.readFileSync(path.join(__dirname,"templates","tmpls-wrapper.js"),{ encoding: "utf8" })
50 | ;
51 |
52 | if (PROD) {
53 | console.log("*** Production template build ***");
54 | }
55 | else {
56 | console.log("*** Debug template build ***");
57 | }
58 |
59 | processTemplates(
60 | /*dir=*/path.join(__dirname,"templates"),
61 | /*collectionPrefix=*/""
62 | );
63 |
64 | bundle_wrapper = bundle_wrapper.replace(/\/\*TEMPLATES\*\//,function(){ return bundle_str; });
65 |
66 | fs.writeFileSync(
67 | path.join(__dirname,"web","js","Tmpls.js"),
68 | bundle_wrapper,
69 | { encoding: "utf8" }
70 | );
71 |
--------------------------------------------------------------------------------
/kickstarter-survey-site/csv/$0.00.csv:
--------------------------------------------------------------------------------
1 | Backer Id,Backer Name,Email,Pledge Amount,Pledged At,Pledged Status,Notes
2 | 1,Foo Bar,foo0@bar.com,$2.00 USD,"2013/06/01, 02:27",collected,
3 |
--------------------------------------------------------------------------------
/kickstarter-survey-site/csv/$5.00.csv:
--------------------------------------------------------------------------------
1 | Backer Id,Backer Name,Email,Pledge Amount,Pledged At,Rewards Sent?,Pledged Status,Notes
2 | 2,Baz Bam,baz@bam.com,$5.00 USD,"2013/05/13, 10:50","",collected,
3 |
--------------------------------------------------------------------------------
/kickstarter-survey-site/email-invite.grips.html:
--------------------------------------------------------------------------------
1 | {$define "#subject" }Kickstarter "You Don't Know JS": Reward Info Survey ({$insert $.name $}){$}
2 |
3 |
4 | {$define "#body" }
5 | {$insert $.name $},
6 |
7 | Thank you so much for being a backer last summer of my Kickstarter project for the "You Don't Know JS" book series.
8 |
9 | I know I'm well behind on the schedule for delivery of the books and the rewards, but I assure you I'm working hard to get all of them finished and fulfilled ASAP. I apologize for the long delays.
10 |
11 | To that end, I have built a simple survey site to collect information from you necessary to ensure proper fulfillment of all rewards. Please make sure to save this link, as it includes your unique account ID, and is necessary for you to access and update your information.
12 |
13 | http://kickstarter.youdontknowjs.com/#{$insert $.user_id $}
14 |
15 | Click the link (or copy-n-paste if clicking doesn't work in your email client), and enter the email you've received this notice at: {$insert $.email $}
16 |
17 | Once logged in, double-check that the information in the system already is correct, and make any changes or additions as necessary. You can re-visit the link above to update your information (for instance, if you change your email or move) as many times as necessary.
18 |
19 | Thanks again,
20 | Kyle Simpson (getify)
21 |
22 |
23 |
24 | {$}
25 |
--------------------------------------------------------------------------------
/kickstarter-survey-site/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "kickstarter-ydkjs",
3 | "version": "0.0.1",
4 | "engines": {
5 | "node": "0.10.22",
6 | "npm": "1.3.14"
7 | },
8 | "dependencies": {
9 | "asynquence": "latest",
10 | "asynquence-contrib": "latest",
11 | "cookie": "~0.1.0",
12 | "forever": "~0.10.8",
13 | "grips": "latest",
14 | "grunt": "~0.4.1",
15 | "grunt-shell": "~0.3.1",
16 | "grunt-contrib-watch": "~0.5.3",
17 | "grunt-contrib-compress": "~0.5.3",
18 | "grunt-forever": "~0.4.1",
19 | "nodemailer": "~0.6.0",
20 | "node-static": "~0.7.1",
21 | "sha1": "~1.1.0",
22 | "then-redis": "~0.3.8",
23 | "uglify-js": "~2.4",
24 | "watch": "~0.8.0"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/kickstarter-survey-site/sample.secret.js:
--------------------------------------------------------------------------------
1 | exports.SERVER_NAME = "..";
2 |
3 | exports.PUBLIC_SERVER_ADDR = "..";
4 | exports.PUBLIC_SERVER_PORT = 80;
5 |
6 | exports.INTERNAL_SERVER_ADDR = "..";
7 | exports.INTERNAL_SERVER_PORT = 8080;
8 |
9 | exports.REDIS_SERVER_ADDR = "..";
10 | exports.REDIS_SERVER_PORT = 0;
11 | exports.REDIS_SERVER_DB = 0;
12 |
13 | exports.PROD_STATIC_FILE_CACHE_LENGTH = 14400;
14 | exports.DEV_STATIC_FILE_CACHE_LENGTH = 1;
15 |
16 | exports.CORS_GET_HEADERS = {
17 | "Access-Control-Allow-Origin": "*",
18 | "Access-Control-Allow-Credentials": false,
19 | "Access-Control-Allow-Methods": "GET, OPTIONS",
20 | "Access-Control-Allow-Headers": "Content-Type, User-Agent, X-Requested-With"
21 | };
22 | exports.CORS_POST_HEADERS = {
23 | "Access-Control-Allow-Origin": "*",
24 | "Access-Control-Allow-Credentials": false,
25 | "Access-Control-Allow-Methods": "POST, OPTIONS",
26 | "Access-Control-Allow-Headers": "Content-Type, User-Agent, X-Requested-With"
27 | };
28 |
--------------------------------------------------------------------------------
/kickstarter-survey-site/templates/index.grips.html:
--------------------------------------------------------------------------------
1 | {$extend "/master" $}
2 |
3 |
4 | {$define "#content" |
5 | info = !$.logged_in ? "#login"
6 | }
7 |
84 | please list a permanent address, good for at least the next 3-6 months
85 |
86 | {$partial shipping_type $}
87 |
88 | {$}
89 |
90 |
91 | {$define "#domestic_shipping" }
92 |
150 | {$}
151 |
--------------------------------------------------------------------------------
/kickstarter-survey-site/templates/tmpls-wrapper.js:
--------------------------------------------------------------------------------
1 | (function UMD(name,context,definition) {
2 | if (typeof module != "undefined" && module.exports) module.exports = definition();
3 | else if (typeof define == "function" && define.amd) define(definition);
4 | else context[name] = definition(name,context);
5 | })("Tmpls",this,function definition(name,context) {
6 | "use strict";
7 |
8 | function init() {
9 | /*TEMPLATES*/
10 | }
11 |
12 | var public_api;
13 |
14 | public_api = {
15 | init: init
16 | };
17 |
18 | return public_api;
19 | });
20 |
--------------------------------------------------------------------------------
/kickstarter-survey-site/web/css/site.css:
--------------------------------------------------------------------------------
1 | *, *:before, *:after {
2 | -moz-box-sizing: border-box;
3 | box-sizing: border-box;
4 | }
5 |
6 | html, body {
7 | padding: 0px;
8 | margin: 0px;
9 | }
10 |
11 | html, body, input[type=text], input[type=password],
12 | input[type=checkbox], input[type=radio], textarea {
13 | font-size: 16px;
14 | line-height: 23px;
15 | font-family: Tahoma, sans-serif;
16 | background-color: #bbb;
17 | color: #000;
18 | letter-spacing: 2px;
19 | border: none;
20 | }
21 |
22 | input[type=text], input[type=password], textarea {
23 | border: 2px solid #000;
24 | }
25 |
26 | input[type=text][readonly], input[type=password][readonly],
27 | input[type=checkbox][readonly], input[type=radio][readonly],
28 | textarea[readonly] {
29 | color: #444;
30 | background-color: #999;
31 | }
32 |
33 | ::-webkit-input-placeholder { color: #777; }
34 | ::-moz-placeholder { color: #777; }
35 | :-ms-input-placeholder { color: #777; }
36 |
37 | #content {
38 | padding: 25px;
39 | }
40 |
41 | nav {
42 | padding: 0px 10px;
43 | background-color: #ddd;
44 | color: black;
45 | width: 100%;
46 | height: 60px;
47 | line-height: 60px;
48 | font-size: 20px;
49 | font-weight: bold;
50 | }
51 |
52 | nav a {
53 | color: black;
54 | text-decoration: none;
55 | }
56 |
57 | #notifications {
58 | display: none;
59 | position: fixed;
60 | top: 5px;
61 | right: 10px;
62 | width: 300px;
63 | background-color: #000;
64 | color: white;
65 | border: 2px solid #fff;
66 | padding: 10px;
67 | }
68 |
69 | #notifications .list {
70 | min-height: 20px;
71 | max-height: 100px;
72 | overflow: scroll;
73 | }
74 |
75 | #notifications .close {
76 | position: absolute;
77 | right: -5px;
78 | top: -5px;
79 | background-color: #000;
80 | color: white;
81 | border: 2px solid #fff;
82 | font-size: 12px;
83 | line-height: 20px;
84 | width: 20px;
85 | font-weight: bold;
86 | text-align: center;
87 | letter-spacing: 0px;
88 | cursor: pointer;
89 | }
90 |
91 | #notifications .list .notification {
92 | padding-bottom: 10px;
93 | margin-bottom: 10px;
94 | border-bottom: 1px solid white;
95 | }
96 |
97 | #notifications .list .notification:last-child {
98 | padding-bottom: 0px;
99 | margin-bottom: 0px;
100 | border-bottom: none;
101 | }
102 |
103 | #email_modal {
104 | display: none;
105 | position: fixed;
106 | background-color: #aaa;
107 | border: 2px solid #000;
108 | padding: 50px;
109 | left: 50%;
110 | top: 50%;
111 | -webkit-transform: translate(-50%, -50%);
112 | transform: translate(-50%, -50%);
113 | }
114 |
--------------------------------------------------------------------------------
/kickstarter-survey-site/web/js/Format.js:
--------------------------------------------------------------------------------
1 | (function UMD(name,context,definition) {
2 | if (typeof module != "undefined" && module.exports) module.exports = definition();
3 | else if (typeof define == "function" && define.amd) define(definition);
4 | else context[name] = definition(name,context);
5 | })("Format",this || {},function definition(name,context) {
6 | "use strict";
7 |
8 | function trim(str) {
9 | return str.replace(/^\s+/,"").replace(/\s+$/,"");
10 | }
11 |
12 | function formatLogin(data) {
13 | // map the login data fields to profile fields
14 | if ("login_email" in data) {
15 | data.profile_email = data.login_email;
16 | delete data.login_email;
17 | }
18 |
19 | formatProfileInfo(data);
20 | }
21 |
22 | function formatProfileInfo(data) {
23 | if ("profile_email" in data) {
24 | data.profile_email = trim(data.profile_email.toLowerCase());
25 |
26 | if (data.profile_email.length > 100) {
27 | data.profile_email = data.profile_email.substr(0,100);
28 | if (context.Notify) {
29 | Notify.warn("Email must be 100 or less characters");
30 | }
31 | }
32 | }
33 | if ("profile_name" in data) {
34 | data.profile_name = trim(data.profile_name);
35 |
36 | if (data.profile_name.length > 50) {
37 | data.profile_name = data.profile_name.substr(0,50);
38 | if (context.Notify) {
39 | Notify.warn("Name must be 50 or less characters");
40 | }
41 | }
42 | }
43 | if ("profile_twitter" in data) {
44 | data.profile_twitter = trim(data.profile_twitter);
45 |
46 | if (data.profile_twitter.length > 15) {
47 | data.profile_twitter = data.profile_twitter.substr(0,15);
48 | if (context.Notify) {
49 | Notify.warn("Twitter account must be 15 or less characters");
50 | }
51 | }
52 | }
53 | if ("profile_phone" in data) {
54 | data.profile_phone = trim(data.profile_phone.replace(/[^\d\+]/g,""));
55 |
56 | if (data.profile_phone.length > 15) {
57 | data.profile_phone = data.profile_phone.substr(0,15);
58 | if (context.Notify) {
59 | Notify.warn("Phone must be 15 or less numbers");
60 | }
61 | }
62 | }
63 | if ("profile_credit" in data) {
64 | data.profile_credit = trim(data.profile_credit);
65 |
66 | if (data.profile_credit.length > 25) {
67 | data.profile_credit = data.profile_credit.substr(0,25);
68 | if (context.Notify) {
69 | Notify.warn("Listing must be 25 or less numbers");
70 | }
71 | }
72 | }
73 | if ("profile_shipping" in data) {
74 | if ("address" in data.profile_shipping) {
75 | data.profile_shipping.address = trim(data.profile_shipping.address);
76 |
77 | if (data.profile_shipping.address.length > 150) {
78 | data.profile_shipping.address = data.profile_shipping.address.substr(0,150);
79 | if (context.Notify) {
80 | Notify.warn("Shipping address must be 150 or less characters");
81 | }
82 | }
83 | }
84 | if (data.profile_shipping.domestic) {
85 | if ("city" in data.profile_shipping) {
86 | data.profile_shipping.city = trim(data.profile_shipping.city);
87 |
88 | if (data.profile_shipping.city.length > 50) {
89 | data.profile_shipping.city = data.profile_shipping.city.substr(0,50);
90 | if (context.Notify) {
91 | Notify.warn("Shipping city must be 50 or less characters");
92 | }
93 | }
94 | }
95 | if ("zip" in data.profile_shipping) {
96 | data.profile_shipping.zip = trim(data.profile_shipping.zip.replace(/[^\d\-]/g,""));
97 |
98 | if (data.profile_shipping.zip.length > 10) {
99 | data.profile_shipping.city = data.profile_shipping.city.substr(0,50);
100 | if (context.Notify) {
101 | Notify.warn("Shipping zip must be 10 or less characters");
102 | }
103 | }
104 | }
105 | }
106 | else {
107 | data.profile_shipping.city = data.profile_shipping.state = data.profile_shipping.zip = null;
108 | }
109 | }
110 | }
111 |
112 | var public_api;
113 |
114 | public_api = {
115 | formatLogin: formatLogin,
116 | formatProfileInfo: formatProfileInfo
117 | };
118 |
119 | return public_api;
120 | });
121 |
--------------------------------------------------------------------------------
/kickstarter-survey-site/web/js/Notify.js:
--------------------------------------------------------------------------------
1 | (function(global){
2 | "use strict";
3 |
4 | var notifications = [],
5 | $notifications,
6 | $notifications_list,
7 | $close
8 | ;
9 |
10 | function notice(msg) {
11 | var i, $msg, notification;
12 |
13 | // cache DOM lookups
14 | $notifications = $notifications || $("#notifications");
15 | $notifications_list = $notifications_list || $notifications.children(".list");
16 | if (!$close) {
17 | $close = $notifications.children(".close");
18 | $close.bind("click",reset);
19 | }
20 |
21 | for (i=0; i").addClass("notification").text(msg);
33 |
34 | $notifications_list.prepend($msg);
35 | $notifications.show();
36 | }
37 |
38 | function warn(msg) {
39 | notice(msg);
40 | }
41 |
42 | function error(msg) {
43 | notice(msg);
44 | }
45 |
46 | function reset() {
47 | notifications.length = 0;
48 | if ($notifications) {
49 | $notifications_list.empty();
50 | $notifications.hide();
51 | }
52 | }
53 |
54 | global.Notify = {
55 | notice: notice,
56 | warn: warn,
57 | error: error,
58 |
59 | reset: reset
60 | };
61 |
62 | })(window);
63 |
--------------------------------------------------------------------------------
/kickstarter-survey-site/web/js/Pages.js:
--------------------------------------------------------------------------------
1 | (function UMD(name,context,definition) {
2 | if (typeof module != "undefined" && module.exports) module.exports = definition();
3 | else if (typeof define == "function" && define.amd) define(definition);
4 | else context[name] = definition(name,context);
5 | })("Pages",this,function definition(name,context) {
6 | "use strict";
7 |
8 | // parseUri 1.2.2
9 | // (c) Steven Levithan
10 | // MIT License
11 | function parseUri(e){var a=parseUri.options,f=a.parser[a.strictMode?"strict":"loose"].exec(e),b={},c=14;while(c--)b[a.key[c]]=f[c]||"";b[a.q.name]={};b[a.key[12]].replace(a.q.parser,function(h,d,g){if(d)b[a.q.name][d]=g});return b}parseUri.options={strictMode:false,key:["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],q:{name:"queryKey",parser:/(?:^|&)([^&=]*)=?([^&]*)/g},parser:{strict:/^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,loose:/^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/}};
12 |
13 | function getPageURL(url) {
14 | var uriparts = parseUri(url);
15 | if (!uriparts.path) {
16 | return "/";
17 | }
18 | else {
19 | return uriparts.path;
20 | }
21 | }
22 |
23 | function siteInit() {
24 | // load and run script for current page
25 | current_page_url = getPageURL(context.document.location.href.toString());
26 | fetchPageScript(current_page_url);
27 |
28 | page_title = $("title").html();
29 |
30 | History.Adapter.bind(window,"statechange",function(){
31 | var state = History.getState();
32 |
33 | if (getPageURL(state.url) !== current_page_url) {
34 | gotoPage(state.url,/*suppressHistory=*/true);
35 | }
36 | });
37 |
38 | $(context.document.body).on("click","#logout",function(evt){
39 | if (Util.session_id) {
40 | $.ajax({
41 | type: "POST",
42 | url: "/logout/do",
43 | data: JSON.stringify({
44 | session_id: Util.session_id
45 | }),
46 | processData: false,
47 | contentType: "application/javascript; charset=UTF-8"
48 | })
49 | .complete(function(){
50 | Util.killSession();
51 | gotoPage("/",/*suppressHistory=*/true);
52 | Pages.replaceURL("/");
53 | Pages.updateNav(/*loggedIn=*/false);
54 |
55 | Notify.notice("Logged out!");
56 | });
57 | }
58 |
59 | evt.preventDefault();
60 | evt.stopImmediatePropagation();
61 | });
62 |
63 | $(context.document.body).on("click","a:not([data-ignore])",function(evt){
64 | var href = evt.currentTarget.href;
65 |
66 | // disable JS-only (or just empty) links
67 | if (evt.currentTarget.getAttribute("href") === "#") {
68 | evt.preventDefault();
69 | evt.stopImmediatePropagation();
70 | }
71 | else if (recognize(href) !== false) {
72 | evt.preventDefault();
73 | evt.stopImmediatePropagation();
74 |
75 | gotoPage(href);
76 | }
77 | });
78 | }
79 |
80 | function gotoPage(url,suppressHistory,passData) {
81 | var content_html, page_url;
82 |
83 | page_url = recognize(url);
84 |
85 | if (page_url !== false) {
86 | if (page_url !== current_page_url) {
87 | // teardown the existing page
88 | pageScriptAPI(current_page_url).teardown();
89 |
90 | Notify.reset();
91 |
92 | current_page_url = page_url;
93 |
94 | content_html = getPageContentHTML(current_page_url);
95 | $("#content").replaceWith(content_html);
96 |
97 | fetchPageScript(current_page_url,passData);
98 |
99 | if (!suppressHistory) {
100 | History.pushState(null,null,url);
101 | document.title = page_title;
102 | }
103 |
104 | return;
105 | }
106 | }
107 |
108 | if (url !== context.document.location.href.toString()) {
109 | context.document.location.href = url;
110 | current_page_url = getPageURL(url);
111 | }
112 | }
113 |
114 | function replaceURL(url) {
115 | History.replaceState(null,null,url);
116 | document.title = page_title;
117 | }
118 |
119 | function pageScriptAPI(url) {
120 | return public_api.page_scripts[(url === "/" ? "/index" : url)] || public_api.page_scripts["."];
121 | }
122 |
123 | function fetchPageScript(url,passData) {
124 | url = getPageURL(url);
125 |
126 | // remap the root page URL just for the purposes of this function
127 | if (url === "/") url = "/index";
128 |
129 | if (!(url in public_api.page_scripts)) {
130 | $LAB
131 | .script("/js/pages" + url + ".js")
132 | .wait(function(){
133 | pageScriptAPI(url).init(passData);
134 | });
135 | }
136 | else {
137 | pageScriptAPI(url).init(passData);
138 | }
139 | }
140 |
141 | function updateNav(loggedIn) {
142 | var nav_html = grips.render("/master#mainnav",{
143 | logged_in: loggedIn
144 | });
145 | $("#mainnav").replaceWith(nav_html);
146 | }
147 |
148 | // ******************
149 |
150 | function getPageHTML(url,data) {
151 | data = data || {};
152 | if (!("logged_in" in data) && Util.session_id) {
153 | data.logged_in = true;
154 | }
155 |
156 | try {
157 | // render page with 'grips' engine
158 | return public_api.grips.render(url + "#page",data);
159 | }
160 | catch (err) {
161 | console.error(err);
162 | return "";
163 | }
164 | }
165 |
166 | function getPageContentHTML(url,data) {
167 | return getSnippetHTML(url + "#content",data);
168 | }
169 |
170 | function getSnippetHTML(url,data) {
171 | data = data || {};
172 | if (!("logged_in" in data) && Util.session_id) {
173 | data.logged_in = true;
174 | }
175 |
176 | try {
177 | // render page with 'grips' engine
178 | return public_api.grips.render(url,data);
179 | }
180 | catch (err) {
181 | console.error(err);
182 | return "";
183 | }
184 | }
185 |
186 | function recognize(url) {
187 | url = getPageURL(url);
188 |
189 | if (url in public_api.grips.collections) {
190 | return url;
191 | }
192 | else {
193 | return false;
194 | }
195 | }
196 |
197 | context = context || {};
198 |
199 | var $ = context.$ || {},
200 | $LAB = context.$LAB || {},
201 | History = context.History || {},
202 | Util = context.Util || {},
203 |
204 | current_page_url,
205 | current_page_num,
206 |
207 | public_api,
208 |
209 | page_title
210 | ;
211 |
212 | public_api = {
213 | // browser-only stuff
214 | siteInit: siteInit,
215 | gotoPage: gotoPage,
216 | replaceURL: replaceURL,
217 | fetchPageScript: fetchPageScript,
218 | updateNav: updateNav,
219 | page_scripts: {
220 | // default no-ops
221 | ".": { init:function(){}, teardown:function(){} }
222 | },
223 |
224 | // used both in browser and on server
225 | getPageURL: getPageURL,
226 | getPageHTML: getPageHTML,
227 | getPageContentHTML: getPageContentHTML,
228 | getSnippetHTML: getSnippetHTML,
229 | recognize: recognize,
230 | parseUri: parseUri
231 | };
232 |
233 | return public_api;
234 | });
235 |
--------------------------------------------------------------------------------
/kickstarter-survey-site/web/js/Util.js:
--------------------------------------------------------------------------------
1 | (function UMD(name,context,definition) {
2 | if (typeof module != "undefined" && module.exports) module.exports = definition();
3 | else if (typeof define == "function" && define.amd) define(definition);
4 | else context[name] = definition(name,context);
5 | })("Util",this,function definition(name,context) {
6 | "use strict";
7 |
8 | // make session store (h5.storage API) backed by session cookies
9 | function sessionCookiesStorage() {
10 |
11 | function createCookie(name,value) {
12 | document.cookie = name + "=" + value + "; path=/";
13 | }
14 |
15 | function readCookie(name) {
16 | var nameEQ = name + "=";
17 | var ca = document.cookie.split(";");
18 | for(var i=0; i 0 && (keys[0] in ret)) {
59 | return ret[keys[0]];
60 | }
61 | return;
62 | }
63 | return ret;
64 | },
65 | discard: function(keys) {
66 | if (Object.prototype.toString.call(keys) !== "[object Array]") {
67 | keys = [keys];
68 | }
69 | for (var i=0; i0){q=!1,c=r.shift(),e=t.slice(),t.length=0,e.unshift(d());try{c.apply(c,e)}catch(f){u.push(f),o=!0,b()}}}function d(){function a(){o||p||q||(q=!0,t.push.apply(t,arguments),u.length=0,b())}return a.fail=function(){o||p||q||(o=!0,t.length=0,u.push.apply(u,arguments),b())},a.abort=function(){o||p||(q=!1,p=!0,t.length=0,u.length=0,b())},a}function g(a,b,c){function d(){clearTimeout(v),v=s=t=u=null}function g(){return l?h():(v||(v=f(h)),void 0)}function h(){if(!(o||p||m)){var b,c=[];if(v=null,k)a.fail.apply(a,u),d();else if(l)a.abort(),d();else if(i()){for(m=!0,b=0;b1?a:a[0],s[b]=!0,g()}}var b=s.length;return a.fail=function(){o||p||k||l||m||s[b]||(k=!0,u=e.call(arguments),g())},a.abort=function(){o||p||k||l||m||(l=!0,h())},s[b]=null,a}var n,q,r,u,v,k=!1,l=!1,m=!1,s=[],t={};for(n=0;n0&&r.push.apply(r,arguments),b(),w)}function i(){return p?w:(s.push.apply(s,arguments),b(),w)}function j(){if(o||p||0===arguments.length)return w;var a=e.apply(arguments);return h(function(b){var c=e.call(arguments);c.shift(),g(b,a,c)}),w}function k(){if(o||p||0===arguments.length)return w;var a,b=e.call(arguments);for(a=0;a0&&w.then.apply(w,arguments),w}return a}var c,d=(b||{})[a],e=Array.prototype.slice;return c=g(),c.noConflict=function(){return b&&(b[a]=d),c},c});
6 |
--------------------------------------------------------------------------------
/kickstarter-survey-site/web/js/external/grips.debug.min.js:
--------------------------------------------------------------------------------
1 | /* grips (c) 2012 Kyle Simpson | http://getify.mit-license.org/ */
2 | ;Object.keys||(Object.keys=function(t){var n,r=[];for(n in t)t.hasOwnProperty(n)&&r.push(n);return r}),Array.isArray||(Array.isArray=function(t){return Object.prototype.toString(t)==="[object Array]"}),Object.create||(Object.create=function(t){function n(){}return n.prototype=t,new n}),Object.prototype.toJSON||(Object.prototype.toJSON=function(){function t(e){for(var t=0;t0)i=m[m.length-1];else if(!f||m.length>0&&m[m.length-1]===i){if(!i)throw new e("Required collection ID missing: "+t)||v}else m.push(i),l=!0;if(i in d){t=t.replace(/^(.+)#/,"#"),u=i+t,g.push(u);for(o=0;o"]/.test(e)&&(e=e.replace(/&/g,"&").replace(//g,">").replace(/"/g,""")),t.string&&(e=e.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/'/g,"\\'").replace(/\r/g,"\\r").replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029").replace(/\n/g,"\\n").replace(/\f/g,"\\f").replace(/\t/g,"\\t")),t.url&&(e=encodeURIComponent(e))),e}var e=function(){function n(){}function r(e,r,i){var s=this===t?new n:this;return s.message=e,s.ref=r,s.stack=i,s}return n.prototype=r.prototype=Object.create(ReferenceError.prototype),r.prototype.constructor=r,r.prototype.toString=function(){var t="TemplateError: "+this.message;return this.ref&&(t+="; "+JSON.stringify(this.ref)),t=t.replace(/[\n\r]+/g," ").replace(/\s+/g," "),this.stack&&(t+="\n"+this.stack),t},r}(),p,d={},v=new Error("Unknown error"),m=[],g=[];return p={extend:u,cloneObj:a,definePartial:l,strEscapes:h,render:c,error:f,TemplateError:e,noConflict:s,sandbox:r,RangeLiteralHash:i,collections:d},p}var n=t.grips;t.grips=r()}(this);
--------------------------------------------------------------------------------
/kickstarter-survey-site/web/js/external/grips.min.js:
--------------------------------------------------------------------------------
1 | /* grips (c) 2012 Kyle Simpson | http://getify.mit-license.org/ */
2 | ;Object.keys||(Object.keys=function(t){var n,r=[];for(n in t)t.hasOwnProperty(n)&&r.push(n);return r}),Array.isArray||(Array.isArray=function(t){return Object.prototype.toString(t)==="[object Array]"}),function(t){function r(){function e(){}function i(){var e=t.grips;return t.grips=n,e}function s(e){e in h||(h[e]={collection:"",extend:null,partials:{}})}function o(e,t){s(e),h[e].extend=t}function u(t){var n,r,i;if(typeof t=="object"){if(t===null)return t;if(Array.isArray(t)){r=[];for(n=0;n0)r=d[d.length-1];else if(!a||d.length>0&&d[d.length-1]===r){if(!r)throw p}else d.push(r),f=!0;if(r in h){e=e.replace(/^(.+)#/,"#"),o=r+e,v.push(o);for(s=0;s"]/.test(e)&&(e=e.replace(/&/g,"&").replace(//g,">").replace(/"/g,""")),t.string&&(e=e.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/'/g,"\\'").replace(/\r/g,"\\r").replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029").replace(/\n/g,"\\n").replace(/\f/g,"\\f").replace(/\t/g,"\\t")),t.url&&(e=encodeURIComponent(e))),e}var c,h={},p=new Error("Unknown error"),d=[],v=[];return c={extend:o,cloneObj:u,definePartial:a,strEscapes:l,render:f,noConflict:i,sandbox:r,RangeLiteralHash:e,collections:h},c}var n=t.grips;t.grips=r()}(this);
--------------------------------------------------------------------------------
/kickstarter-survey-site/web/js/external/h5ive.bundle.js:
--------------------------------------------------------------------------------
1 | /*! h5ive:storage | (c) Kyle Simpson | MIT License: http://getify.mit-license.org */
2 | (function(e){e.h5={}})(this),function(e){if(!e)throw new Error("storage.h5ive: core.h5ive required.");e.storage=function(e){function i(e){var i,s;for(i in e)s={"h5ive:data":e[i]},r&&(s["h5ive:expires"]=r),t.setItem(i,JSON.stringify(s));return n}function s(e){Object.prototype.toString.call(e)!="[object Array]"&&(e=[e]);for(var r=0;r=r["h5ive:expires"]){delete i[e[n]],t.removeItem(e[n]);continue}i[e[n]]=r["h5ive:data"]}}catch(o){}}if(e.length<2){if(e.length>0&&e[0]in i)return i[e[0]];return}return i}var t,n,r;return e=e||{},"expires"in e&&typeof e.expires=="number"&&e.expires>0&&(r=e.expires+(new Date).getTime()),e.expires=="session"?t=sessionStorage:t=localStorage,n={save:i,discard:s,get:o},n}}(this.h5);
3 |
--------------------------------------------------------------------------------
/kickstarter-survey-site/web/js/load.js:
--------------------------------------------------------------------------------
1 | /*! LAB.js (LABjs :: Loading And Blocking JavaScript)
2 | v2.0.3 (c) Kyle Simpson
3 | MIT License
4 | */
5 | (function(o){var K=o.$LAB,y="UseLocalXHR",z="AlwaysPreserveOrder",u="AllowDuplicates",A="CacheBust",B="BasePath",C=/^[^?#]*\//.exec(location.href)[0],D=/^\w+\:\/\/\/?[^\/]+/.exec(C)[0],i=document.head||document.getElementsByTagName("head"),L=(o.opera&&Object.prototype.toString.call(o.opera)=="[object Opera]")||("MozAppearance"in document.documentElement.style),q=document.createElement("script"),E=typeof q.preload=="boolean",r=E||(q.readyState&&q.readyState=="uninitialized"),F=!r&&q.async===true,M=!r&&!F&&!L;function G(a){return Object.prototype.toString.call(a)=="[object Function]"}function H(a){return Object.prototype.toString.call(a)=="[object Array]"}function N(a,c){var b=/^\w+\:\/\//;if(/^\/\/\/?/.test(a)){a=location.protocol+a}else if(!b.test(a)&&a.charAt(0)!="/"){a=(c||"")+a}return b.test(a)?a:((a.charAt(0)=="/"?D:C)+a)}function s(a,c){for(var b in a){if(a.hasOwnProperty(b)){c[b]=a[b]}}return c}function O(a){var c=false;for(var b=0;b0){for(var a=0;a=0;){d=n.shift();a=a[d.type].apply(null,d.args)}return a},noConflict:function(){o.$LAB=K;return m},sandbox:function(){return J()}};return m}o.$LAB=J();(function(a,c,b){if(document.readyState==null&&document[a]){document.readyState="loading";document[a](c,b=function(){document.removeEventListener(c,b,false);document.readyState="complete"},false)}})("addEventListener","DOMContentLoaded")})(this);
6 |
7 | (function(global){
8 | "use strict";
9 |
10 | global.$LAB.setGlobalDefaults({ CacheBust: true });
11 |
12 | global.$LAB
13 | .script("//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js")
14 | .script("/js/external/asq.js")
15 | .script("/js/external/grips.debug.min.js")
16 | .script("/js/external/h5ive.bundle.js")
17 | .script("/js/external/history.js")
18 |
19 | .script("/js/Validate.js")
20 | .script("/js/Format.js")
21 | .script("/js/Notify.js")
22 | .script("/js/Tmpls.js")
23 | .wait()
24 |
25 | .script("/js/Util.js")
26 | .script("/js/Pages.js")
27 | .wait()
28 |
29 | .script("/js/site.js");
30 |
31 | })(window);
32 |
--------------------------------------------------------------------------------
/kickstarter-survey-site/web/js/pages/index.js:
--------------------------------------------------------------------------------
1 | (function(global,Pages){
2 | "use strict";
3 |
4 | function doLogin() {
5 | var res, data,
6 | url_parts = Pages.parseUri(document.location.href.toString())
7 | ;
8 |
9 | // if site is disabled, don't proceed
10 | if (Pages.disabled) {
11 | Notify.error("Not allowed");
12 | return;
13 | }
14 |
15 | data = {
16 | login_email: $login_email.val()
17 | };
18 |
19 | if (url_parts.anchor) {
20 | data.user_id = url_parts.anchor;
21 | data.user_id = data.user_id.replace(/[^a-f0-9\-]/ig,"");
22 | }
23 |
24 | // first validate the entered data
25 | res = Validate.checkLogin(data);
26 |
27 | if (res !== true) {
28 | Notify.error(res);
29 | return;
30 | }
31 |
32 | // make sure the data is formatted correctly
33 | Format.formatLogin(data);
34 |
35 | // Login user
36 | Notify.reset();
37 | Notify.notice("Verifying user ID and email, please wait...");
38 | $.ajax({
39 | type: "POST",
40 | url: "/user/verify",
41 | data: JSON.stringify(data),
42 | processData: false,
43 | contentType: "application/javascript; charset=UTF-8",
44 | dataType: "json"
45 | })
46 | .success(function(res) {
47 | Notify.reset();
48 | if (res.success) {
49 | Util.startSession(/*sessionID=*/res.success);
50 | postLogin();
51 | }
52 | else {
53 | Notify.error("Verification failed: " + (res.error || res));
54 | }
55 | })
56 | .error(function(jqx,err,errObj){
57 | Notify.reset();
58 | Notify.error("Verification failed: " + err + (errObj ? "; " + JSON.stringify(errObj.stack || errObj) : ""));
59 | });
60 | }
61 |
62 | function postLogin(data) {
63 | Pages.gotoPage("/profile",/*suppressHistory=*/true,data);
64 | Pages.replaceURL("/profile");
65 | Pages.updateNav(/*loggedIn=*/true);
66 | }
67 |
68 | function init(){
69 | $verify_user = $("#verify_user");
70 | $login_email = $("#login_email");
71 |
72 | $verify_user.click(doLogin);
73 | }
74 |
75 | function teardown(){
76 | $verify_user.unbind("click");
77 | $login_email = $verify_user = null;
78 | }
79 |
80 | var $login_email,
81 | $verify_user
82 | ;
83 |
84 | Pages.page_scripts["/index"] = {
85 | init: init,
86 | teardown: teardown
87 | };
88 |
89 | })(window,Pages);
90 |
--------------------------------------------------------------------------------
/kickstarter-survey-site/web/js/pages/profile.js:
--------------------------------------------------------------------------------
1 | (function(global,Pages){
2 | "use strict";
3 |
4 | function doUpdate() {
5 | var res, data;
6 |
7 | // if site is disabled, don't proceed
8 | if (Pages.disabled) {
9 | Notify.error("Not allowed");
10 | return;
11 | }
12 |
13 | data = {
14 | session_id: Util.session_id,
15 | profile_name: $profile_name.val(),
16 | profile_twitter: $profile_twitter.val(),
17 | profile_phone: $profile_phone.val(),
18 | profile_credit: $profile_credit.val()
19 | };
20 |
21 | if ($profile_shirt_size.length > 0) {
22 | data.profile_shirt_size = $profile_shirt_size.val();
23 | }
24 |
25 | if ($profile_shipping_domestic.length > 0) {
26 | data.profile_shipping = {
27 | domestic: $profile_shipping_domestic.is(":checked"),
28 | address: $profile_shipping_address.val()
29 | };
30 |
31 | // save additional domestic shipping fields?
32 | if (data.profile_shipping.domestic) {
33 | data.profile_shipping.city = $profile_shipping_city.val();
34 | data.profile_shipping.state = $profile_shipping_state.val();
35 | data.profile_shipping.zip = $profile_shipping_zip.val();
36 | }
37 | }
38 |
39 | // first validate the entered data
40 | res = Validate.checkProfileInfo(data);
41 |
42 | if (res !== true) {
43 | Notify.error(res);
44 | return;
45 | }
46 |
47 | Notify.reset();
48 | Notify.notice("Updating profile, please wait...");
49 |
50 | // make sure the data is formatted correctly
51 | Format.formatProfileInfo(data);
52 |
53 | // save profile info
54 | $.ajax({
55 | type: "POST",
56 | url: "/profile/update",
57 | data: JSON.stringify(data),
58 | processData: false,
59 | contentType: "application/javascript; charset=UTF-8",
60 | dataType: "json"
61 | })
62 | .success(function(res) {
63 | if (res.success) {
64 | Notify.reset();
65 | Notify.notice("Profile updated");
66 | }
67 | else {
68 | Notify.reset();
69 | Notify.error("Update failed: " + (res.error || res));
70 | }
71 | })
72 | .error(function(jqx,err,errObj){
73 | Notify.reset();
74 | Notify.error("Update failed: " + err + (errObj ? "; " + JSON.stringify(errObj.stack || errObj) : ""));
75 | });
76 | }
77 |
78 | function doUpdateEmail() {
79 | var res, data;
80 |
81 | // if site is disabled, don't proceed
82 | if (Pages.disabled) {
83 | Notify.error("Not allowed");
84 | return;
85 | }
86 |
87 | data = {
88 | session_id: Util.session_id,
89 | profile_email: $("#new_email").val()
90 | };
91 |
92 | // first validate the entered data
93 | res = Validate.checkProfileInfo(data);
94 |
95 | if (res !== true) {
96 | Notify.error(res);
97 | return;
98 | }
99 |
100 | // make sure the data is formatted correctly
101 | Format.formatProfileInfo(data);
102 |
103 | if (data.profile_email === current_email) {
104 | Notify.error("Email must be different");
105 | return;
106 | }
107 |
108 | Notify.reset();
109 | Notify.notice("Updating profile, please wait...");
110 |
111 | // save profile info
112 | $.ajax({
113 | type: "POST",
114 | url: "/profile/update-email",
115 | data: JSON.stringify(data),
116 | processData: false,
117 | contentType: "application/javascript; charset=UTF-8",
118 | dataType: "json"
119 | })
120 | .success(function(res) {
121 | hideEmailModal();
122 |
123 | if (res.success) {
124 | // refresh the profile view after the email update
125 | doFetch();
126 | }
127 | else {
128 | $("#new_email").val("");
129 | Notify.reset();
130 | Notify.error("Update failed: " + (res.error || res));
131 | }
132 | })
133 | .error(function(jqx,err,errObj){
134 | hideEmailModal();
135 | $("#new_email").val("");
136 | Notify.reset();
137 | Notify.error("Update failed: " + err + (errObj ? "; " + JSON.stringify(errObj.stack || errObj) : ""));
138 | });
139 | }
140 |
141 | function doFetch() {
142 | var data = {
143 | session_id: Util.session_id
144 | };
145 |
146 | // fetch profile info
147 | Notify.reset();
148 | Notify.notice("Loading profile, please wait...");
149 | $.ajax({
150 | type: "POST",
151 | url: "/profile/get",
152 | data: JSON.stringify(data),
153 | processData: false,
154 | contentType: "application/javascript; charset=UTF-8",
155 | dataType: "json"
156 | })
157 | .success(function(res) {
158 | var html;
159 |
160 | Notify.reset();
161 | if (res.profile && res.profile.profile_email) {
162 | teardown();
163 | html = Pages.getPageContentHTML("/profile",res.profile);
164 | $("#content").replaceWith(html);
165 | current_email = res.profile.profile_email;
166 | init();
167 | }
168 | else {
169 | Notify.error("Profile load failed: " + (res.error || res));
170 | }
171 | })
172 | .error(function(jqx,err,errObj){
173 | Notify.reset();
174 | Notify.error("Profile load failed: " + err + (errObj ? "; " + JSON.stringify(errObj.stack || errObj) : ""));
175 | });
176 | }
177 |
178 | function swapShippingType() {
179 | var cur_address = $profile_shipping_address.val(), html;
180 |
181 | if ($profile_shipping_domestic.is(":checked")) {
182 | html = Pages.getSnippetHTML("/profile#domestic_shipping",{
183 | profile_shipping: {
184 | domestic: true,
185 | address: cur_address,
186 | city: "",
187 | state: "",
188 | zip: ""
189 | }
190 | });
191 |
192 | teardown();
193 | $("#shipping_info").replaceWith(html);
194 | init();
195 | }
196 | else {
197 | html = Pages.getSnippetHTML("/profile#international_shipping",{
198 | profile_shipping: {
199 | domestic: false,
200 | address: cur_address
201 | }
202 | });
203 |
204 | teardown();
205 | $("#shipping_info").replaceWith(html);
206 | init();
207 | }
208 | }
209 |
210 | function init(){
211 | if ($("#content").is(".loading")) {
212 | doFetch();
213 | }
214 | else {
215 | $profile_email = $("#profile_email");
216 | $modify_email = $("#modify_email");
217 | $profile_name = $("#profile_name");
218 | $profile_twitter = $("#profile_twitter");
219 | $profile_phone = $("#profile_phone");
220 | $profile_credit = $("#profile_credit");
221 | $profile_shirt_size = $("#profile_shirt_size");
222 | $profile_shipping_domestic = $("#profile_shipping_domestic");
223 | $profile_shipping_address = $("#profile_shipping_address");
224 | $profile_shipping_city = $("#profile_shipping_city");
225 | $profile_shipping_state = $("#profile_shipping_state");
226 | $profile_shipping_zip = $("#profile_shipping_zip");
227 | $update_profile = $("#update_profile");
228 |
229 | $profile_shipping_domestic.bind("change",swapShippingType);
230 | $update_profile.click(doUpdate);
231 | $modify_email.click(showEmailModal);
232 |
233 | if (!current_email) {
234 | current_email = $profile_email.val();
235 | }
236 | }
237 | }
238 |
239 | function teardown(){
240 | if ($update_profile) {
241 | $update_profile.unbind("click");
242 |
243 | $profile_email = $modify_email = $profile_name = $profile_twitter = $profile_phone =
244 | $profile_credit = $profile_shirt_size = $profile_shipping_domestic =
245 | $profile_shipping_address = $profile_shipping_city =
246 | $profile_shipping_state = $profile_shipping_zip =
247 | $update_profile = null;
248 | }
249 | }
250 |
251 | function showEmailModal() {
252 | $("#email_modal").show();
253 | $("#update_email").click(doUpdateEmail);
254 | $("#cancel_update").click(hideEmailModal);
255 | }
256 |
257 | function hideEmailModal() {
258 | $("#email_modal").hide();
259 | $("#update_email, #cancel_update").unbind("click");
260 | }
261 |
262 | var $profile_email,
263 | $modify_email,
264 | $profile_name,
265 | $profile_twitter,
266 | $profile_phone,
267 | $profile_credit,
268 | $profile_shirt_size,
269 | $profile_shipping_domestic,
270 | $profile_shipping_address,
271 | $profile_shipping_city,
272 | $profile_shipping_state,
273 | $profile_shipping_zip,
274 | $update_profile,
275 |
276 | current_email
277 | ;
278 |
279 | Pages.page_scripts["/profile"] = {
280 | init: init,
281 | teardown: teardown
282 | };
283 |
284 | })(window,Pages);
285 |
--------------------------------------------------------------------------------
/kickstarter-survey-site/web/js/site.js:
--------------------------------------------------------------------------------
1 | (function(global){
2 | "use strict";
3 |
4 | var docready = ASQ(function(done){
5 | $(document).ready(done);
6 | });
7 |
8 | // re-establish user session (if any)
9 | Util.restoreSession()
10 | .then(function(){
11 | docready.val(function(){
12 | Pages.updateNav(/*loggedIn=*/true);
13 | });
14 | })
15 | .or(function(){
16 | docready.val(function(){
17 | Pages.updateNav(/*loggedIn=*/false);
18 | });
19 | });
20 |
21 | Pages.grips = Tmpls.grips = grips;
22 |
23 | Tmpls.init();
24 |
25 | docready
26 | .val(function(){
27 | Pages.siteInit();
28 | });
29 |
30 | })(window);
31 |
--------------------------------------------------------------------------------
/preface.md:
--------------------------------------------------------------------------------
1 | # You Don't Know JS
2 | # Preface
3 |
4 | I'm sure you noticed, but "JS" in the book series title is not an abbreviation for words used to curse about JavaScript, though cursing at the language's quirks is something we can probably all identify with!
5 |
6 | From the earliest days of the web, JavaScript has been a foundational technology that drives interactive experience around the content we consume. While flickering mouse trails and annoying pop-up prompts may be where JavaScript started, nearly 2 decades later, the technology and capability of JavaScript has grown many orders of magnitude, and few doubt its importance at the heart of the world's most widely available software platform: the web.
7 |
8 | But as a language, it has perpetually been a target for a great deal of criticism, owing partly to its heritage but even more to its design philosophy. Even the name evokes, as Brendan Eich once put it, "dumb kid brother" status next to its more mature older brother "Java". But the name is merely an accident of politics and marketing. The two languages are vastly different in many important ways. "JavaScript" is as related to "Java" as "Carnival" is to "Car".
9 |
10 | Because JavaScript borrows concepts and syntax idioms from several languages, including proud C-style procedural roots as well as subtle, less obvious Scheme/Lisp-style functional roots, it is exceedingly approachable to a broad audience of developers, even those with just little to no programming experience. The "Hello World" of JavaScript is so simple that the language is inviting and easy to get comfortable with in early exposure.
11 |
12 | While JavaScript is perhaps one of the easiest languages to get up and running with, its eccentricities make solid mastery of the language a vastly less common occurrence than in many other languages. Where it takes a pretty in-depth knowledge of a language like C or C++ to write a full-scale program, full-scale production JavaScript can, and often does, barely scratch the surface of what the language can do.
13 |
14 | Sophisticated concepts which are deeply rooted into the language tend instead to surface themselves in *seemingly* simplistic ways, such as passing around functions as callbacks, which encourages the JavaScript developer to just use the language as-is and not worry too much about what's going on under the hood.
15 |
16 | It is simultaneously a simple, easy-to-use language that has broad appeal, and a complex and nuanced collection of language mechanics which without careful study will elude *true understanding* even for the most seasoned of JavaScript developers.
17 |
18 | Therein lies the paradox of JavaScript, the Achilles' Heel of the language, the challenge we are presently addressing. Because JavaScript *can* be used without understanding, the understanding of the language is often never attained.
19 |
20 | ## Mission
21 |
22 | If at every point that you encounter a surprise or frustration in JavaScript, your response is to add it to the blacklist, as some are accustomed to doing, you soon will be relegated to a hollow shell of the richness of JavaScript.
23 |
24 | While this subset has been famously dubbed "The Good Parts", I would implore you, dear reader, to instead consider it the "The Easy Parts", "The Safe Parts", or even "The Incomplete Parts".
25 |
26 | This *You Don't Know JavaScript* book series offers a contrary challenge: learn and deeply understand *all* of JavaScript, even and especially "The Tough Parts".
27 |
28 | Here, we address head on the tendency of JS developers to learn "just enough" to get by, without ever forcing themselves to learn exactly how and why the language behaves the way it does. Furthermore, we eschew the common advice to *retreat* when the road gets rough.
29 |
30 | I am not content, nor should you be, at stopping once something *just works*, and not really knowing *why*. I gently challenge you to journey down that bumpy "road less traveled" and embrace all that JavaScript is and can do. With that knowledge, no technique, no framework, no popular buzzword acronym of the week, will be beyond your understanding.
31 |
32 | These books each take on specific core parts of the language which are most commonly misunderstood or under-understood, and dive very deep and exhaustively into them. You should come away from reading with a firm confidence in your understanding, not just of the theoretical, but the practical "what you need to know" bits.
33 |
34 | The JavaScript you know *right now* is probably *parts* handed down to you by others who've been burned by incomplete understanding. *That* JavaScript is but a shadow of the true language. You don't *really* know JavaScript, *yet*, but if you dig into this series, you *will*. Read on, my friends. JavaScript awaits you.
35 |
36 | ## Summary
37 |
38 | JavaScript is awesome. It's easy to learn partially, and much harder to learn completely (or even *sufficiently*). When developers encounter confusion, they usually blame the language instead of their lack of understanding. These books aim to fix that, inspiring a strong appreciation for the language you can now, and *should*, deeply *know*.
39 |
40 | Note: Many of the examples in this book assume modern (and future-reaching) JavaScript engine environments, such as ES6. Some code may not work as described if run in older (pre-ES6) engines.
41 |
--------------------------------------------------------------------------------
/scope & closures/README.md:
--------------------------------------------------------------------------------
1 | # You Don't Know JS: Scope & Closures
2 |
3 |
4 |
5 | -----
6 |
7 | **[Purchase digital/print copy from O'Reilly](http://shop.oreilly.com/product/0636920026327.do)**
8 |
9 | -----
10 |
11 | [Table of Contents](toc.md)
12 |
13 | * [Foreword](https://shanehudson.net/2014/06/03/foreword-dont-know-js/) (by [Shane Hudson](https://github.com/shanehudson))
14 | * [Preface](../preface.md)
15 | * [Chapter 1: What is Scope?](ch1.md)
16 | * [Chapter 2: Lexical Scope](ch2.md)
17 | * [Chapter 3: Function vs. Block Scope](ch3.md)
18 | * [Chapter 4: Hoisting](ch4.md)
19 | * [Chapter 5: Scope Closures](ch5.md)
20 | * [Appendix A: Dynamic Scope](apA.md)
21 | * [Appendix B: Polyfilling Block Scope](apB.md)
22 | * [Appendix C: Lexical-this](apC.md)
23 | * [Appendix D: Thank You's!](apD.md)
24 |
--------------------------------------------------------------------------------
/scope & closures/apA.md:
--------------------------------------------------------------------------------
1 | # You Don't Know JS: Scope & Closures
2 | # Appendix A: Dynamic Scope
3 |
4 | In Chapter 2, we talked about "Dynamic Scope" as a contrast to the "Lexical Scope" model, which is how scope works in JavaScript (and in fact, most other languages).
5 |
6 | We will briefly examine dynamic scope, to hammer home the contrast. But, more importantly, dynamic scope actually is a near cousin to another mechanism (`this`) in JavaScript, which we covered in the "*this & Object Prototypes*" title of this book series.
7 |
8 | As we saw in Chapter 2, lexical scope is the set of rules about how the *Engine* can look-up a variable and where it will find it. The key characteristic of lexical scope is that it is defined at author-time, when the code is written (assuming you don't cheat with `eval()` or `with`).
9 |
10 | Dynamic scope seems to imply, and for good reason, that there's a model whereby scope can be determined dynamically at runtime, rather than statically at author-time. That is in fact the case. Let's illustrate via code:
11 |
12 | ```js
13 | function foo() {
14 | console.log( a ); // 2
15 | }
16 |
17 | function bar() {
18 | var a = 3;
19 | foo();
20 | }
21 |
22 | var a = 2;
23 |
24 | bar();
25 | ```
26 |
27 | Lexical scope holds that the RHS reference to `a` in `foo()` will be resolved to the global variable `a`, which will result in value `2` being output.
28 |
29 | Dynamic scope, by contrast, doesn't concern itself with how and where functions and scopes are declared, but rather **where they are called from**. In other words, the scope chain is based on the call-stack, not the nesting of scopes in code.
30 |
31 | So, if JavaScript had dynamic scope, when `foo()` is executed, **theoretically** the code below would instead result in `3` as the output.
32 |
33 | ```js
34 | function foo() {
35 | console.log( a ); // 3 (not 2!)
36 | }
37 |
38 | function bar() {
39 | var a = 3;
40 | foo();
41 | }
42 |
43 | var a = 2;
44 |
45 | bar();
46 | ```
47 |
48 | How can this be? Because when `foo()` cannot resolve the variable reference for `a`, instead of stepping up the nested (lexical) scope chain, it walks up the call-stack, to find where `foo()` was *called from*. Since `foo()` was called from `bar()`, it checks the variables in scope for `bar()`, and finds an `a` there with value `3`.
49 |
50 | Strange? You're probably thinking so, at the moment.
51 |
52 | But that's just because you've probably only ever worked on (or at least deeply considered) code which is lexically scoped. So dynamic scoping seems foreign. If you had only ever written code in a dynamically scoped language, it would seem natural, and lexical scope would be the odd-ball.
53 |
54 | To be clear, JavaScript **does not, in fact, have dynamic scope**. It has lexical scope. Plain and simple. But the `this` mechanism is kind of like dynamic scope.
55 |
56 | The key contrast: **lexical scope is write-time, whereas dynamic scope (and `this`!) are runtime**. Lexical scope cares *where a function was declared*, but dynamic scope cares where a function was *called from*.
57 |
58 | Finally: `this` cares *how a function was called*, which shows how closely related the `this` mechanism is to the idea of dynamic scoping. To dig more into `this`, read the title "*this & Object Prototypes*".
59 |
--------------------------------------------------------------------------------
/scope & closures/apB.md:
--------------------------------------------------------------------------------
1 | # You Don't Know JS: Scope & Closures
2 | # Appendix B: Polyfilling Block Scope
3 |
4 | In Chapter 3, we explored Block Scope. We saw that `with` and the `catch` clause are both tiny examples of block scope that have existed in JavaScript since at least the introduction of ES3.
5 |
6 | But it's ES6's introduction of `let` that finally gives full, unfettered block-scoping capability to our code. There are many exciting things, both functionally and code-stylistically, that block scope will enable.
7 |
8 | But what if we wanted to use block scope in pre-ES6 environments?
9 |
10 | Consider this code:
11 |
12 | ```js
13 | {
14 | let a = 2;
15 | console.log( a ); // 2
16 | }
17 |
18 | console.log( a ); // ReferenceError
19 | ```
20 |
21 | This will work great in ES6 environments. But can we do so pre-ES6? `catch` is the answer.
22 |
23 | ```js
24 | try{throw 2}catch(a){
25 | console.log( a ); // 2
26 | }
27 |
28 | console.log( a ); // ReferenceError
29 | ```
30 |
31 | Whoa! That's some ugly, weird looking code. We see a `try/catch` that appears to forcibly throw an error, but the "error" it throws is just a value `2`, and then the variable declaration that receives it is in the `catch(a)` clause. Mind: blown.
32 |
33 | That's right, the `catch` clause has block-scoping to it, which means it can be used as a polyfill for block scope in pre-ES6 environments.
34 |
35 | "But...", you say. "...no one wants to write ugly code like that!" That's true. No one writes (some of) the code output by the CoffeeScript compiler, either. That's not the point.
36 |
37 | The point is that tools can transpile ES6 code to work in pre-ES6 environments. You can write code using block-scoping, and benefit from such functionality, and let a build-step tool take care of producing code that will actually *work* when deployed.
38 |
39 | This is actually the preferred migration path for all (ahem, most) of ES6: to use a code transpiler to take ES6 code and produce ES5-compatible code during the transition from pre-ES6 to ES6.
40 |
41 | ## Traceur
42 |
43 | Google maintains a project called "Traceur" [^note-traceur], which is exactly tasked with transpiling ES6 features into pre-ES6 (mostly ES5, but not all!) for general usage. The TC39 committee relies on this tool (and others) to test out the semantics of the features they specify.
44 |
45 | What does Traceur produce from our snippet? You guessed it!
46 |
47 | ```js
48 | {
49 | try {
50 | throw undefined;
51 | } catch (a) {
52 | a = 2;
53 | console.log( a );
54 | }
55 | }
56 |
57 | console.log( a );
58 | ```
59 |
60 | So, with the use of such tools, we can start taking advantage of block scope regardless of if we are targeting ES6 or not, because `try/catch` has been around (and worked this way) from ES3 days.
61 |
62 | ## Implicit vs. Explicit Blocks
63 |
64 | In Chapter 3, we identified some potential pitfalls to code maintainability/refactorability when we introduce block-scoping. Is there another way to take advantage of block scope but to reduce this downside?
65 |
66 | Consider this alternate form of `let`, called the "let block" or "let statement" (contrasted with "let declarations" from before).
67 |
68 | ```js
69 | let (a = 2) {
70 | console.log( a ); // 2
71 | }
72 |
73 | console.log( a ); // ReferenceError
74 | ```
75 |
76 | Instead of implicitly hijacking an existing block, the let-statement creates an explicit block for its scope binding. Not only does the explicit block stand out more, and perhaps fare more robustly in code refactoring, it produces somewhat cleaner code by, grammatically, forcing all the declarations to the top of the block. This makes it easier to look at any block and know what's scoped to it and not.
77 |
78 | As a pattern, it mirrors the approach many people take in function-scoping when they manually move/hoist all their `var` declarations to the top of the function. The let-statement puts them there at the top of the block by intent, and if you don't use `let` declarations strewn throughout, your block-scoping declarations are somewhat easier to identify and maintain.
79 |
80 | But, there's a problem. The let-statement form is not included in ES6. Neither does the official Traceur compiler accept that form of code.
81 |
82 | We have two options. We can format using ES6-valid syntax and a little sprinkle of code discipline:
83 |
84 | ```js
85 | /*let*/ { let a = 2;
86 | console.log( a );
87 | }
88 |
89 | console.log( a ); // ReferenceError
90 | ```
91 |
92 | But, tools are meant to solve our problems. So the other option is to write explicit let statement blocks, and let a tool convert them to valid, working code.
93 |
94 | So, I built a tool called "let-er" [^note-let_er] to address just this issue. *let-er* is a build-step code transpiler, but its only task is to find let-statement forms and transpile them. It will leave alone any of the rest of your code, including any let-declarations. You can safely use *let-er* as the first ES6 transpiler step, and then pass your code through something like Traceur if necessary.
95 |
96 | Moreover, *let-er* has a configuration flag `--es6`, which when turned on (off by default), changes the kind of code produced. Instead of the `try/catch` ES3 polyfill hack, *let-er* would take our snippet and produce the fully ES6-compliant, non-hacky:
97 |
98 | ```js
99 | {
100 | let a = 2;
101 | console.log( a );
102 | }
103 |
104 | console.log( a ); // ReferenceError
105 | ```
106 |
107 | So, you can start using *let-er* right away, and target all pre-ES6 environments, and when you only care about ES6, you can add the flag and instantly target only ES6.
108 |
109 | And most importantly, **you can use the more preferable and more explicit let-statement form** even though it is not an official part of any ES version (yet).
110 |
111 | ## Performance
112 |
113 | Let me add one last quick note on the performance of `try/catch`, and/or to address the question, "why not just use an IIFE to create the scope?"
114 |
115 | Firstly, the performance of `try/catch` *is* slower, but there's no reasonable assumption that it *has* to be that way, or even that it *always will be* that way. Since the official TC39-approved ES6 transpiler uses `try/catch`, the Traceur team has asked Chrome to improve the performance of `try/catch`, and they are obviously motivated to do so.
116 |
117 | Secondly, IIFE is not a fair apples-to-apples comparison with `try/catch`, because a function wrapped around any arbitrary code changes the meaning, inside of that code, of `this`, `return`, `break`, and `continue`. IIFE is not a suitable general substitute. It could only be used manually in certain cases.
118 |
119 | The question really becomes: do you want block-scoping, or not. If you do, these tools provide you that option. If not, keep using `var` and go on about your coding!
120 |
121 | [^note-traceur]: [Google Traceur](http://traceur-compiler.googlecode.com/git/demo/repl.html)
122 |
123 | [^note-let_er]: [let-er](https://github.com/getify/let-er)
124 |
--------------------------------------------------------------------------------
/scope & closures/apC.md:
--------------------------------------------------------------------------------
1 | # You Don't Know JS: Scope & Closures
2 | # Appendix C: Lexical-this
3 |
4 | Though this title does not address the `this` mechanism in any detail, there's one ES6 topic which relates `this` to lexical scope in an important way, which we will quickly examine.
5 |
6 | ES6 adds a special syntactic form of function declaration called the "arrow function". It looks like this:
7 |
8 | ```js
9 | var foo = a => {
10 | console.log( a );
11 | };
12 |
13 | foo( 2 ); // 2
14 | ```
15 |
16 | The so-called "fat arrow" is often mentioned as a short-hand for the *tediously verbose* (sarcasm) `function` keyword.
17 |
18 | But there's something much more important going on with arrow-functions that has nothing to do with saving keystrokes in your declaration.
19 |
20 | Briefly, this code suffers a problem:
21 |
22 | ```js
23 |
24 | var obj = {
25 | id: "awesome",
26 | cool: function coolFn() {
27 | console.log( this.id );
28 | }
29 | };
30 |
31 | var id = "not awesome";
32 |
33 | obj.cool(); // awesome
34 |
35 | setTimeout( obj.cool, 100 ); // not awesome
36 | ```
37 |
38 | The problem is the loss of `this` binding on the `cool()` function. There are various ways to address that problem, but one often-repeated solution is `var self = this;`.
39 |
40 | That might look like:
41 |
42 | ```js
43 | var obj = {
44 | count: 0,
45 | cool: function coolFn() {
46 | var self = this;
47 |
48 | if (self.count < 1) {
49 | setTimeout( function timer(){
50 | self.count++;
51 | console.log( "awesome?" );
52 | }, 100 );
53 | }
54 | }
55 | };
56 |
57 | obj.cool(); // awesome?
58 | ```
59 |
60 | Without getting too much into the weeds here, the `var self = this` "solution" just dispenses with the whole problem of understanding and properly using `this` binding, and instead falls back to something we're perhaps more comfortable with: lexical scope. `self` becomes just an identifier that can be resolved via lexical scope and closure, and cares not what happened to the `this` binding along the way.
61 |
62 | People don't like writing verbose stuff, especially when they do it over and over again. So, a motivation of ES6 is to help alleviate these scenarios, and indeed, *fix* common idiom problems, such as this one.
63 |
64 | The ES6 solution, the arrow-function, introduces a behavior called "lexical this".
65 |
66 | ```js
67 | var obj = {
68 | count: 0,
69 | cool: function coolFn() {
70 | if (this.count < 1) {
71 | setTimeout( () => { // arrow-function ftw?
72 | this.count++;
73 | console.log( "awesome?" );
74 | }, 100 );
75 | }
76 | }
77 | };
78 |
79 | obj.cool(); // awesome?
80 | ```
81 |
82 | The short explanation is that arrow-functions do not behave at all like normal functions when it comes to their `this` binding. They discard all the normal rules for `this` binding, and instead take on the `this` value of their immediate lexical enclosing scope, whatever it is.
83 |
84 | So, in that snippet, the arrow-function doesn't get its `this` unbound in some unpredictable way, it just "inherits" the `this` binding of the `cool()` function (which is correct if we invoke it as shown!).
85 |
86 | While this makes for shorter code, my perspective is that arrow-functions are really just codifying into the language syntax a common *mistake* of developers, which is to confuse and conflate "this binding" rules with "lexical scope" rules.
87 |
88 | Put another way: why go to the trouble and verbosity of using the `this` style coding paradigm, only to cut it off at the knees by mixing it with lexical references. It seems natural to embrace one approach or the other for any given piece of code, and not mix them in the same piece of code.
89 |
90 | **Note:** one other detraction from arrow-functions is that they are anonymous, not named. See Chapter 3 for the reasons why anonymous functions are less desirable than named functions.
91 |
92 | A more appropriate approach, in my perspective, to this "problem", is to use and embrace the `this` mechanism correctly.
93 |
94 | ```js
95 | var obj = {
96 | count: 0,
97 | cool: function coolFn() {
98 | if (this.count < 1) {
99 | setTimeout( function timer(){
100 | this.count++; // `this` is safe because of `bind(..)`
101 | console.log( "more awesome" );
102 | }.bind( this ), 100 ); // look, `bind()`!
103 | }
104 | }
105 | };
106 |
107 | obj.cool(); // more awesome
108 | ```
109 |
110 | Whether you prefer the new lexical-this behavior of arrow-functions, or you prefer the tried-and-true `bind()`, it's important to note that arrow-functions are **not** just about less typing of "function".
111 |
112 | They have an *intentional behavioral difference* that we should learn and understand, and if we so choose, leverage.
113 |
114 | Now that we fully understand lexical scoping (and closure!), understanding lexical-this should be a breeze!
115 |
--------------------------------------------------------------------------------
/scope & closures/apD.md:
--------------------------------------------------------------------------------
1 | # You Don't Know JS: Scope & Closures
2 | # Appendix D: Acknowledgments
3 |
4 | I have many people to thank for making this book title and the overall series happen.
5 |
6 | First, I must thank my wife Christen Simpson, and my two kids Ethan and Emily, for putting up with Dad always pecking away at the computer. Even when not writing books, my obsession with JavaScript glues my eyes to the screen far more than it should. That time I borrow from my family is the reason these books can so deeply and completely explain JavaScript to you, the reader. I owe my family everything.
7 |
8 | I'd like to thank my editors at O'Reilly, namely Simon St.Laurent and Brian MacDonald, as well as the rest of the editorial and marketing staff. They are fantastic to work with, and have been especially accommodating during this experiment into "open source" book writing, editing, and production.
9 |
10 | Thank you to the many folks who have participated in making this book series better by providing editorial suggestions and corrections, including Shelley Powers, Tim Ferro, Evan Borden, Forrest L. Norvell, Jennifer Davis, Jesse Harlin, and many others. A big thank you to Shane Hudson for writing the Foreword for this title.
11 |
12 | Thank you to the countless folks in the community, including members of the TC39 committee, who have shared so much knowledge with the rest of us, and especially tolerated my incessant questions and explorations with patience and detail. John-David Dalton, Juriy "kangax" Zaytsev, Mathias Bynens, Axel Rauschmayer, Nicholas Zakas, Angus Croll, Reginald Braithwaite, Dave Herman, Brendan Eich, Allen Wirfs-Brock, Bradley Meck, Domenic Denicola, David Walsh, Tim Disney, Peter van der Zee, Andrea Giammarchi, Kit Cambridge, Eric Elliott, and so many others, I can't even scratch the surface.
13 |
14 | The *You Don't Know JS* book series was born on Kickstarter, so I also wish to thank all my (nearly) 500 generous backers, without whom this book series could not have happened:
15 |
16 | > Jan Szpila, nokiko, Murali Krishnamoorthy, Ryan Joy, Craig Patchett, pdqtrader, Dale Fukami, ray hatfield, R0drigo Perez [Mx], Dan Petitt, Jack Franklin, Andrew Berry, Brian Grinstead, Rob Sutherland, Sergi Meseguer, Phillip Gourley, Mark Watson, Jeff Carouth, Alfredo Sumaran, Martin Sachse, Marcio Barrios, Dan, AimelyneM, Matt Sullivan, Delnatte Pierre-Antoine, Jake Smith, Eugen Tudorancea, Iris, David Trinh, simonstl, Ray Daly, Uros Gruber, Justin Myers, Shai Zonis, Mom & Dad, Devin Clark, Dennis Palmer, Brian Panahi Johnson, Josh Marshall, Marshall, Dennis Kerr, Matt Steele, Erik Slagter, Sacah, Justin Rainbow, Christian Nilsson, Delapouite, D.Pereira, Nicolas Hoizey, George V. Reilly, Dan Reeves, Bruno Laturner, Chad Jennings, Shane King, Jeremiah Lee Cohick, od3n, Stan Yamane, Marko Vucinic, Jim B, Stephen Collins, Ægir Þorsteinsson, Eric Pederson, Owain, Nathan Smith, Jeanetteurphy, Alexandre ELISÉ, Chris Peterson, Rik Watson, Luke Matthews, Justin Lowery, Morten Nielsen, Vernon Kesner, Chetan Shenoy, Paul Tregoing, Marc Grabanski, Dion Almaer, Andrew Sullivan, Keith Elsass, Tom Burke, Brian Ashenfelter, David Stuart, Karl Swedberg, Graeme, Brandon Hays, John Christopher, Gior, manoj reddy, Chad Smith, Jared Harbour, Minoru TODA, Chris Wigley, Daniel Mee, Mike, Handyface, Alex Jahraus, Carl Furrow, Rob Foulkrod, Max Shishkin, Leigh Penny Jr., Robert Ferguson, Mike van Hoenselaar, Hasse Schougaard, rajan venkataguru, Jeff Adams, Trae Robbins, Rolf Langenhuijzen, Jorge Antunes, Alex Koloskov, Hugh Greenish, Tim Jones, Jose Ochoa, Michael Brennan-White, Naga Harish Muvva, Barkóczi Dávid, Kitt Hodsden, Paul McGraw, Sascha Goldhofer, Andrew Metcalf, Markus Krogh, Michael Mathews, Matt Jared, Juanfran, Georgie Kirschner, Kenny Lee, Ted Zhang, Amit Pahwa, Inbal Sinai, Dan Raine, Schabse Laks, Michael Tervoort, Alexandre Abreu, Alan Joseph Williams, NicolasD, Cindy Wong, Reg Braithwaite, LocalPCGuy, Jon Friskics, Chris Merriman, John Pena, Jacob Katz, Sue Lockwood, Magnus Johansson, Jeremy Crapsey, Grzegorz Pawłowski, nico nuzzaci, Christine Wilks, Hans Bergren, charles montgomery, Ariel בר-לבב Fogel, Ivan Kolev, Daniel Campos, Hugh Wood, Christian Bradford, Frédéric Harper, Ionuţ Dan Popa, Jeff Trimble, Rupert Wood, Trey Carrico, Pancho Lopez, Joël kuijten, Tom A Marra, Jeff Jewiss, Jacob Rios, Paolo Di Stefano, Soledad Penades, Chris Gerber, Andrey Dolganov, Wil Moore III, Thomas Martineau, Kareem, Ben Thouret, Udi Nir, Morgan Laupies, jory carson-burson, Nathan L Smith, Eric Damon Walters, Derry Lozano-Hoyland, Geoffrey Wiseman, mkeehner, KatieK, Scott MacFarlane, Brian LaShomb, Adrien Mas, christopher ross, Ian Littman, Dan Atkinson, Elliot Jobe, Nick Dozier, Peter Wooley, John Hoover, dan, Martin A. Jackson, Héctor Fernando Hurtado, andy ennamorato, Paul Seltmann, Melissa Gore, Dave Pollard, Jack Smith, Philip Da Silva, Guy Israeli, @megalithic, Damian Crawford, Felix Gliesche, April Carter Grant, Heidi, jim tierney, Andrea Giammarchi, Nico Vignola, Don Jones, Chris Hartjes, Alex Howes, john gibbon, David J. Groom, BBox, Yu 'Dilys' Sun, Nate Steiner, Brandon Satrom, Brian Wyant, Wesley Hales, Ian Pouncey, Timothy Kevin Oxley, George Terezakis, sanjay raj, Jordan Harband, Marko McLion, Wolfgang Kaufmann, Pascal Peuckert, Dave Nugent, Markus Liebelt, Welling Guzman, Nick Cooley, Daniel Mesquita, Robert Syvarth, Chris Coyier, Rémy Bach, Adam Dougal, Alistair Duggin, David Loidolt, Ed Richer, Brian Chenault, GoldFire Studios, Carles Andrés, Carlos Cabo, Yuya Saito, roberto ricardo, Barnett Klane, Mike Moore, Kevin Marx, Justin Love, Joe Taylor, Paul Dijou, Michael Kohler, Rob Cassie, Mike Tierney, Cody Leroy Lindley, tofuji, Shimon Schwartz, Raymond, Luc De Brouwer, David Hayes, Rhys Brett-Bowen, Dmitry, Aziz Khoury, Dean, Scott Tolinski - Level Up, Clement Boirie, Djordje Lukic, Anton Kotenko, Rafael Corral, Philip Hurwitz, Jonathan Pidgeon, Jason Campbell, Joseph C., SwiftOne, Jan Hohner, Derick Bailey, getify, Daniel Cousineau, Chris Charlton, Eric Turner, David Turner, Joël Galeran, Dharma Vagabond, adam, Dirk van Bergen, dave ♥♫★ furf, Vedran Zakanj, Ryan McAllen, Natalie Patrice Tucker, Eric J. Bivona, Adam Spooner, Aaron Cavano, Kelly Packer, Eric J, Martin Drenovac, Emilis, Michael Pelikan, Scott F. Walter, Josh Freeman, Brandon Hudgeons, vijay chennupati, Bill Glennon, Robin R., Troy Forster, otaku_coder, Brad, Scott, Frederick Ostrander, Adam Brill, Seb Flippence, Michael Anderson, Jacob, Adam Randlett, Standard, Joshua Clanton, Sebastian Kouba, Chris Deck, SwordFire, Hannes Papenberg, Richard Woeber, hnzz, Rob Crowther, Jedidiah Broadbent, Sergey Chernyshev, Jay-Ar Jamon, Ben Combee, luciano bonachela, Mark Tomlinson, Kit Cambridge, Michael Melgares, Jacob Adams, Adrian Bruinhout, Bev Wieber, Scott Puleo, Thomas Herzog, April Leone, Daniel Mizieliński, Kees van Ginkel, Jon Abrams, Erwin Heiser, Avi Laviad, David newell, Jean-Francois Turcot, Niko Roberts, Erik Dana, Charles Neill, Aaron Holmes, Grzegorz Ziółkowski, Nathan Youngman, Timothy, Jacob Mather, Michael Allan, Mohit Seth, Ryan Ewing, Benjamin Van Treese, Marcelo Santos, Denis Wolf, Phil Keys, Chris Yung, Timo Tijhof, Martin Lekvall, Agendine, Greg Whitworth, Helen Humphrey, Dougal Campbell, Johannes Harth, Bruno Girin, Brian Hough, Darren Newton, Craig McPheat, Olivier Tille, Dennis Roethig, Mathias Bynens, Brendan Stromberger, sundeep, John Meyer, Ron Male, John F Croston III, gigante, Carl Bergenhem, B.J. May, Rebekah Tyler, Ted Foxberry, Jordan Reese, Terry Suitor, afeliz, Tom Kiefer, Darragh Duffy, Kevin Vanderbeken, Andy Pearson, Simon Mac Donald, Abid Din, Chris Joel, Tomas Theunissen, David Dick, Paul Grock, Brandon Wood, John Weis, dgrebb, Nick Jenkins, Chuck Lane, Johnny Megahan, marzsman, Tatu Tamminen, Geoffrey Knauth, Alexander Tarmolov, Jeremy Tymes, Chad Auld, Sean Parmelee, Rob Staenke, Dan Bender, Yannick derwa, Joshua Jones, Geert Plaisier, Tom LeZotte, Christen Simpson, Stefan Bruvik, Justin Falcone, Carlos Santana, Michael Weiss, Pablo Villoslada, Peter deHaan, Dimitris Iliopoulos, seyDoggy, Adam Jordens, Noah Kantrowitz, Amol M, Matthew Winnard, Dirk Ginader, Phinam Bui, David Rapson, Andrew Baxter, Florian Bougel, Michael George, Alban Escalier, Daniel Sellers, Sasha Rudan, John Green, Robert Kowalski, David I. Teixeira (@ditma, Charles Carpenter, Justin Yost, Sam S, Denis Ciccale, Kevin Sheurs, Yannick Croissant, Pau Fracés, Stephen McGowan, Shawn Searcy, Chris Ruppel, Kevin Lamping, Jessica Campbell, Christopher Schmitt, Sablons, Jonathan Reisdorf, Bunni Gek, Teddy Huff, Michael Mullany, Michael Fürstenberg, Carl Henderson, Rick Yoesting, Scott Nichols, Hernán Ciudad, Andrew Maier, Mike Stapp, Jesse Shawl, Sérgio Lopes, jsulak, Shawn Price, Joel Clermont, Chris Ridmann, Sean Timm, Jason Finch, Aiden Montgomery, Elijah Manor, Derek Gathright, Jesse Harlin, Dillon Curry, Courtney Myers, Diego Cadenas, Arne de Bree, João Paulo Dubas, James Taylor, Philipp Kraeutli, Mihai Păun, Sam Gharegozlou, joshjs, Matt Murchison, Eric Windham, Timo Behrmann, Andrew Hall, joshua price, Théophile Villard
17 |
18 | This book series is being produced in an open source fashion, including editing and production. We owe GitHub a debt of gratitude for making that sort of thing possible for the community!
19 |
20 | Thank you again to all the countless folks I didn't name but who I nonetheless owe thanks. May this book series be "owned" by all of us and serve to contribute to increasing awareness and understanding of the JavaScript language, to the benefit of all current and future community contributors.
21 |
--------------------------------------------------------------------------------
/scope & closures/ch4.md:
--------------------------------------------------------------------------------
1 | # You Don't Know JS: Scope & Closures
2 | # Chapter 4: Hoisting
3 |
4 | By now, you should be fairly comfortable with the idea of scope, and how variables are attached to different levels of scope depending on where and how they are declared. Both function scope and block scope behave by the same rules in this regard: any variable declared within a scope is attached to that scope.
5 |
6 | But there's a subtle detail of how scope attachment works with declarations that appear in various locations within a scope, and that detail is what we will examine here.
7 |
8 | ## Chicken Or The Egg?
9 |
10 | There's a temptation to think that all of the code you see in a JavaScript program is interpreted line-by-line, top-down in order, as the program executes. While that is substantially true, there's one part of that assumption which can lead to incorrect thinking about your program.
11 |
12 | Consider this code:
13 |
14 | ```js
15 | a = 2;
16 |
17 | var a;
18 |
19 | console.log( a );
20 | ```
21 |
22 | What do you expect to be printed in the `console.log(..)` statement?
23 |
24 | Many developers would expect `undefined`, since the `var a` statement comes after the `a = 2`, and it would seem natural to assume that the variable is re-defined, and thus assigned the default `undefined`. However, the output will be `2`.
25 |
26 | Consider another piece of code:
27 |
28 | ```js
29 | console.log( a );
30 |
31 | var a = 2;
32 | ```
33 |
34 | You might be tempted to assume that, since the previous snippet exhibited some less-than-top-down looking behavior, perhaps in this snippet, `2` will also be printed. Others may think that since the `a` variable is used before it is declared, this must result in a `ReferenceError` being thrown.
35 |
36 | Unfortunately, both guesses are incorrect. `undefined` is the output.
37 |
38 | **So, what's going on here?** It would appear we have a chicken-and-the-egg question. Which comes first, the declaration ("egg"), or the assignment ("chicken")?
39 |
40 | ## The Compiler Strikes Again
41 |
42 | To answer this question, we need to refer back to Chapter 1, and our discussion of compilers. Recall that the *Engine* actually will compile your JavaScript code before it interprets it. Part of the compilation phase was to find and associate all declarations with their appropriate scopes. Chapter 2 showed us that this is the heart of Lexical Scope.
43 |
44 | So, the best way to think about things is that all declarations, both variables and functions, are processed first, before any part of your code is executed.
45 |
46 | When you see `var a = 2;`, you probably think of that as one statement. But JavaScript actually thinks of it as two statements: `var a;` and `a = 2;`. The first statement, the declaration, is processed during the compilation phase. The second statement, the assignment, is left **in place** for the execution phase.
47 |
48 | Our first snippet then should be thought of as being handled like this:
49 |
50 | ```js
51 | var a;
52 | ```
53 | ```js
54 | a = 2;
55 |
56 | console.log( a );
57 | ```
58 |
59 | ...where the first part is the compilation and the second part is the execution.
60 |
61 | Similarly, our second snippet is actually processed as:
62 |
63 | ```js
64 | var a;
65 | ```
66 | ```js
67 | console.log( a );
68 |
69 | a = 2;
70 | ```
71 |
72 | So, one way of thinking, sort of metaphorically, about this process, is that variable and function declarations are "moved" from where they appear in the flow of the code to the top of the code. This gives rise to the name "Hoisting".
73 |
74 | In other words, **the egg (declaration) comes before the chicken (assignment)**.
75 |
76 | **Note:** Only the declarations themselves are hoisted, while any assignments or other executable logic are left *in place*. If hoisting were to re-arrange the executable logic of our code, that could wreak havoc.
77 |
78 | ```js
79 | foo();
80 |
81 | function foo() {
82 | console.log( a ); // undefined
83 |
84 | var a = 2;
85 | }
86 | ```
87 |
88 | The function `foo`'s declaration (which in this case *includes* the implied value of it as an actual function) is hoisted, such that the call on the first line is able to execute.
89 |
90 | It's also important to note that hoisting is **per-scope**. So while our previous snippets were simplified in that they only included global scope, the `foo(..)` function we are now examining itself exhibits that `var a` is hoisted to the top of `foo(..)` (not, obviously, to the top of the program). So the program can perhaps be more accurately interpreted like this:
91 |
92 | ```js
93 | function foo() {
94 | var a;
95 |
96 | console.log( a ); // undefined
97 |
98 | a = 2;
99 | }
100 |
101 | foo();
102 | ```
103 |
104 | Function declarations are hoisted, as we just saw. But function expressions are not.
105 |
106 | ```js
107 | foo(); // not ReferenceError, but TypeError!
108 |
109 | var foo = function bar() {
110 | // ...
111 | };
112 | ```
113 |
114 | The variable identifier `foo` is hoisted and attached to the enclosing scope (global) of this program, so `foo()` doesn't fail as a `ReferenceError`. But `foo` has no value yet (as it would if it had been a true function declaration instead of expression). So, `foo()` is attempting to invoke the `undefined` value, which is a `TypeError` illegal operation.
115 |
116 | Also recall that even though it's a named function expression, the name identifier is not available in the enclosing scope:
117 |
118 | ```js
119 | foo(); // TypeError
120 | bar(); // ReferenceError
121 |
122 | var foo = function bar() {
123 | // ...
124 | };
125 | ```
126 |
127 | This snippet is more accurately interpreted (with hoisting) as:
128 |
129 | ```js
130 | var foo;
131 |
132 | foo(); // TypeError
133 | bar(); // ReferenceError
134 |
135 | foo = function() {
136 | var bar = ...self...
137 | // ...
138 | }
139 | ```
140 |
141 | ## Functions First
142 |
143 | Both function declarations and variable declarations are hoisted. But a subtle detail (that *can* show up in code with multiple "duplicate" declarations) is that functions are hoisted first, and then variables.
144 |
145 | Consider:
146 |
147 | ```js
148 | foo(); // 1
149 |
150 | var foo;
151 |
152 | function foo() {
153 | console.log( 1 );
154 | }
155 |
156 | foo = function() {
157 | console.log( 2 );
158 | };
159 | ```
160 |
161 | `1` is printed instead of `2`! This snippet is interpreted by the *Engine* as:
162 |
163 | ```js
164 | function foo() {
165 | console.log( 1 );
166 | }
167 |
168 | foo(); // 1
169 |
170 | foo = function() {
171 | console.log( 2 );
172 | };
173 | ```
174 |
175 | Notice that `var foo` was the duplicate (and thus ignored) declaration, even though it came before the `function foo()...` declaration, because function declarations are hoisted before normal variables.
176 |
177 | While multiple/duplicate `var` declarations are effectively ignored, subsequent function declarations *do* override previous ones.
178 |
179 | ```js
180 | foo(); // 3
181 |
182 | function foo() {
183 | console.log( 1 );
184 | }
185 |
186 | var foo = function() {
187 | console.log( 2 );
188 | };
189 |
190 | function foo() {
191 | console.log( 3 );
192 | }
193 | ```
194 |
195 | While this all may sound like nothing more than interesting academic trivia, it highlights the fact that duplicate definitions in the same scope are a really bad idea and will often lead to confusing results.
196 |
197 | Function declarations that appear inside of normal blocks typically hoist to the enclosing scope, rather than being conditional as this code implies:
198 |
199 | ```js
200 | foo(); // "b"
201 |
202 | var a = true;
203 | if (a) {
204 | function foo() { console.log( "a" ); }
205 | }
206 | else {
207 | function foo() { console.log( "b" ); }
208 | }
209 | ```
210 |
211 | However, it's important to note that this behavior is not reliable and is subject to change in future versions of JavaScript, so it's probably best to avoid declaring functions in blocks.
212 |
213 | ## Review (TL;DR)
214 |
215 | We can be tempted to look at `var a = 2;` as one statement, but the JavaScript *Engine* does not see it that way. It sees `var a` and `a = 2` as two separate statements, the first one a compiler-phase task, and the second one an execution-phase task.
216 |
217 | What this leads to is that all declarations in a scope, regardless of where they appear, are processed *first* before the code itself is executed. You can visualize this as declarations (variables and functions) being "moved" to the top of their respective scopes, which we call "hoisting".
218 |
219 | Declarations themselves are hoisted, but assignments, even assignments of function expressions, are *not* hoisted.
220 |
221 | Be careful about duplicate declarations, especially mixed between normal var declarations and function declarations -- peril awaits if you do!
222 |
--------------------------------------------------------------------------------
/scope & closures/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarStudio/You-Dont-Know-JS/f4b83f540033904867311c597d16232bd08a984e/scope & closures/cover.jpg
--------------------------------------------------------------------------------
/scope & closures/fig1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarStudio/You-Dont-Know-JS/f4b83f540033904867311c597d16232bd08a984e/scope & closures/fig1.png
--------------------------------------------------------------------------------
/scope & closures/fig2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarStudio/You-Dont-Know-JS/f4b83f540033904867311c597d16232bd08a984e/scope & closures/fig2.png
--------------------------------------------------------------------------------
/scope & closures/toc.md:
--------------------------------------------------------------------------------
1 | # You Don't Know JS: Scope & Closures
2 |
3 | ## Table of Contents
4 |
5 | * Foreword
6 | * Preface
7 | * Chapter 1: What is Scope?
8 | * Compiler Theory
9 | * Understanding Scope
10 | * Nested Scope
11 | * Errors
12 | * Chapter 2: Lexical Scope
13 | * Lex-time
14 | * Cheating Lexical
15 | * Chapter 3: Function vs. Block Scope
16 | * Scope From Functions
17 | * Hiding In Plain Scope
18 | * Functions As Scopes
19 | * Blocks As Scopes
20 | * Chapter 4: Hoisting
21 | * Chicken Or The Egg?
22 | * The Compiler Strikes Again
23 | * Functions First
24 | * Chapter 5: Scope Closures
25 | * Enlightenment
26 | * Nitty Gritty
27 | * Now I Can See
28 | * Loops + Closure
29 | * Modules
30 | * Appendix A: Dynamic Scope
31 | * Appendix B: Polyfilling Block Scope
32 | * Appendix C: Lexical-this
33 | * Appendix D: Acknowledgments
34 |
--------------------------------------------------------------------------------
/this & object prototypes/README.md:
--------------------------------------------------------------------------------
1 | # You Don't Know JS: *this* & Object Prototypes
2 |
3 |
4 |
5 | -----
6 |
7 | **[Purchase digital/print copy from O'Reilly](http://shop.oreilly.com/product/0636920033738.do)**
8 |
9 | -----
10 |
11 | [Table of Contents](toc.md)
12 |
13 | * [Foreword](foreword.md) (by [Nick Berardi](https://github.com/nberardi))
14 | * [Preface](../preface.md)
15 | * [Chapter 1: *this* Or That?](ch1.md)
16 | * [Chapter 2: *this* All Makes Sense Now!](ch2.md)
17 | * [Chapter 3: Objects](ch3.md)
18 | * [Chapter 4: Mixing (Up) "Class" Objects](ch4.md)
19 | * [Chapter 5: Prototypes](ch5.md)
20 | * [Chapter 6: Behavior Delegation](ch6.md)
21 | * [Appendix A: ES6 *class*](apA.md)
22 | * [Appendix B: Thank You's!](apB.md)
23 |
--------------------------------------------------------------------------------
/this & object prototypes/apB.md:
--------------------------------------------------------------------------------
1 | # You Don't Know JS: *this* & Object Prototypes
2 | # Appendix B: Acknowledgments
3 |
4 | I have many people to thank for making this book title and the overall series happen.
5 |
6 | First, I must thank my wife Christen Simpson, and my two kids Ethan and Emily, for putting up with Dad always pecking away at the computer. Even when not writing books, my obsession with JavaScript glues my eyes to the screen far more than it should. That time I borrow from my family is the reason these books can so deeply and completely explain JavaScript to you, the reader. I owe my family everything.
7 |
8 | I'd like to thank my editors at O'Reilly, namely Simon St.Laurent and Brian MacDonald, as well as the rest of the editorial and marketing staff. They are fantastic to work with, and have been especially accommodating during this experiment into "open source" book writing, editing, and production.
9 |
10 | Thank you to the many folks who have participated in making this book series better by providing editorial suggestions and corrections, including Shelley Powers, Tim Ferro, Evan Borden, Forrest L. Norvell, Jennifer Davis, Jesse Harlin, and many others. A big thank you to Nick Berardi for writing the Foreword for this title.
11 |
12 | Thank you to the countless folks in the community, including members of the TC39 committee, who have shared so much knowledge with the rest of us, and especially tolerated my incessant questions and explorations with patience and detail. John-David Dalton, Juriy "kangax" Zaytsev, Mathias Bynens, Axel Rauschmayer, Nicholas Zakas, Angus Croll, Reginald Braithwaite, Dave Herman, Brendan Eich, Allen Wirfs-Brock, Bradley Meck, Domenic Denicola, David Walsh, Tim Disney, Peter van der Zee, Andrea Giammarchi, Kit Cambridge, Eric Elliott, and so many others, I can't even scratch the surface.
13 |
14 | The *You Don't Know JS* book series was born on Kickstarter, so I also wish to thank all my (nearly) 500 generous backers, without whom this book series could not have happened:
15 |
16 | > Jan Szpila, nokiko, Murali Krishnamoorthy, Ryan Joy, Craig Patchett, pdqtrader, Dale Fukami, ray hatfield, R0drigo Perez [Mx], Dan Petitt, Jack Franklin, Andrew Berry, Brian Grinstead, Rob Sutherland, Sergi Meseguer, Phillip Gourley, Mark Watson, Jeff Carouth, Alfredo Sumaran, Martin Sachse, Marcio Barrios, Dan, AimelyneM, Matt Sullivan, Delnatte Pierre-Antoine, Jake Smith, Eugen Tudorancea, Iris, David Trinh, simonstl, Ray Daly, Uros Gruber, Justin Myers, Shai Zonis, Mom & Dad, Devin Clark, Dennis Palmer, Brian Panahi Johnson, Josh Marshall, Marshall, Dennis Kerr, Matt Steele, Erik Slagter, Sacah, Justin Rainbow, Christian Nilsson, Delapouite, D.Pereira, Nicolas Hoizey, George V. Reilly, Dan Reeves, Bruno Laturner, Chad Jennings, Shane King, Jeremiah Lee Cohick, od3n, Stan Yamane, Marko Vucinic, Jim B, Stephen Collins, Ægir Þorsteinsson, Eric Pederson, Owain, Nathan Smith, Jeanetteurphy, Alexandre ELISÉ, Chris Peterson, Rik Watson, Luke Matthews, Justin Lowery, Morten Nielsen, Vernon Kesner, Chetan Shenoy, Paul Tregoing, Marc Grabanski, Dion Almaer, Andrew Sullivan, Keith Elsass, Tom Burke, Brian Ashenfelter, David Stuart, Karl Swedberg, Graeme, Brandon Hays, John Christopher, Gior, manoj reddy, Chad Smith, Jared Harbour, Minoru TODA, Chris Wigley, Daniel Mee, Mike, Handyface, Alex Jahraus, Carl Furrow, Rob Foulkrod, Max Shishkin, Leigh Penny Jr., Robert Ferguson, Mike van Hoenselaar, Hasse Schougaard, rajan venkataguru, Jeff Adams, Trae Robbins, Rolf Langenhuijzen, Jorge Antunes, Alex Koloskov, Hugh Greenish, Tim Jones, Jose Ochoa, Michael Brennan-White, Naga Harish Muvva, Barkóczi Dávid, Kitt Hodsden, Paul McGraw, Sascha Goldhofer, Andrew Metcalf, Markus Krogh, Michael Mathews, Matt Jared, Juanfran, Georgie Kirschner, Kenny Lee, Ted Zhang, Amit Pahwa, Inbal Sinai, Dan Raine, Schabse Laks, Michael Tervoort, Alexandre Abreu, Alan Joseph Williams, NicolasD, Cindy Wong, Reg Braithwaite, LocalPCGuy, Jon Friskics, Chris Merriman, John Pena, Jacob Katz, Sue Lockwood, Magnus Johansson, Jeremy Crapsey, Grzegorz Pawłowski, nico nuzzaci, Christine Wilks, Hans Bergren, charles montgomery, Ariel בר-לבב Fogel, Ivan Kolev, Daniel Campos, Hugh Wood, Christian Bradford, Frédéric Harper, Ionuţ Dan Popa, Jeff Trimble, Rupert Wood, Trey Carrico, Pancho Lopez, Joël kuijten, Tom A Marra, Jeff Jewiss, Jacob Rios, Paolo Di Stefano, Soledad Penades, Chris Gerber, Andrey Dolganov, Wil Moore III, Thomas Martineau, Kareem, Ben Thouret, Udi Nir, Morgan Laupies, jory carson-burson, Nathan L Smith, Eric Damon Walters, Derry Lozano-Hoyland, Geoffrey Wiseman, mkeehner, KatieK, Scott MacFarlane, Brian LaShomb, Adrien Mas, christopher ross, Ian Littman, Dan Atkinson, Elliot Jobe, Nick Dozier, Peter Wooley, John Hoover, dan, Martin A. Jackson, Héctor Fernando Hurtado, andy ennamorato, Paul Seltmann, Melissa Gore, Dave Pollard, Jack Smith, Philip Da Silva, Guy Israeli, @megalithic, Damian Crawford, Felix Gliesche, April Carter Grant, Heidi, jim tierney, Andrea Giammarchi, Nico Vignola, Don Jones, Chris Hartjes, Alex Howes, john gibbon, David J. Groom, BBox, Yu 'Dilys' Sun, Nate Steiner, Brandon Satrom, Brian Wyant, Wesley Hales, Ian Pouncey, Timothy Kevin Oxley, George Terezakis, sanjay raj, Jordan Harband, Marko McLion, Wolfgang Kaufmann, Pascal Peuckert, Dave Nugent, Markus Liebelt, Welling Guzman, Nick Cooley, Daniel Mesquita, Robert Syvarth, Chris Coyier, Rémy Bach, Adam Dougal, Alistair Duggin, David Loidolt, Ed Richer, Brian Chenault, GoldFire Studios, Carles Andrés, Carlos Cabo, Yuya Saito, roberto ricardo, Barnett Klane, Mike Moore, Kevin Marx, Justin Love, Joe Taylor, Paul Dijou, Michael Kohler, Rob Cassie, Mike Tierney, Cody Leroy Lindley, tofuji, Shimon Schwartz, Raymond, Luc De Brouwer, David Hayes, Rhys Brett-Bowen, Dmitry, Aziz Khoury, Dean, Scott Tolinski - Level Up, Clement Boirie, Djordje Lukic, Anton Kotenko, Rafael Corral, Philip Hurwitz, Jonathan Pidgeon, Jason Campbell, Joseph C., SwiftOne, Jan Hohner, Derick Bailey, getify, Daniel Cousineau, Chris Charlton, Eric Turner, David Turner, Joël Galeran, Dharma Vagabond, adam, Dirk van Bergen, dave ♥♫★ furf, Vedran Zakanj, Ryan McAllen, Natalie Patrice Tucker, Eric J. Bivona, Adam Spooner, Aaron Cavano, Kelly Packer, Eric J, Martin Drenovac, Emilis, Michael Pelikan, Scott F. Walter, Josh Freeman, Brandon Hudgeons, vijay chennupati, Bill Glennon, Robin R., Troy Forster, otaku_coder, Brad, Scott, Frederick Ostrander, Adam Brill, Seb Flippence, Michael Anderson, Jacob, Adam Randlett, Standard, Joshua Clanton, Sebastian Kouba, Chris Deck, SwordFire, Hannes Papenberg, Richard Woeber, hnzz, Rob Crowther, Jedidiah Broadbent, Sergey Chernyshev, Jay-Ar Jamon, Ben Combee, luciano bonachela, Mark Tomlinson, Kit Cambridge, Michael Melgares, Jacob Adams, Adrian Bruinhout, Bev Wieber, Scott Puleo, Thomas Herzog, April Leone, Daniel Mizieliński, Kees van Ginkel, Jon Abrams, Erwin Heiser, Avi Laviad, David newell, Jean-Francois Turcot, Niko Roberts, Erik Dana, Charles Neill, Aaron Holmes, Grzegorz Ziółkowski, Nathan Youngman, Timothy, Jacob Mather, Michael Allan, Mohit Seth, Ryan Ewing, Benjamin Van Treese, Marcelo Santos, Denis Wolf, Phil Keys, Chris Yung, Timo Tijhof, Martin Lekvall, Agendine, Greg Whitworth, Helen Humphrey, Dougal Campbell, Johannes Harth, Bruno Girin, Brian Hough, Darren Newton, Craig McPheat, Olivier Tille, Dennis Roethig, Mathias Bynens, Brendan Stromberger, sundeep, John Meyer, Ron Male, John F Croston III, gigante, Carl Bergenhem, B.J. May, Rebekah Tyler, Ted Foxberry, Jordan Reese, Terry Suitor, afeliz, Tom Kiefer, Darragh Duffy, Kevin Vanderbeken, Andy Pearson, Simon Mac Donald, Abid Din, Chris Joel, Tomas Theunissen, David Dick, Paul Grock, Brandon Wood, John Weis, dgrebb, Nick Jenkins, Chuck Lane, Johnny Megahan, marzsman, Tatu Tamminen, Geoffrey Knauth, Alexander Tarmolov, Jeremy Tymes, Chad Auld, Sean Parmelee, Rob Staenke, Dan Bender, Yannick derwa, Joshua Jones, Geert Plaisier, Tom LeZotte, Christen Simpson, Stefan Bruvik, Justin Falcone, Carlos Santana, Michael Weiss, Pablo Villoslada, Peter deHaan, Dimitris Iliopoulos, seyDoggy, Adam Jordens, Noah Kantrowitz, Amol M, Matthew Winnard, Dirk Ginader, Phinam Bui, David Rapson, Andrew Baxter, Florian Bougel, Michael George, Alban Escalier, Daniel Sellers, Sasha Rudan, John Green, Robert Kowalski, David I. Teixeira (@ditma, Charles Carpenter, Justin Yost, Sam S, Denis Ciccale, Kevin Sheurs, Yannick Croissant, Pau Fracés, Stephen McGowan, Shawn Searcy, Chris Ruppel, Kevin Lamping, Jessica Campbell, Christopher Schmitt, Sablons, Jonathan Reisdorf, Bunni Gek, Teddy Huff, Michael Mullany, Michael Fürstenberg, Carl Henderson, Rick Yoesting, Scott Nichols, Hernán Ciudad, Andrew Maier, Mike Stapp, Jesse Shawl, Sérgio Lopes, jsulak, Shawn Price, Joel Clermont, Chris Ridmann, Sean Timm, Jason Finch, Aiden Montgomery, Elijah Manor, Derek Gathright, Jesse Harlin, Dillon Curry, Courtney Myers, Diego Cadenas, Arne de Bree, João Paulo Dubas, James Taylor, Philipp Kraeutli, Mihai Păun, Sam Gharegozlou, joshjs, Matt Murchison, Eric Windham, Timo Behrmann, Andrew Hall, joshua price, Théophile Villard
17 |
18 | This book series is being produced in an open source fashion, including editing and production. We owe GitHub a debt of gratitude for making that sort of thing possible for the community!
19 |
20 | Thank you again to all the countless folks I didn't name but who I nonetheless owe thanks. May this book series be "owned" by all of us and serve to contribute to increasing awareness and understanding of the JavaScript language, to the benefit of all current and future community contributors.
21 |
--------------------------------------------------------------------------------
/this & object prototypes/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarStudio/You-Dont-Know-JS/f4b83f540033904867311c597d16232bd08a984e/this & object prototypes/cover.jpg
--------------------------------------------------------------------------------
/this & object prototypes/fig1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarStudio/You-Dont-Know-JS/f4b83f540033904867311c597d16232bd08a984e/this & object prototypes/fig1.png
--------------------------------------------------------------------------------
/this & object prototypes/fig2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarStudio/You-Dont-Know-JS/f4b83f540033904867311c597d16232bd08a984e/this & object prototypes/fig2.png
--------------------------------------------------------------------------------
/this & object prototypes/fig3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarStudio/You-Dont-Know-JS/f4b83f540033904867311c597d16232bd08a984e/this & object prototypes/fig3.png
--------------------------------------------------------------------------------
/this & object prototypes/fig4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarStudio/You-Dont-Know-JS/f4b83f540033904867311c597d16232bd08a984e/this & object prototypes/fig4.png
--------------------------------------------------------------------------------
/this & object prototypes/fig5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarStudio/You-Dont-Know-JS/f4b83f540033904867311c597d16232bd08a984e/this & object prototypes/fig5.png
--------------------------------------------------------------------------------
/this & object prototypes/fig6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarStudio/You-Dont-Know-JS/f4b83f540033904867311c597d16232bd08a984e/this & object prototypes/fig6.png
--------------------------------------------------------------------------------
/this & object prototypes/foreword.md:
--------------------------------------------------------------------------------
1 | # You Don't Know JS: *this* & Object Prototypes
2 | # Foreword
3 |
4 | While reading this book in preparation for writing this foreword, I was forced to reflect on how I learned JavaScript and how much it has changed over the last 15 years that I have been programming and developing with it.
5 |
6 | When I started using JavaScript 15 years ago, the practice of using non-HTML technologies such as CSS and JS in your web pages was called DHTML or Dynamic HTML. Back then, the usefulness of JavaScript varied greatly and seemed to be tilted toward adding animated snowflakes to your web pages or dynamic clocks that told the time in the status bar. Suffice it to say, I didn’t really pay much attention to JavaScript in the early part of my career because of the novelty of the implementations that I often found on the Internet.
7 |
8 | It wasn’t until 2005 that I first rediscovered JavaScript as a real programming language that I needed to pay closer attention to. After digging into the first beta release of Google Maps, I was hooked on the potential it had. At the time, Google Maps was a first-of-its-kind application -- it allowed you to move a map around with your mouse, zoom in and out, and make server requests without reloading the page -- all with JavaScript. It seemed like magic!
9 |
10 | When anything seems like magic, it is usually a good indication you are at the dawn of a new way of doing things. And boy, was I not wrong -- fast-forwarding to today, I would say that JavaScript is one of the primary languages I use for both client- and server-side programming, and I wouldn’t have it any other way.
11 |
12 | One of my regrets as I look over the past 15 years is that I didn’t give JavaScript more of a chance before 2005, or more accurately, that I lacked the foresight to see JavaScript as a true programming language that is just as useful as C++, C#, Java, and many others.
13 |
14 | If I had this *You Don’t Know JS* series of books at the start of my career, my career history would look much different than it does today. And that is one of the things I love about this series: it explains JS at a level that builds your understanding as you go through the series, but in a fun and informative way.
15 |
16 | *this & Object Prototypes* is a wonderful continuation to the series. It does a great and natural job of building on the prior book, Scope & Closures, and extending that knowledge to a very important part of the JS language, the `this` keyword and prototypes. These two simple things are pivotal for what you will learn in the future books, because they are foundational to doing real programming with JavaScript. The concept of how to create objects, relate them, and extend them to represent things in your application is necessary to create large and complex applications in JavaScript. And without them, creating complex applications (such as Google Maps) wouldn’t be possible in JavaScript.
17 |
18 | I would say that the vast majority of web developers probably have never built a JavaScript object and just treat the language as event-binding glue between buttons and AJAX requests. I was in that camp at a point in my career, but after I learned how to master prototypes and create objects in JavaScript, a world of possibilities opened up for me. If you fall into the category of just creating event-binding glue code, this book is a must-read; if you just need a refresher, this book will be a go-to resource for you. Either way, you will not be disappointed. Trust me!
19 |
20 | Nick Berardi
21 | [nickberardi.com](http://nickberardi.com), [@nberardi](http://twitter.com/nberardi)
22 |
--------------------------------------------------------------------------------
/this & object prototypes/toc.md:
--------------------------------------------------------------------------------
1 | # You Don't Know JS: *this* & Object Prototypes
2 |
3 | ## Table of Contents
4 |
5 | * Foreword
6 | * Preface
7 | * Chapter 1: `this` Or That?
8 | * Why `this`?
9 | * Confusions
10 | * What's `this`?
11 | * Chapter 2: `this` All Makes Sense Now!
12 | * Call-site
13 | * Nothing But Rules
14 | * Everything In Order
15 | * Binding Exceptions
16 | * Lexical `this`
17 | * Chapter 3: Objects
18 | * Syntax
19 | * Type
20 | * Contents
21 | * Iteration
22 | * Chapter 4: Mixing (Up) "Class" Objects
23 | * Class Theory
24 | * Class Mechanics
25 | * Class Inheritance
26 | * Mixins
27 | * Chapter 5: Prototypes
28 | * `[[Prototype]]`
29 | * "Class"
30 | * "(Prototypal) Inheritance"
31 | * Object Links
32 | * Chapter 6: Behavior Delegation
33 | * Towards Delegation-Oriented Design
34 | * Classes vs. Objects
35 | * Simpler Design
36 | * Nicer Syntax
37 | * Introspection
38 | * Appendix A: ES6 `class`
39 | * Appendix B: Acknowledgments
40 |
41 |
--------------------------------------------------------------------------------
/types & grammar/README.md:
--------------------------------------------------------------------------------
1 | # 你不知道的JavaScript:类型和语法
2 |
3 |
4 |
5 | -----
6 |
7 | **[你可以从O'Reilly出版社获取数字版/纸质版](http://shop.oreilly.com/product/0636920033745.do)**
8 |
9 | -----
10 |
11 | [目录](toc.md)
12 |
13 | * [前言](foreword.md) ([David Walsh](http://davidwalsh.name))
14 | * [作者序](../preface.md)
15 | * [第一章:类型](ch1.md)
16 | * [第二章:值](ch2.md)
17 | * [第三章:原生对象](ch3.md)
18 | * [第四章:类型转换](ch4.md)
19 | * [第五章:语法](ch5.md)
20 | * [附录A:混合的JavaScript环境](apA.md)
21 | * [附录B:致谢!](apB.md)
22 |
--------------------------------------------------------------------------------
/types & grammar/apB.md:
--------------------------------------------------------------------------------
1 | # You Don't Know JS: Types & Grammar
2 | # Appendix B: Acknowledgments
3 |
4 | I have many people to thank for making this book title and the overall series happen.
5 |
6 | First, I must thank my wife Christen Simpson, and my two kids Ethan and Emily, for putting up with Dad always pecking away at the computer. Even when not writing books, my obsession with JavaScript glues my eyes to the screen far more than it should. That time I borrow from my family is the reason these books can so deeply and completely explain JavaScript to you, the reader. I owe my family everything.
7 |
8 | I'd like to thank my editors at O'Reilly, namely Simon St.Laurent and Brian MacDonald, as well as the rest of the editorial and marketing staff. They are fantastic to work with, and have been especially accommodating during this experiment into "open source" book writing, editing, and production.
9 |
10 | Thank you to the many folks who have participated in making this book series better by providing editorial suggestions and corrections, including Shelley Powers, Tim Ferro, Evan Borden, Forrest L. Norvell, Jennifer Davis, Jesse Harlin, and many others. A big thank you to David Walsh for writing the Foreword for this title.
11 |
12 | Thank you to the countless folks in the community, including members of the TC39 committee, who have shared so much knowledge with the rest of us, and especially tolerated my incessant questions and explorations with patience and detail. John-David Dalton, Juriy "kangax" Zaytsev, Mathias Bynens, Axel Rauschmayer, Nicholas Zakas, Angus Croll, Reginald Braithwaite, Dave Herman, Brendan Eich, Allen Wirfs-Brock, Bradley Meck, Domenic Denicola, David Walsh, Tim Disney, Peter van der Zee, Andrea Giammarchi, Kit Cambridge, Eric Elliott, and so many others, I can't even scratch the surface.
13 |
14 | The *You Don't Know JS* book series was born on Kickstarter, so I also wish to thank all my (nearly) 500 generous backers, without whom this book series could not have happened:
15 |
16 | > Jan Szpila, nokiko, Murali Krishnamoorthy, Ryan Joy, Craig Patchett, pdqtrader, Dale Fukami, ray hatfield, R0drigo Perez [Mx], Dan Petitt, Jack Franklin, Andrew Berry, Brian Grinstead, Rob Sutherland, Sergi Meseguer, Phillip Gourley, Mark Watson, Jeff Carouth, Alfredo Sumaran, Martin Sachse, Marcio Barrios, Dan, AimelyneM, Matt Sullivan, Delnatte Pierre-Antoine, Jake Smith, Eugen Tudorancea, Iris, David Trinh, simonstl, Ray Daly, Uros Gruber, Justin Myers, Shai Zonis, Mom & Dad, Devin Clark, Dennis Palmer, Brian Panahi Johnson, Josh Marshall, Marshall, Dennis Kerr, Matt Steele, Erik Slagter, Sacah, Justin Rainbow, Christian Nilsson, Delapouite, D.Pereira, Nicolas Hoizey, George V. Reilly, Dan Reeves, Bruno Laturner, Chad Jennings, Shane King, Jeremiah Lee Cohick, od3n, Stan Yamane, Marko Vucinic, Jim B, Stephen Collins, Ægir Þorsteinsson, Eric Pederson, Owain, Nathan Smith, Jeanetteurphy, Alexandre ELISÉ, Chris Peterson, Rik Watson, Luke Matthews, Justin Lowery, Morten Nielsen, Vernon Kesner, Chetan Shenoy, Paul Tregoing, Marc Grabanski, Dion Almaer, Andrew Sullivan, Keith Elsass, Tom Burke, Brian Ashenfelter, David Stuart, Karl Swedberg, Graeme, Brandon Hays, John Christopher, Gior, manoj reddy, Chad Smith, Jared Harbour, Minoru TODA, Chris Wigley, Daniel Mee, Mike, Handyface, Alex Jahraus, Carl Furrow, Rob Foulkrod, Max Shishkin, Leigh Penny Jr., Robert Ferguson, Mike van Hoenselaar, Hasse Schougaard, rajan venkataguru, Jeff Adams, Trae Robbins, Rolf Langenhuijzen, Jorge Antunes, Alex Koloskov, Hugh Greenish, Tim Jones, Jose Ochoa, Michael Brennan-White, Naga Harish Muvva, Barkóczi Dávid, Kitt Hodsden, Paul McGraw, Sascha Goldhofer, Andrew Metcalf, Markus Krogh, Michael Mathews, Matt Jared, Juanfran, Georgie Kirschner, Kenny Lee, Ted Zhang, Amit Pahwa, Inbal Sinai, Dan Raine, Schabse Laks, Michael Tervoort, Alexandre Abreu, Alan Joseph Williams, NicolasD, Cindy Wong, Reg Braithwaite, LocalPCGuy, Jon Friskics, Chris Merriman, John Pena, Jacob Katz, Sue Lockwood, Magnus Johansson, Jeremy Crapsey, Grzegorz Pawłowski, nico nuzzaci, Christine Wilks, Hans Bergren, charles montgomery, Ariel בר-לבב Fogel, Ivan Kolev, Daniel Campos, Hugh Wood, Christian Bradford, Frédéric Harper, Ionuţ Dan Popa, Jeff Trimble, Rupert Wood, Trey Carrico, Pancho Lopez, Joël kuijten, Tom A Marra, Jeff Jewiss, Jacob Rios, Paolo Di Stefano, Soledad Penades, Chris Gerber, Andrey Dolganov, Wil Moore III, Thomas Martineau, Kareem, Ben Thouret, Udi Nir, Morgan Laupies, jory carson-burson, Nathan L Smith, Eric Damon Walters, Derry Lozano-Hoyland, Geoffrey Wiseman, mkeehner, KatieK, Scott MacFarlane, Brian LaShomb, Adrien Mas, christopher ross, Ian Littman, Dan Atkinson, Elliot Jobe, Nick Dozier, Peter Wooley, John Hoover, dan, Martin A. Jackson, Héctor Fernando Hurtado, andy ennamorato, Paul Seltmann, Melissa Gore, Dave Pollard, Jack Smith, Philip Da Silva, Guy Israeli, @megalithic, Damian Crawford, Felix Gliesche, April Carter Grant, Heidi, jim tierney, Andrea Giammarchi, Nico Vignola, Don Jones, Chris Hartjes, Alex Howes, john gibbon, David J. Groom, BBox, Yu 'Dilys' Sun, Nate Steiner, Brandon Satrom, Brian Wyant, Wesley Hales, Ian Pouncey, Timothy Kevin Oxley, George Terezakis, sanjay raj, Jordan Harband, Marko McLion, Wolfgang Kaufmann, Pascal Peuckert, Dave Nugent, Markus Liebelt, Welling Guzman, Nick Cooley, Daniel Mesquita, Robert Syvarth, Chris Coyier, Rémy Bach, Adam Dougal, Alistair Duggin, David Loidolt, Ed Richer, Brian Chenault, GoldFire Studios, Carles Andrés, Carlos Cabo, Yuya Saito, roberto ricardo, Barnett Klane, Mike Moore, Kevin Marx, Justin Love, Joe Taylor, Paul Dijou, Michael Kohler, Rob Cassie, Mike Tierney, Cody Leroy Lindley, tofuji, Shimon Schwartz, Raymond, Luc De Brouwer, David Hayes, Rhys Brett-Bowen, Dmitry, Aziz Khoury, Dean, Scott Tolinski - Level Up, Clement Boirie, Djordje Lukic, Anton Kotenko, Rafael Corral, Philip Hurwitz, Jonathan Pidgeon, Jason Campbell, Joseph C., SwiftOne, Jan Hohner, Derick Bailey, getify, Daniel Cousineau, Chris Charlton, Eric Turner, David Turner, Joël Galeran, Dharma Vagabond, adam, Dirk van Bergen, dave ♥♫★ furf, Vedran Zakanj, Ryan McAllen, Natalie Patrice Tucker, Eric J. Bivona, Adam Spooner, Aaron Cavano, Kelly Packer, Eric J, Martin Drenovac, Emilis, Michael Pelikan, Scott F. Walter, Josh Freeman, Brandon Hudgeons, vijay chennupati, Bill Glennon, Robin R., Troy Forster, otaku_coder, Brad, Scott, Frederick Ostrander, Adam Brill, Seb Flippence, Michael Anderson, Jacob, Adam Randlett, Standard, Joshua Clanton, Sebastian Kouba, Chris Deck, SwordFire, Hannes Papenberg, Richard Woeber, hnzz, Rob Crowther, Jedidiah Broadbent, Sergey Chernyshev, Jay-Ar Jamon, Ben Combee, luciano bonachela, Mark Tomlinson, Kit Cambridge, Michael Melgares, Jacob Adams, Adrian Bruinhout, Bev Wieber, Scott Puleo, Thomas Herzog, April Leone, Daniel Mizieliński, Kees van Ginkel, Jon Abrams, Erwin Heiser, Avi Laviad, David newell, Jean-Francois Turcot, Niko Roberts, Erik Dana, Charles Neill, Aaron Holmes, Grzegorz Ziółkowski, Nathan Youngman, Timothy, Jacob Mather, Michael Allan, Mohit Seth, Ryan Ewing, Benjamin Van Treese, Marcelo Santos, Denis Wolf, Phil Keys, Chris Yung, Timo Tijhof, Martin Lekvall, Agendine, Greg Whitworth, Helen Humphrey, Dougal Campbell, Johannes Harth, Bruno Girin, Brian Hough, Darren Newton, Craig McPheat, Olivier Tille, Dennis Roethig, Mathias Bynens, Brendan Stromberger, sundeep, John Meyer, Ron Male, John F Croston III, gigante, Carl Bergenhem, B.J. May, Rebekah Tyler, Ted Foxberry, Jordan Reese, Terry Suitor, afeliz, Tom Kiefer, Darragh Duffy, Kevin Vanderbeken, Andy Pearson, Simon Mac Donald, Abid Din, Chris Joel, Tomas Theunissen, David Dick, Paul Grock, Brandon Wood, John Weis, dgrebb, Nick Jenkins, Chuck Lane, Johnny Megahan, marzsman, Tatu Tamminen, Geoffrey Knauth, Alexander Tarmolov, Jeremy Tymes, Chad Auld, Sean Parmelee, Rob Staenke, Dan Bender, Yannick derwa, Joshua Jones, Geert Plaisier, Tom LeZotte, Christen Simpson, Stefan Bruvik, Justin Falcone, Carlos Santana, Michael Weiss, Pablo Villoslada, Peter deHaan, Dimitris Iliopoulos, seyDoggy, Adam Jordens, Noah Kantrowitz, Amol M, Matthew Winnard, Dirk Ginader, Phinam Bui, David Rapson, Andrew Baxter, Florian Bougel, Michael George, Alban Escalier, Daniel Sellers, Sasha Rudan, John Green, Robert Kowalski, David I. Teixeira (@ditma, Charles Carpenter, Justin Yost, Sam S, Denis Ciccale, Kevin Sheurs, Yannick Croissant, Pau Fracés, Stephen McGowan, Shawn Searcy, Chris Ruppel, Kevin Lamping, Jessica Campbell, Christopher Schmitt, Sablons, Jonathan Reisdorf, Bunni Gek, Teddy Huff, Michael Mullany, Michael Fürstenberg, Carl Henderson, Rick Yoesting, Scott Nichols, Hernán Ciudad, Andrew Maier, Mike Stapp, Jesse Shawl, Sérgio Lopes, jsulak, Shawn Price, Joel Clermont, Chris Ridmann, Sean Timm, Jason Finch, Aiden Montgomery, Elijah Manor, Derek Gathright, Jesse Harlin, Dillon Curry, Courtney Myers, Diego Cadenas, Arne de Bree, João Paulo Dubas, James Taylor, Philipp Kraeutli, Mihai Păun, Sam Gharegozlou, joshjs, Matt Murchison, Eric Windham, Timo Behrmann, Andrew Hall, joshua price, Théophile Villard
17 |
18 | This book series is being produced in an open source fashion, including editing and production. We owe GitHub a debt of gratitude for making that sort of thing possible for the community!
19 |
20 | Thank you again to all the countless folks I didn't name but who I nonetheless owe thanks. May this book series be "owned" by all of us and serve to contribute to increasing awareness and understanding of the JavaScript language, to the benefit of all current and future community contributors.
21 |
--------------------------------------------------------------------------------
/types & grammar/ch1.md:
--------------------------------------------------------------------------------
1 | # 你不知道的JavaScript:类型和语法
2 | # 第一章:类型
3 |
4 | 大多数开发人员认为,动态语言(如JavaScript)并没有*类型*。让我们来看看ES5.1的规范(http://www.ecma-international.org/ecma-262/5.1/)对于这部分内容是怎么说的:
5 |
6 | > 本规范中所有算法所操作的值都有一个类型与之对应。这些值的类型均在本规范中对应。当然,这些类型也可能是ECMAScript语言中规定的类型的子类型。
7 | >
8 | > 在ECMAScript语言中,每个ECMAScript类型所对应的值都被ECMAScript程序开发人员直接操作。ECMAScript语言中规定的类型为Undefined, Null,Boolean,String,Number,以及Object。
9 |
10 | 如果你是强类型语言(静态语言)的粉丝,你也许会对这样使用“类型”感到很反感。在那些语言里,“类型”所拥有的含义可比在JS里的多得多。
11 |
12 | 有人说JS不应该声称它有“类型,应该把这种东西称为“标签”,或是“子类型”。
13 |
14 | 好吧。我们将使用这一粗略的定义(类似于规范中所描述的):一个*类型*是一个固有的,内建的特征集,无论是编译引擎还是**开发人员**,都可以用它来确定一个值的行为,并把这个值和其他值加以区分。
15 |
16 | 简单来说,如果在编译引擎和开发人员眼里,值`42`(数字)和值`"42"`(字符串)处理的方法不同,那么我们就说他们有不同的*类型*——`number`和`string`。当你处理`42`时,你将使用一些处理数字的方法,比如数学运算。而当你处理`"42"`时,你则会使用一些字符串处理方法,比如输出到页面,等等。**这两个值有不同的类型。**
17 |
18 | 虽然这并不是什么严谨的定义,但对于我们接下来的讨论,已经绰绰有余了。而且这样的定义,和JS如何形容自己是一致的。
19 |
20 | # 类型——或是别的什么
21 |
22 | 不考虑学术上的争论,我们来想想为什么JavaScript会需要*类型*?
23 |
24 | 对于每种*类型*及其基本行为都有所了解,有助于更高效的将值进行类型转换(详见第四章,类型转换)。几乎所有的JS程序,都存在着这样那样的类型转换,所以了解这些,对你来说很重要。
25 |
26 | 如果你有一个值为`42`的`number`,但想对它进行`string`类型的操作,如移除`1`位置的字符`"2"`,你最好先将这个值的类型从`number`转换为`string`。
27 |
28 | 这看似很简单。
29 |
30 | 但是进行这样的类型转换,有很多方式。有些方式很明确,很简单就能说出来龙去脉,并且也值得信赖.但如果你不够细心,类型转换可能以一种匪夷所思的方式展现在你面前。
31 |
32 | 类型转换可能是JavaScript最大的疑惑之一了。这点经常被视为这一语言的缺陷,是应该避免使用的。
33 |
34 | 由于有了对JavaScript类型的全面了解,我们希望能够说明为何类型转换的*坏名声*言过其实,甚至是不恰当的——我们会改变你的传统观点,让你看到类型转换的强大力量和实用性。不过首先,我们先来了解一下值和类型。
35 |
36 | ## 内建类型
37 |
38 | JavaScript定义了七种内建类型:
39 |
40 | * `null`
41 | * `undefined`
42 | * `boolean`
43 | * `number`
44 | * `string`
45 | * `object`
46 | * `symbol` —— ES6中新增
47 |
48 | **提示:**以上类型,除`object`的被称为基本类型。
49 |
50 | `typeof`运算符会检测所给值得类型,并返回以下其中字符串类型的值——然而奇怪的是,返回的结果和我们刚刚列出的的内建类型并不一一对应。
51 |
52 | ```js
53 | typeof undefined === "undefined"; // true
54 | typeof true === "boolean"; // true
55 | typeof 42 === "number"; // true
56 | typeof "42" === "string"; // true
57 | typeof { life: 42 } === "object"; // true
58 |
59 | // ES6新增!
60 | typeof Symbol() === "symbol"; // true
61 | ```
62 |
63 | 列出的六种类型的值都会返回一个对应类型名称的字符串。`Symbol`是ES6中新增的数据类型,我们会在第三章详细介绍。
64 |
65 | 你也许注意到了,我将`null`从列表中除去了。因为他很特殊——当使用`typeof`运算符时,它表现的就像bug一样:
66 |
67 | ```js
68 | typeof null === "object"; // true
69 | ```
70 |
71 | 如果它返回的是`"null"`的话,那可真是件好事,可惜的是,这个bug已经存在了20年,而且由于有太多的web程序依赖这一bug运行,修复这一bug的话,将会创造更多的bug,并且使很多web应用无法运行,所以估计将来也不会修复。
72 |
73 | 如果你想要确定一个`null`类型的值是这一类型,你需要使用复合判定:
74 |
75 | ```js
76 | var a = null;
77 |
78 | (!a && typeof a === "object"); // true
79 | ```
80 |
81 | `null`是基本类型中唯一值表现的像false一样的类型(详见第四章),但如果运行`typeof`进行检查,返回的还是`"object"`。
82 |
83 | 那么,`typeof`返回的第七种字符串类型的值是什么?
84 |
85 | ```js
86 | typeof function a(){ /* .. */ } === "function"; // true
87 | ```
88 |
89 | 单拍脑袋想的话,很容易理解`function`(函数)会是JS中顶级的内建类型,尤其是它针对`typeof`运算符的表现。然而,如果你阅读相关的标准,会发现它实际上是对象类型(`object`)的子类型。更确切的说,函数是一种“可以被调用的对象”——一类拥有名为`[[Call]]`的内建属性且可以被调用的对象。
90 |
91 | 函数实际上是对象这点其实很有用。最重要的一点就是,它可以有属性。例如:
92 |
93 | ```js
94 | function a(b,c) {
95 | /* .. */
96 | }
97 | ```
98 |
99 | 该函数具有一个`length`属性,值为函数形式参数的个数。
100 |
101 | ```js
102 | a.length; // 2
103 | ```
104 |
105 | 本例中,函数声明中包括两个形参(`b`和`c`),所以“函数的长度”是`2`。
106 |
107 | 那么数组呢?他们也是JS内置的类型,会不会有什么特殊的表现?
108 |
109 | ```js
110 | typeof [1,2,3] === "object"; // true
111 | ```
112 |
113 | 然而并没有,只是普通的对象罢了。一般将它们也视为对象的“子类型”(详见第三章),与普通对象不同的是,它们可以通过数字来序列化(就像普通对象那样可以通过字符串类型的key(键)来序列化一样),并且操作有可以自动更新的`length`属性。
114 |
115 | ## 值和对象
116 |
117 | 在JavaScript中,变量不具有类型——**值有类型**。变量可以在任何时刻保存任何值。
118 |
119 | 换句话说,JS并不是强类型的语言,编译引擎不会让一个*变量*始终保存和这个变量最开始所保存的值拥有相同的类型。变量可以保存一个`string`类型的值,并在接下来的赋值操作中保存一个`number`类型,以此类推。
120 |
121 | 一个`值`如`42`是`number`类型的,而且这个*类型*是不能改变的。另一个值,如`"42"`是`string`类型,可以通过对`number`类型的`42`进行**类型转换**(详见第四章)来得到。
122 |
123 | 如果你用`typeof`运算符去操作一个变量,看上去就像是在求“变量是什么类型?”,然而JS中的变量并不具有类型。所以,其实是在求“变量中保存的值是什么类型?”
124 |
125 | ```js
126 | var a = 42;
127 | typeof a; // "number"
128 |
129 | a = true;
130 | typeof a; // "boolean"
131 | ```
132 |
133 | `typeof`运算符返回的必然是字符串类型:
134 |
135 | ```js
136 | typeof typeof 42; // "string"
137 | ```
138 |
139 | 其中`typeof 42`会返回`"number"`,然后`typeof "number"`就会返回`"string"`。
140 |
141 | ### `undefined` vs "undeclared"(未定义和未声明)
142 |
143 | 当变量没有被赋值的时候,其值为`undefined`。调用`typeof`运算符对它进行操作会返回`"undefined"`:
144 |
145 | ```js
146 | var a;
147 |
148 | typeof a; // "undefined"
149 |
150 | var b = 42;
151 | var c;
152 |
153 | // 然后另
154 | b = c;
155 |
156 | typeof b; // "undefined"
157 | typeof c; // "undefined"
158 | ```
159 |
160 | 对于许多开发者都认为“未定义(undefined)”相当于是“未声明”的代名词,然而在JS中,这两个概念截然不同。
161 |
162 | 一个“未定义(undefined)”的变量是已经在当前作用域中声明了的,只不过是目前它并没有保存其他的值而已。而“未声明(undeclared)”则是指在当前作用域中没有声明的变量。
163 |
164 | 考虑如下的示例:
165 |
166 | ```js
167 | var a;
168 |
169 | a; // undefined
170 | b; // ReferenceError: b is not defined(错误的中文大意是:引用错误:b尚未定义)
171 | ```
172 |
173 | 浏览器对于这一错误的描述可以说相当让人困惑。“b尚未定义”很容易让人理解成“b是未定义”。然后,“未定义”和“尚未定义”间的差别实在是太大了。如果浏览器要是能报个像“未找到变量b”或是“b尚未声明”之类的错误,就不会这么让人迷糊了。
174 |
175 | 同样的,`typeof`运算符的特殊行为加重了这一困惑,请看例子:
176 |
177 | ```js
178 | var a;
179 |
180 | typeof a; // "undefined"
181 |
182 | typeof b; // "undefined"
183 | ```
184 |
185 | 对于“未声明”或着说“尚未定义”的变量,`typeof`会返回`"undefined"`。你会发现,虽然`b`是一个没有声明的变量,但是当我们执行`typeof b`的时候却没有报错。会出现这种情况,源于`typeof`运算符特殊的安全机制。
186 |
187 | 和前面的例子一样,如果对于没有声明的变量,`typeof`会返回一个“未声明”之类的东西,而不是将其和“undefined”混为一谈的话,就不会有这么多麻烦了。
188 |
189 | ### `typeof`对未声明的处理
190 |
191 | 然而,在浏览器端这种,多个脚本文件均可以在全局命名空间下加载变量的JavaScript环境中,这种安全机制反而很有用。
192 |
193 | **提示:**许多开发者坚信,在全局命名空间下不应该有任何变量,所有的东西都应该在模块或者是私有/分离的命名空间中。理论上,这很棒,而且确实是我们追求的一个目标,然而在实践中,这几乎是不可能的。不过ES6中加入了对模块的支持,这使得我们能够更接近这一目标。
194 |
195 | 例如,在你的程序中,你通过一个全局变量`DEBUG`实现了一个调试模式。你希望在开始进行debug,如在控制台输出一条调试信息之前,检查这个变量是否已经声明。你可以将全局的`var DEBUG = true`声明写在一个名为"debug.js"的文件夹下,当你在进行开发/测试下才在浏览器中引入,而不是在生产环境。
196 |
197 | 而你需要注意的,就是如何去在你的其他代码中检查这个全局的`DEBUG`变量,毕竟你可不希望报一个`ReferenceError`。在这种场景下,`typeof`运算符就成了我们的好帮手。
198 |
199 | ```js
200 | // 注意,这种方法会报错!
201 | if (DEBUG) {
202 | console.log( "Debugging is starting" );
203 | }
204 |
205 | // 更为安全的检查方式
206 | if (typeof DEBUG !== "undefined") {
207 | console.log( "Debugging is starting" );
208 | }
209 | ```
210 |
211 | 这类检查不仅对于用户定义的变量很有用,当你在见此一个内建的API的时候,这种不会抛出错误的检查也非常棒:
212 |
213 | ```js
214 | if (typeof atob === "undefined") {
215 | atob = function() { /*..*/ };
216 | }
217 | ```
218 |
219 | **提示:**当你在对一个目前不存在的特性写“polyfill(腻子脚本)”的时候,你需要避免用`var`来声明变量`atob`。如果你在`if`语句里面使用`var atob`来声明,即使if语句的条件不满足,变量的声明也会被提升到作用域的最顶级(详见本系列中的《作用域和闭包》)。在部分浏览器中,对一些特殊的全局的内建对象类型(常称为“宿主对象”,如浏览器中的DOM对象),这种重复的声明会报错。所以最好避免使用`var`来阻止变量提升。
220 |
221 | 另一种不使用`typeof`安全机制,进行检查的方法,就是利用所有的全局变量都是(global)全局对象(在浏览器中就是`window`对象)这一点。所以,上面的检查还有如下等价的写法(同样很安全):
222 |
223 | ```js
224 | if (window.DEBUG) {
225 | // ..
226 | }
227 |
228 | if (!window.atob) {
229 | // ..
230 | }
231 | ```
232 |
233 | 和引用一个未声明的变量不同,当你尝试获取一个对象(即便是`window`对象)不存在的属性的时候,并不会抛出什么`ReferenceError`。
234 |
235 | 而另一方面,一些开发者极力避免使用`window`对象来引用全局变量,尤其是当你的代码运行在多种JS环境(不光是浏览器,比如服务端的node.js)时,全局(global)对象可不一定叫`window`。
236 |
237 | 即便当你不使用全局变量的时候,`typeof`的安全机制也有它的用武之地,虽然这种情况很少见,也有一些开发人员认为这种设计并不值得。比如你准备写一个可供他人复制粘贴的通用函数,想要知道程序中是否定义了某一特定的变量(将会影响你函数的执行),你可以这样:
238 |
239 | ```js
240 | function doSomethingCool() {
241 | var helper =
242 | (typeof FeatureXYZ !== "undefined") ?
243 | FeatureXYZ :
244 | function() { /*.. 默认值 ..*/ };
245 |
246 | var val = helper();
247 | // ..
248 | }
249 | ```
250 |
251 | `doSomethingCool()`会检查是否存在一个名为`FeatureXYZ`的变量,有的话就使用,没有的话,就使用默认值。现在,如果有人在他的程序/模块中使用了这一公共函数,检查它们是否定义了`FeatureXYZ`就显得尤为重要:
252 |
253 | ```js
254 | // IIFE (详见本系列《作用域和闭包》一书中的立即执行函数表达式)
255 | (function(){
256 | function FeatureXYZ() { /*.. my XYZ feature ..*/ }
257 |
258 | // include `doSomethingCool(..)`
259 | function doSomethingCool() {
260 | var helper =
261 | (typeof FeatureXYZ !== "undefined") ?
262 | FeatureXYZ :
263 | function() { /*.. default feature ..*/ };
264 |
265 | var val = helper();
266 | // ..
267 | }
268 |
269 | doSomethingCool();
270 | })();
271 | ```
272 |
273 | 在这里,`FeatureXYZ`并不是一个全局变量,但我们仍然使用`typeof`运算符的安全机制来检查。注意到,在这种情况下,我们可没有全局对象用于这一检查(像使用`window.___`那样),所以`typeof`真的很有帮助。
274 |
275 | 有些开发者可能会喜欢一种叫做“依赖注入”的设计模式,让`doSomethingCool()`不去检查`FeatureXYZ`是否在它外部/附近被定义,而是通过显示的判断来确定,如:
276 |
277 | ```js
278 | function doSomethingCool(FeatureXYZ) {
279 | var helper = FeatureXYZ ||
280 | function() { /*.. 默认值 ..*/ };
281 |
282 | var val = helper();
283 | // ..
284 | }
285 | ```
286 |
287 | 要实现这一功能,其实有很多解决方案。没有一种模式是“对的”或“错的”——要对各种方法进行权衡。不过总的来说,`typeof`的安全机制确实给了我们更多的选择。
288 |
289 | ## 总结
290 |
291 | JavaScript拥有七种内建类型:`null`,`undefined`,`boolean`,`number`,`string`,`object`,`symbol`。可以通过使用`typeof`运算符来对它们进行区分。
292 |
293 | 变量不具有类型,但值有。这些类型定义了值的行为。
294 |
295 | 许多开发者会将“未定义(undefined)”和“未声明”混为一谈,但是在JavaScript它们完全不同。`undefined`是一个可供已经声明的变量保存的值。“未声明”意味着一个未经声明的变量。
296 |
297 | 不幸的是,JavaScript中很多地方都将两者混为一谈,比如错误信息("ReferenceError: a is not defined"),以及用`typeof`操作,两者都返回`"undefined"`。
298 |
299 | 不过,`typeof`这种安全机制(阻止报错)在某些场景中,如需要检查一个变量是否存在的时候还是很有用的。
300 |
--------------------------------------------------------------------------------
/types & grammar/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarStudio/You-Dont-Know-JS/f4b83f540033904867311c597d16232bd08a984e/types & grammar/cover.jpg
--------------------------------------------------------------------------------
/types & grammar/fig1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarStudio/You-Dont-Know-JS/f4b83f540033904867311c597d16232bd08a984e/types & grammar/fig1.png
--------------------------------------------------------------------------------
/types & grammar/foreword.md:
--------------------------------------------------------------------------------
1 | # You Don't Know JS: Types & Grammar
2 | # Foreword
3 |
4 | It was once said, "JavaScript is the only language developers don't learn to use before using it."
5 |
6 | I laugh each time I hear that quote because it was true for me and I suspect it was for many other developers. JavaScript, and maybe even CSS and HTML, were not a core computer science language taught at college in the Internet's early days, so personal development was very much based on the budding developer's search and "view source" abilities to piece together these basic web languages.
7 |
8 | I still remember my first high school website project. The task was to create any type of web store, and me being a James Bond fan, I decided to create a Goldeneye store. It had everything: the Goldeneye midi theme song playing in the background, a JavaScript-powered crosshairs following the mouse around the screen, and a gunshot sound that played upon every click. Q would have been proud of this masterpiece of a website.
9 |
10 | I tell that story because I did back then what many developers are doing today: I copied and pasted chunks of JavaScript code into my project without having a clue what's actually happening. The widespread use of JavaScript toolkits like jQuery have, in their own small way, perpetuated this pattern of nonlearning of core JavaScript.
11 |
12 | I'm not disparaging JavaScript toolkit use; after all, I'm a member of the MooTools JavaScript team! But the reason JavaScript toolkits are as powerful as they are is because their developers know the fundamentals, and their "gotchas," and apply them magnificently. As useful as these toolkits are, it's still incredibly important to know the basics of the language, and with books like Kyle Simpson's *You Don't Know JS* series, there's no excuse not to learn them.
13 |
14 | *Types and Grammar*, the third installment of the series, is an excellent look at the core JavaScript fundamentals that copy and paste and JavaScript toolkits don't and could never teach you. Coercion and its pitfalls, natives as constructors, and the whole gamut of JavaScript basics are thoroughly explained with focused code examples. Like the other books in this series, Kyle cuts straight to the point: no fluff and word-smithing -- exactly the type of tech book I love.
15 |
16 | Enjoy Types and Grammar and don't let it get too far away from your desk!
17 |
18 | David Walsh
19 | [http://davidwalsh.name](http://davidwalsh.name), [@davidwalshblog](http://twitter.com/davidwalshblog)
20 | Senior Web Developer, Mozilla
21 |
--------------------------------------------------------------------------------
/types & grammar/toc.md:
--------------------------------------------------------------------------------
1 | # You Don't Know JS: Types & Grammar
2 |
3 | ## 目录
4 |
5 | * 前言
6 | * 作者序
7 | * 第一章:类型
8 | * 类型——或是别的什么
9 | * 内置类型
10 | * 值和类型
11 | * 第二章:值
12 | * 数组
13 | * 字符串
14 | * 数字
15 | * 特殊的值
16 | * 值vs引用
17 | * 第三章:原生对象
18 | * 内部的`[[Class]]`
19 | * Boxing Wrappers
20 | * Unboxing
21 | * Natives as Constructors
22 | * 第四章:类型转换
23 | * Converting Values
24 | * Abstract Value Operations
25 | * Explicit Coercion
26 | * Implicit Coercion
27 | * Loose Equals vs Strict Equals
28 | * Abstract Relational Comparison
29 | * 第五章:语法
30 | * Statements & Expressions
31 | * Operator Precedence
32 | * Automatic Semicolons
33 | * Errors
34 | * Function Arguments
35 | * `try..finally`
36 | * `switch`
37 | * 附录A:混合的JavaScript环境
38 | * Appendix B: Acknowledgments
39 |
40 |
--------------------------------------------------------------------------------
/up & going/README.md:
--------------------------------------------------------------------------------
1 | # You Don't Know JS: Up & Going
2 |
3 |
4 |
5 | -----
6 |
7 | **[Purchase digital/print copy from O'Reilly](http://shop.oreilly.com/product/0636920039303.do)**
8 |
9 | -----
10 |
11 | [Table of Contents](toc.md)
12 |
13 | * [Foreword](foreword.md) (by [Jenn Lukas](http://jennlukas.com))
14 | * [Preface](../preface.md)
15 | * [Chapter 1: Into Programming](ch1.md)
16 | * [Chapter 2: Into JavaScript](ch2.md)
17 | * [Chapter 3: Into YDKJS](ch3.md)
18 | * [Appendix A: Thank You's!](apA.md)
19 |
--------------------------------------------------------------------------------
/up & going/apA.md:
--------------------------------------------------------------------------------
1 | # You Don't Know JS: Up & Going
2 | # Appendix A: Acknowledgments
3 |
4 | I have many people to thank for making this book title and the overall series happen.
5 |
6 | First, I must thank my wife Christen Simpson, and my two kids Ethan and Emily, for putting up with Dad always pecking away at the computer. Even when not writing books, my obsession with JavaScript glues my eyes to the screen far more than it should. That time I borrow from my family is the reason these books can so deeply and completely explain JavaScript to you, the reader. I owe my family everything.
7 |
8 | I'd like to thank my editors at O'Reilly, namely Simon St.Laurent and Brian MacDonald, as well as the rest of the editorial and marketing staff. They are fantastic to work with, and have been especially accommodating during this experiment into "open source" book writing, editing, and production.
9 |
10 | Thank you to the many folks who have participated in making this book series better by providing editorial suggestions and corrections, including Shelley Powers, Tim Ferro, Evan Borden, Forrest L. Norvell, Jennifer Davis, Jesse Harlin, Kris Kowal, Rick Waldron, Jordan Harband, Benjamin Gruenbaum, Vyacheslav Egorov, David Nolen, and many others. A big thank you to Jenn Lukas for writing the Foreword for this title.
11 |
12 | Thank you to the countless folks in the community, including members of the TC39 committee, who have shared so much knowledge with the rest of us, and especially tolerated my incessant questions and explorations with patience and detail. John-David Dalton, Juriy "kangax" Zaytsev, Mathias Bynens, Axel Rauschmayer, Nicholas Zakas, Angus Croll, Reginald Braithwaite, Dave Herman, Brendan Eich, Allen Wirfs-Brock, Bradley Meck, Domenic Denicola, David Walsh, Tim Disney, Peter van der Zee, Andrea Giammarchi, Kit Cambridge, Eric Elliott, and so many others, I can't even scratch the surface.
13 |
14 | Since the "You Don't Know JS" book series was born on Kickstarter, I also wish to thank all my (nearly) 500 generous backers, without whom this book series could not have happened:
15 |
16 | > Jan Szpila, nokiko, Murali Krishnamoorthy, Ryan Joy, Craig Patchett, pdqtrader, Dale Fukami, ray hatfield, R0drigo Perez [Mx], Dan Petitt, Jack Franklin, Andrew Berry, Brian Grinstead, Rob Sutherland, Sergi Meseguer, Phillip Gourley, Mark Watson, Jeff Carouth, Alfredo Sumaran, Martin Sachse, Marcio Barrios, Dan, AimelyneM, Matt Sullivan, Delnatte Pierre-Antoine, Jake Smith, Eugen Tudorancea, Iris, David Trinh, simonstl, Ray Daly, Uros Gruber, Justin Myers, Shai Zonis, Mom & Dad, Devin Clark, Dennis Palmer, Brian Panahi Johnson, Josh Marshall, Marshall, Dennis Kerr, Matt Steele, Erik Slagter, Sacah, Justin Rainbow, Christian Nilsson, Delapouite, D.Pereira, Nicolas Hoizey, George V. Reilly, Dan Reeves, Bruno Laturner, Chad Jennings, Shane King, Jeremiah Lee Cohick, od3n, Stan Yamane, Marko Vucinic, Jim B, Stephen Collins, Ægir Þorsteinsson, Eric Pederson, Owain, Nathan Smith, Jeanetteurphy, Alexandre ELISÉ, Chris Peterson, Rik Watson, Luke Matthews, Justin Lowery, Morten Nielsen, Vernon Kesner, Chetan Shenoy, Paul Tregoing, Marc Grabanski, Dion Almaer, Andrew Sullivan, Keith Elsass, Tom Burke, Brian Ashenfelter, David Stuart, Karl Swedberg, Graeme, Brandon Hays, John Christopher, Gior, manoj reddy, Chad Smith, Jared Harbour, Minoru TODA, Chris Wigley, Daniel Mee, Mike, Handyface, Alex Jahraus, Carl Furrow, Rob Foulkrod, Max Shishkin, Leigh Penny Jr., Robert Ferguson, Mike van Hoenselaar, Hasse Schougaard, rajan venkataguru, Jeff Adams, Trae Robbins, Rolf Langenhuijzen, Jorge Antunes, Alex Koloskov, Hugh Greenish, Tim Jones, Jose Ochoa, Michael Brennan-White, Naga Harish Muvva, Barkóczi Dávid, Kitt Hodsden, Paul McGraw, Sascha Goldhofer, Andrew Metcalf, Markus Krogh, Michael Mathews, Matt Jared, Juanfran, Georgie Kirschner, Kenny Lee, Ted Zhang, Amit Pahwa, Inbal Sinai, Dan Raine, Schabse Laks, Michael Tervoort, Alexandre Abreu, Alan Joseph Williams, NicolasD, Cindy Wong, Reg Braithwaite, LocalPCGuy, Jon Friskics, Chris Merriman, John Pena, Jacob Katz, Sue Lockwood, Magnus Johansson, Jeremy Crapsey, Grzegorz Pawłowski, nico nuzzaci, Christine Wilks, Hans Bergren, charles montgomery, Ariel בר-לבב Fogel, Ivan Kolev, Daniel Campos, Hugh Wood, Christian Bradford, Frédéric Harper, Ionuţ Dan Popa, Jeff Trimble, Rupert Wood, Trey Carrico, Pancho Lopez, Joël kuijten, Tom A Marra, Jeff Jewiss, Jacob Rios, Paolo Di Stefano, Soledad Penades, Chris Gerber, Andrey Dolganov, Wil Moore III, Thomas Martineau, Kareem, Ben Thouret, Udi Nir, Morgan Laupies, jory carson-burson, Nathan L Smith, Eric Damon Walters, Derry Lozano-Hoyland, Geoffrey Wiseman, mkeehner, KatieK, Scott MacFarlane, Brian LaShomb, Adrien Mas, christopher ross, Ian Littman, Dan Atkinson, Elliot Jobe, Nick Dozier, Peter Wooley, John Hoover, dan, Martin A. Jackson, Héctor Fernando Hurtado, andy ennamorato, Paul Seltmann, Melissa Gore, Dave Pollard, Jack Smith, Philip Da Silva, Guy Israeli, @megalithic, Damian Crawford, Felix Gliesche, April Carter Grant, Heidi, jim tierney, Andrea Giammarchi, Nico Vignola, Don Jones, Chris Hartjes, Alex Howes, john gibbon, David J. Groom, BBox, Yu 'Dilys' Sun, Nate Steiner, Brandon Satrom, Brian Wyant, Wesley Hales, Ian Pouncey, Timothy Kevin Oxley, George Terezakis, sanjay raj, Jordan Harband, Marko McLion, Wolfgang Kaufmann, Pascal Peuckert, Dave Nugent, Markus Liebelt, Welling Guzman, Nick Cooley, Daniel Mesquita, Robert Syvarth, Chris Coyier, Rémy Bach, Adam Dougal, Alistair Duggin, David Loidolt, Ed Richer, Brian Chenault, GoldFire Studios, Carles Andrés, Carlos Cabo, Yuya Saito, roberto ricardo, Barnett Klane, Mike Moore, Kevin Marx, Justin Love, Joe Taylor, Paul Dijou, Michael Kohler, Rob Cassie, Mike Tierney, Cody Leroy Lindley, tofuji, Shimon Schwartz, Raymond, Luc De Brouwer, David Hayes, Rhys Brett-Bowen, Dmitry, Aziz Khoury, Dean, Scott Tolinski - Level Up, Clement Boirie, Djordje Lukic, Anton Kotenko, Rafael Corral, Philip Hurwitz, Jonathan Pidgeon, Jason Campbell, Joseph C., SwiftOne, Jan Hohner, Derick Bailey, getify, Daniel Cousineau, Chris Charlton, Eric Turner, David Turner, Joël Galeran, Dharma Vagabond, adam, Dirk van Bergen, dave ♥♫★ furf, Vedran Zakanj, Ryan McAllen, Natalie Patrice Tucker, Eric J. Bivona, Adam Spooner, Aaron Cavano, Kelly Packer, Eric J, Martin Drenovac, Emilis, Michael Pelikan, Scott F. Walter, Josh Freeman, Brandon Hudgeons, vijay chennupati, Bill Glennon, Robin R., Troy Forster, otaku_coder, Brad, Scott, Frederick Ostrander, Adam Brill, Seb Flippence, Michael Anderson, Jacob, Adam Randlett, Standard, Joshua Clanton, Sebastian Kouba, Chris Deck, SwordFire, Hannes Papenberg, Richard Woeber, hnzz, Rob Crowther, Jedidiah Broadbent, Sergey Chernyshev, Jay-Ar Jamon, Ben Combee, luciano bonachela, Mark Tomlinson, Kit Cambridge, Michael Melgares, Jacob Adams, Adrian Bruinhout, Bev Wieber, Scott Puleo, Thomas Herzog, April Leone, Daniel Mizieliński, Kees van Ginkel, Jon Abrams, Erwin Heiser, Avi Laviad, David newell, Jean-Francois Turcot, Niko Roberts, Erik Dana, Charles Neill, Aaron Holmes, Grzegorz Ziółkowski, Nathan Youngman, Timothy, Jacob Mather, Michael Allan, Mohit Seth, Ryan Ewing, Benjamin Van Treese, Marcelo Santos, Denis Wolf, Phil Keys, Chris Yung, Timo Tijhof, Martin Lekvall, Agendine, Greg Whitworth, Helen Humphrey, Dougal Campbell, Johannes Harth, Bruno Girin, Brian Hough, Darren Newton, Craig McPheat, Olivier Tille, Dennis Roethig, Mathias Bynens, Brendan Stromberger, sundeep, John Meyer, Ron Male, John F Croston III, gigante, Carl Bergenhem, B.J. May, Rebekah Tyler, Ted Foxberry, Jordan Reese, Terry Suitor, afeliz, Tom Kiefer, Darragh Duffy, Kevin Vanderbeken, Andy Pearson, Simon Mac Donald, Abid Din, Chris Joel, Tomas Theunissen, David Dick, Paul Grock, Brandon Wood, John Weis, dgrebb, Nick Jenkins, Chuck Lane, Johnny Megahan, marzsman, Tatu Tamminen, Geoffrey Knauth, Alexander Tarmolov, Jeremy Tymes, Chad Auld, Sean Parmelee, Rob Staenke, Dan Bender, Yannick derwa, Joshua Jones, Geert Plaisier, Tom LeZotte, Christen Simpson, Stefan Bruvik, Justin Falcone, Carlos Santana, Michael Weiss, Pablo Villoslada, Peter deHaan, Dimitris Iliopoulos, seyDoggy, Adam Jordens, Noah Kantrowitz, Amol M, Matthew Winnard, Dirk Ginader, Phinam Bui, David Rapson, Andrew Baxter, Florian Bougel, Michael George, Alban Escalier, Daniel Sellers, Sasha Rudan, John Green, Robert Kowalski, David I. Teixeira (@ditma, Charles Carpenter, Justin Yost, Sam S, Denis Ciccale, Kevin Sheurs, Yannick Croissant, Pau Fracés, Stephen McGowan, Shawn Searcy, Chris Ruppel, Kevin Lamping, Jessica Campbell, Christopher Schmitt, Sablons, Jonathan Reisdorf, Bunni Gek, Teddy Huff, Michael Mullany, Michael Fürstenberg, Carl Henderson, Rick Yoesting, Scott Nichols, Hernán Ciudad, Andrew Maier, Mike Stapp, Jesse Shawl, Sérgio Lopes, jsulak, Shawn Price, Joel Clermont, Chris Ridmann, Sean Timm, Jason Finch, Aiden Montgomery, Elijah Manor, Derek Gathright, Jesse Harlin, Dillon Curry, Courtney Myers, Diego Cadenas, Arne de Bree, João Paulo Dubas, James Taylor, Philipp Kraeutli, Mihai Păun, Sam Gharegozlou, joshjs, Matt Murchison, Eric Windham, Timo Behrmann, Andrew Hall, joshua price, Théophile Villard
17 |
18 | This book series is being produced in an open source fashion, including editing and production. We owe GitHub a debt of gratitude for making that sort of thing possible for the community!
19 |
20 | Thank you again to all the countless folks I didn't name but to whom I nonetheless owe thanks. May this book series be "owned" by all of us and serve to contribute to increasing awareness and understanding of the JavaScript language, to the benefit of all current and future community contributors.
21 |
--------------------------------------------------------------------------------
/up & going/ch3.md:
--------------------------------------------------------------------------------
1 | # You Don't Know JS: Up & Going
2 | # Chapter 3: Into YDKJS
3 |
4 | What is this series all about? Put simply, it's about taking seriously the task of learning *all parts of JavaScript*, not just some subset of the language that someone called "the good parts," and not just whatever minimal amount you need to get your job done at work.
5 |
6 | Serious developers in other languages expect to put in the effort to learn most or all of the language(s) they primarily write in, but JS developers seem to stand out from the crowd in the sense of typically not learning very much of the language. This is not a good thing, and it's not something we should continue to allow to be the norm.
7 |
8 | The *You Don't Know JS* (*YDKJS*) series stands in stark contrast to the typical approaches to learning JS, and is unlike almost any other JS books you will read. It challenges you to go beyond your comfort zone and to ask the deeper "why" questions for every single behavior you encounter. Are you up for that challenge?
9 |
10 | I'm going to use this final chapter to briefly summarize what to expect from the rest of the books in the series, and how to most effectively go about building a foundation of JS learning on top of *YDKJS*.
11 |
12 | ## Scope & Closures
13 |
14 | Perhaps one of the most fundamental things you'll need to quickly come to terms with is how scoping of variables really works in JavaScript. It's not enough to have anecdotal fuzzy *beliefs* about scope.
15 |
16 | The *Scope & Closures* title starts by debunking the common misconception that JS is an "interpreted language" and therefore not compiled. Nope.
17 |
18 | The JS engine compiles your code right before (and sometimes during!) execution. So we use some deeper understanding of the compiler's approach to our code to understand how it finds and deals with variable and function declarations. Along the way, we see the typical metaphor for JS variable scope management, "Hoisting."
19 |
20 | This critical understanding of "lexical scope" is what we then base our exploration of closure on for the last chapter of the book. Closure is perhaps the single most important concept in all of JS, but if you haven't first grasped firmly how scope works, closure will likely remain beyond your grasp.
21 |
22 | One important application of closure is the module pattern, as we briefly introduced in this book in Chapter 2. The module pattern is perhaps the most prevalent code organization pattern in all of JavaScript; deep understanding of it should be one of your highest priorities.
23 |
24 | ## this & Object Prototypes
25 |
26 | Perhaps one of the most widespread and persistent mistruths about JavaScript is that the `this` keyword refers to the function it appears in. Terribly mistaken.
27 |
28 | The `this` keyword is dynamically bound based on how the function in question is executed, and it turns out there are four simple rules to understand and fully determine `this` binding.
29 |
30 | Closely related to the `this` keyword is the object prototype mechanism, which is a look-up chain for properties, similar to how lexical scope variables are found. But wrapped up in the prototypes is the other huge miscue about JS: the idea of emulating (fake) classes and (so-called "prototypal") inheritance.
31 |
32 | Unfortunately, the desire to bring class and inheritance design pattern thinking to JavaScript is just about the worst thing you could try to do, because while the syntax may trick you into thinking there's something like classes present, in fact the prototype mechanism is fundamentally opposite in its behavior.
33 |
34 | What's at issue is whether it's better to ignore the mismatch and pretend that what you're implementing is "inheritance," or whether it's more appropriate to learn and embrace how the object prototype system actually works. The latter is more appropriately named "behavior delegation."
35 |
36 | This is more than syntactic preference. Delegation is an entirely different, and more powerful, design pattern, one that replaces the need to design with classes and inheritance. But these assertions will absolutely fly in the face of nearly every other blog post, book, and conference talk on the subject for the entirety of JavaScript's lifetime.
37 |
38 | The claims I make regarding delegation versus inheritance come not from a dislike of the language and its syntax, but from the desire to see the true capability of the language properly leveraged and the endless confusion and frustration wiped away.
39 |
40 | But the case I make regarding prototypes and delegation is a much more involved one than what I will indulge here. If you're ready to reconsider everything you think you know about JavaScript "classes" and "inheritance," I offer you the chance to "take the red pill" (*Matrix* 1999) and check out Chapters 4-6 of the *this & Object Prototypes* title of this series.
41 |
42 | ## Types & Grammar
43 |
44 | The third title in this series primarily focuses on tackling yet another highly controversial topic: type coercion. Perhaps no topic causes more frustration with JS developers than when you talk about the confusions surrounding implicit coercion.
45 |
46 | By far, the conventional wisdom is that implicit coercion is a "bad part" of the language and should be avoided at all costs. In fact, some have gone so far as to call it a "flaw" in the design of the language. Indeed, there are tools whose entire job is to do nothing but scan your code and complain if you're doing anything even remotely like coercion.
47 |
48 | But is coercion really so confusing, so bad, so treacherous, that your code is doomed from the start if you use it?
49 |
50 | I say no. After having built up an understanding of how types and values really work in Chapters 1-3, Chapter 4 takes on this debate and fully explains how coercion works, in all its nooks and crevices. We see just what parts of coercion really are surprising and what parts actually make complete sense if given the time to learn.
51 |
52 | But I'm not merely suggesting that coercion is sensible and learnable, I'm asserting that coercion is an incredibly useful and totally underestimated tool that *you should be using in your code.* I'm saying that coercion, when used properly, not only works, but makes your code better. All the naysayers and doubters will surely scoff at such a position, but I believe it's one of the main keys to upping your JS game.
53 |
54 | Do you want to just keep following what the crowd says, or are you willing to set all the assumptions aside and look at coercion with a fresh perspective? The *Types & Grammar* title of this series will coerce your thinking.
55 |
56 | ## Async & Performance
57 |
58 | The first three titles of this series focus on the core mechanics of the language, but the fourth title branches out slightly to cover patterns on top of the language mechanics for managing asynchronous programming. Asynchrony is not only critical to the performance of our applications, it's increasingly becoming *the* critical factor in writability and maintainability.
59 |
60 | The book starts first by clearing up a lot of terminology and concept confusion around things like "async," "parallel," and "concurrent," and explains in depth how such things do and do not apply to JS.
61 |
62 | Then we move into examining callbacks as the primary method of enabling asynchrony. But it's here that we quickly see that the callback alone is hopelessly insufficient for the modern demands of asynchronous programming. We identify two major deficiencies of callbacks-only coding: *Inversion of Control* (IoC) trust loss and lack of linear reason-ability.
63 |
64 | To address these two major deficiencies, ES6 introduces two new mechanisms (and indeed, patterns): promises and generators.
65 |
66 | Promises are a time-independent wrapper around a "future value," which lets you reason about and compose them regardless of if the value is ready or not yet. Moreover, they effectively solve the IoC trust issues by routing callbacks through a trustable and composable promise mechanism.
67 |
68 | Generators introduce a new mode of execution for JS functions, whereby the generator can be paused at `yield` points and be resumed asynchronously later. The pause-and-resume capability enables synchronous, sequential looking code in the generator to be processed asynchronously behind the scenes. By doing so, we address the non-linear, non-local-jump confusions of callbacks and thereby make our asynchronous code sync-looking so as to be more reason-able.
69 |
70 | But it's the combination of promises and generators that "yields" our most effective asynchronous coding pattern to date in JavaScript. In fact, much of the future sophistication of asynchrony coming in ES7 and later will certainly be built on this foundation. To be serious about programming effectively in an async world, you're going to need to get really comfortable with combining promises and generators.
71 |
72 | If promises and generators are about expressing patterns that let our programs run more concurrently and thus get more processing accomplished in a shorter period, JS has many other facets of performance optimization worth exploring.
73 |
74 | Chapter 5 delves into topics like program parallelism with Web Workers and data parallelism with SIMD, as well as low-level optimization techniques like ASM.js. Chapter 6 takes a look at performance optimization from the perspective of proper benchmarking techniques, including what kinds of performance to worry about and what to ignore.
75 |
76 | Writing JavaScript effectively means writing code that can break the constraint barriers of being run dynamically in a wide range of browsers and other environments. It requires a lot of intricate and detailed planning and effort on our parts to take a program from "it works" to "it works well."
77 |
78 | The *Async & Performance* title is designed to give you all the tools and skills you need to write reasonable and performant JavaScript code.
79 |
80 | ## ES6 & Beyond
81 |
82 | No matter how much you feel you've mastered JavaScript to this point, the truth is that JavaScript is never going to stop evolving, and moreover, the rate of evolution is increasing rapidly. This fact is almost a metaphor for the spirit of this series, to embrace that we'll never fully *know* every part of JS, because as soon as you master it all, there's going to be new stuff coming down the line that you'll need to learn.
83 |
84 | This title is dedicated to both the short- and mid-term visions of where the language is headed, not just the *known* stuff like ES6 but the *likely* stuff beyond.
85 |
86 | While all the titles of this series embrace the state of JavaScript at the time of this writing, which is mid-way through ES6 adoption, the primary focus in the series has been more on ES5. Now, we want to turn our attention to ES6, ES7, and ...
87 |
88 | Since ES6 is nearly complete at the time of this writing, *ES6 & Beyond* starts by dividing up the concrete stuff from the ES6 landscape into several key categories, including new syntax, new data structures (collections), and new processing capabilities and APIs. We cover each of these new ES6 features, in varying levels of detail, including reviewing details that are touched on in other books of this series.
89 |
90 | Some exciting ES6 things to look forward to reading about: destructuring, default parameter values, symbols, concise methods, computed properties, arrow functions, block scoping, promises, generators, iterators, modules, proxies, weakmaps, and much, much more! Phew, ES6 packs quite a punch!
91 |
92 | The first part of the book is a roadmap for all the stuff you need to learn to get ready for the new and improved JavaScript you'll be writing and exploring over the next couple of years.
93 |
94 | The latter part of the book turns attention to briefly glance at things that we can likely expect to see in the near future of JavaScript. The most important realization here is that post-ES6, JS is likely going to evolve feature by feature rather than version by version, which means we can expect to see these near-future things coming much sooner than you might imagine.
95 |
96 | The future for JavaScript is bright. Isn't it time we start learning it!?
97 |
98 | ## Review
99 |
100 | The *YDKJS* series is dedicated to the proposition that all JS developers can and should learn all of the parts of this great language. No person's opinion, no framework's assumptions, and no project's deadline should be the excuse for why you never learn and deeply understand JavaScript.
101 |
102 | We take each important area of focus in the language and dedicate a short but very dense book to fully explore all the parts of it that you perhaps thought you knew but probably didn't fully.
103 |
104 | "You Don't Know JS" isn't a criticism or an insult. It's a realization that all of us, myself included, must come to terms with. Learning JavaScript isn't an end goal but a process. We don't know JavaScript, yet. But we will!
105 |
--------------------------------------------------------------------------------
/up & going/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarStudio/You-Dont-Know-JS/f4b83f540033904867311c597d16232bd08a984e/up & going/cover.jpg
--------------------------------------------------------------------------------
/up & going/fig1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarStudio/You-Dont-Know-JS/f4b83f540033904867311c597d16232bd08a984e/up & going/fig1.png
--------------------------------------------------------------------------------
/up & going/fig2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarStudio/You-Dont-Know-JS/f4b83f540033904867311c597d16232bd08a984e/up & going/fig2.png
--------------------------------------------------------------------------------
/up & going/fig3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarStudio/You-Dont-Know-JS/f4b83f540033904867311c597d16232bd08a984e/up & going/fig3.png
--------------------------------------------------------------------------------
/up & going/fig4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarStudio/You-Dont-Know-JS/f4b83f540033904867311c597d16232bd08a984e/up & going/fig4.png
--------------------------------------------------------------------------------
/up & going/fig5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarStudio/You-Dont-Know-JS/f4b83f540033904867311c597d16232bd08a984e/up & going/fig5.png
--------------------------------------------------------------------------------
/up & going/fig6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarStudio/You-Dont-Know-JS/f4b83f540033904867311c597d16232bd08a984e/up & going/fig6.png
--------------------------------------------------------------------------------
/up & going/foreword.md:
--------------------------------------------------------------------------------
1 | # You Don't Know JS: Up & Going
2 | # Foreword
3 |
4 | What was the last new thing you learned?
5 |
6 | Perhaps it was a foreign language, like Italian or German. Or maybe it was a graphics editor, like Photoshop. Or a cooking technique or woodworking or an exercise routine. I want you to remember that feeling when you finally got it: the lightbulb moment. When things went from blurry to crystal clear, as you mastered the table saw or understood the difference between masculine and feminine nouns in French. How did it feel? Pretty amazing, right?
7 |
8 | Now I want you to travel back a little bit further in your memory to right before you learned your new skill. How did *that* feel? Probably slightly intimidating and maybe a little bit frustrating, right? At one point, we all did not know the things that we know now and that’s totally OK; we all start somewhere. Learning new material is an exciting adventure, especially if you are looking to learn the subject efficiently.
9 |
10 | I teach a lot of beginner coding classes. The students who take my classes have often tried teaching themselves subjects like HTML or JavaScript by reading blog posts or copying and pasting code, but they haven’t been able to truly master the material that will allow them to code their desired outcome. And because they don’t truly grasp the ins and outs of certain coding topics, they can’t write powerful code or debug their own work, as they don’t really understand what is happening.
11 |
12 | I always believe in teaching my classes the proper way, meaning I teach web standards, semantic markup, well-commented code, and other best practices. I cover the subject in a thorough manner to explain the hows and whys, without just tossing out code to copy and paste. When you strive to comprehend your code, you create better work and become better at what you do. The code isn’t just your *job* anymore, it’s your *craft*. This is why I love *Up & Going*. Kyle takes us on a deep dive through syntax and terminology to give a great introduction to JavaScript without cutting corners. This book doesn’t skim over the surface, but really allows us to genuinely understand the concepts we will be writing.
13 |
14 | Because it’s not enough to be able to duplicate jQuery snippets into your website, the same way it’s not enough to learn how to open, close, and save a document in Photoshop. Sure, once I learn a few basics about the program I could create and share a design I made. But without legitimately knowing the tools and what is behind them, how can I define a grid, or craft a legible type system, or optimize graphics for web use. The same goes for JavaScript. Without knowing how loops work, or how to define variables, or what scope is, we won’t be writing the best code we can. We don’t want to settle for anything less -- this is, after all, our craft.
15 |
16 | The more you are exposed to JavaScript, the clearer it becomes. Words like closures, objects, and methods might seem out of reach to you now, but this book will help those terms come into clarity. I want you to keep those two feelings of before and after you learn something in mind as you begin this book. It might seem daunting, but you’ve picked up this book because you are starting an awesome journey to hone your knowledge. *Up & Going* is the start of our path to understanding programming. Enjoy the lightbulb moments!
17 |
18 | Jenn Lukas
19 | [jennlukas.com](http://jennlukas.com/), [@jennlukas](https://twitter.com/jennlukas)
20 | Front-end consultant
21 |
--------------------------------------------------------------------------------
/up & going/toc.md:
--------------------------------------------------------------------------------
1 | # You Don't Know JS: Up & Going
2 |
3 | ## Table of Contents
4 |
5 | * Foreword
6 | * Preface
7 | * Chapter 1: Into Programming
8 | * Code
9 | * Try It Yourself
10 | * Operators
11 | * Values & Types
12 | * Code Comments
13 | * Variables
14 | * Blocks
15 | * Conditionals
16 | * Loops
17 | * Functions
18 | * Practice
19 | * Chapter 2: Into JavaScript
20 | * Values & Types
21 | * Variables
22 | * Conditionals
23 | * Strict Mode
24 | * Functions As Values
25 | * `this` Keyword
26 | * Prototypes
27 | * Old & New
28 | * Non-JavaScript
29 | * Chapter 3: Into YDKJS
30 | * Scope & Closures
31 | * this & Object Prototypes
32 | * Types & Grammar
33 | * Async & Performance
34 | * ES6 & Beyond
35 | * Appendix A: Acknowledgments
36 |
--------------------------------------------------------------------------------