How JavaScript Works
Sample Chapter
Douglas Crockford

  Chapter List  
Raindrops on roses and whiskers on kittens.
Not Maria Augusta von Trapp

[
    {"number":  0, "chapter": "Read Me First!"},
    {"number":  1, "chapter": "How Names Work"},
    {"number":  2, "chapter": "How Numbers Work"},
    {"number":  3, "chapter": "How Big Integers Work"},
    {"number":  4, "chapter": "How Big Floating Point Works"},
    {"number":  5, "chapter": "How Big Big Rationals Work"},
    {"number":  6, "chapter": "How Booleans Work"},
    {"number":  7, "chapter": "How Arrays Works"},
    {"number":  8, "chapter": "How Objects Work"},
    {"number":  9, "chapter": "How Strings Work"},
    {"number": 10, "chapter": "How The Bottom Values Work"},
    {"number": 11, "chapter": "How Statements Work"},
    {"number": 12, "chapter": "How Functions Work"},
    {"number": 13, "chapter": "How Generators Work"},
    {"number": 14, "chapter": "How Exceptions Work"},
    {"number": 15, "chapter": "How Programs Work"},
    {"number": 16, "chapter": "How this Works"},
    {"number": 17, "chapter": "How Classfree Works"},
    {"number": 18, "chapter": "How Tail Calls Work"},
    {"number": 19, "chapter": "How Purity Works"},
    {"number": 20, "chapter": "How Eventual Programming Works"},
    {"number": 21, "chapter": "How Date Works"},
    {"number": 22, "chapter": "How JSON Works"},
    {"number": 23, "chapter": "How Testing Works"},
    {"number": 24, "chapter": "How Optimization Works"},
    {"number": 25, "chapter": "How Transpiling Works"},
    {"number": 26, "chapter": "How Tokenizing Works"},
    {"number": 27, "chapter": "How Parsing Works"},
    {"number": 28, "chapter": "How Code Generation Works"},
    {"number": 29, "chapter": "How Runtimes Work"},
    {"number": 30, "chapter": "How Wat! Works"},
    {"number": 31, "chapter": "How This Book Works"}
]

0 Read Me First! ○○○○○
Few images invoke the mysteries and ultimate certainties of a sequence of random events as well as that of the proverbial monkey at a typewriter.
George Marsaglia

Java­Script is not very pretty, but it works.

This book is for people who have had some experience with Java­Script, and want to have a better, deeper understanding of how it works and how to use it well. It is also for experienced pro­gram­mers who are looking to understand the workings of another lan­guage.

This book is not for beginners. I hope to someday write a book for beginners. This is not that book. This is not a light book. If you skim it, you will likely get nothing from it.

This book is not about JavaScript engines or virtual machines. It is about the lan­guage itself and the things every pro­gram­mer should know about it. This book is a radical reappraisal of Java­Script, how it works, how it could be made better, and how it can be better used. It is about how to think about Java­Script and how to think in Java­Script. I am going to pretend that the current version of the lan­guage is the only version. I am not going to waste your time by showing how things worked in ES1 or ES3 or ES5. That does not matter. The focus is on how Java­Script works for us now.

This book is not comprehensive. There are large, complex chunks of the lan­guage that will be dismissed without a word. If I fail to mention your most favorite fea­ture, that is most likely because that fea­ture is crap. I will not be paying much attention to syntax. I am assuming that you already know how to write an if statement. If you need assistance with those sorts of details, ask JSLint. jslint.com

There are some useful parts of the lan­guage that I will spend little time on, such as most of the methods in the primordial prototypes. There are excellent online reference materials for that. My favorite resource is Mozilla Foundation.
developer.mozilla.org/en-US/docs/Web/JavaScript/Reference

An important goal in programming lan­guage design is to produce a clean, logical lan­guage that composes well and is free of weird corner cases. Java­Script came nowhere close to meeting that goal. It gets worse with each revision as more fea­tures are agglutinated. The lan­guage is full of weird corner and edge cases. This book illuminates only a few of those corners, just to show that there are monsters there. Stay away from the corners and edges. Do not go into the dark. Stay in the part of the lan­guage that is simple and clean. Everything you need to write good programs is there.

Ten years ago I wrote a cranky little pamphlet about Java­Script. The premise was unusual, that whilst Java­Script was obviously a mess, there was buried deep inside of it a very good lan­guage. By avoiding the bad parts, you could write good programs.

This was quite at odds with the opinion of some programming experts that mastery can only be demonstrated by exploiting all of a lan­guage’s fea­tures. They believed strongly, without any need of proof, that fea­tures exist for the demonstration of mastery, so there are no bad features.

That opinion still seems to dominate even though it is deeply wrong. True mastery is shown by writing good programs that are readable, maintainable, and free of error. If you ever feel the need to show off, try doing that. Being a humble pro­gram­mer, I am always looking at myself and my work, seeking to improve my skills. I have learned the hard way that optimizing for fea­ture exploitation is counterproductive.

This is my most powerful tool for improving a programming lan­guage:

If a fea­ture is sometimes useful and sometimes dangerous and if there is a better option then always use the better option.

So armed, I am always looking to make the lan­guage I use smaller and better, to avoid if I can the fea­tures that are more likely to create bugs. I am still refining my ideas about what is good practice and what is not. This book represents my latest thinking about Java­Script. I am able to write about Java­Script’s good parts only because Java­Script has good parts. Compared to a decade ago, I think less of the lan­guage is good, but I think that good part is better.

Java­Script has become the most important programming lan­guage in the world. That is at least partly my fault. Sorry. The issuing of new editions of the ECMAScript stan­dard has not repaired Java­Script’s deep problems, and sometimes creates new problems. A stan­dards committee has limited power to repair a lan­guage. They have almost limitless power to grow the lan­guage, increasing its complexity and weirdness. They also have the power to not make things worse, but where is the fun in that?

Aging programming languages suffer from a bad plastic surgery addiction. They are desperately injecting new features in the fevered hope of remaining popular, or at least fashionable. Feature bloat is as big and as deep of a problem as code bloat. I think that we should instead praise JavaScript’s inner beauty.

I also recommend that you get the ECMAScript stan­dard. It can be tough reading, but it is free. www.ecma-international.org/publications/standards/Ecma-262.htm

Reading the ECMAScript stan­dard literally changed my life. Like most people, I started writing Java­Script without first bothering to learn it well. I found the lan­guage to be faulty, confusing, and irritating. It wasn’t until I got around to reading the ECMAScript stan­dard for myself that I discovered JavaScript’s brilliance.

Heresy

This book about a programming lan­guage will make some people angry. I am a harbinger of the next paradigm, and that is threatening to the keepers of the old paradigm. I am used to this. I was attacked when I discovered that Java­Script has good parts, which turned out to be the first important discovery of the 21st century. I was attacked when I discovered JSON, which is now the world’s best loved data interchange format.

Communities form around shared beliefs, and communities can provide benefits to their members even when those beliefs are wrong. Communities can feel threatened when those beliefs are questioned. I am a heretic. I value the pursuit of truth over the benefits of community. That is offensive to some people.

I am just a pro­gram­mer who is trying to figure out the best way to write programs. I might be wrong, but I am working really hard to get it right. Many of the patterns of thought in our profession were cemented in the FORTRAN era. I think it is time that we move beyond that. Change is hard, even in the most innovative of professions.

If you are offended by heresy, then put this book back on the shelf and walk away.

Code

All of the code in this book is in the Public Domain. You are free to use it for any purpose, but please do not use it for evil. Try to do some good with it if that is at all possible.

I strongly recommend that you do not copy and paste code that you do not understand, even mine. This seems to have become a stan­dard practice, but it is dangerous and reckless. It is not nearly as stupid as installing packages that you haven’t even looked at, but it is still really bad. Given the current state of the art, the most important security filter is your brain. Use it. This is important.

I make no claim that the programs presented in this book are perfect. I do claim that the programs I am writing now are better than what I was writing ten years ago. I work hard at trying to get better at this. I am hoping that I live long enough to finally get it right. I hope that you do, too. In the meantime, erratums for this book can be found at the book’s website. In Latin, the plural of erratum is errata as is done with second declension neuter nouns in the nominative case. But I am writing in Modern English, and in Modern English we should be forming plural nouns by appending -s, or in cases of excess sibilance, -es. So, yes, erratums. Given a choice between progress and tradition, I am going with progress informed by the lessons of history. That is how things are made better. howjavascriptworks.com/erratums

Please report my many blunders to erratum@howjavascriptworks.com.

Next

This book is about Java­Script, but I sometimes talk about The Next Lan­guage, the lan­guage that will replace Java­Script. I have to believe that there will be a lan­guage after Java­Script, because if Java­Script is the last lan­guage, that would be really sad. We must find a way to the next lan­guage, if only for our kids. They deserve a better legacy than Java­Script.

I believe that children are our future. And also robots.

The next paradigm will be globally distributed, secure, eventual programming. The Internet demands this. Nearly all of our current programming lan­guages, including Java­Script, are still firmly rooted in the old paradigm of local, insecure, sequential pro­gram­ming. I see Java­Script as a transitional lan­guage. Adop­tion of the best practices in Java­Script will be good preparation for understanding the next paradigm.

English

The word for 1 is misspelled. I use the corrected spelling wun. The pronunciation of one does not conform to any of the stan­dard or special rules of English pronunciation. And having the word for 1 start with the letter that looks like 0 is a bug.

The spelling of wun is unfamiliar to you so it might feel wrong. I am doing this intentionally to give you practice with the idea that a bad feeling about something unfamiliar is not proof that it is wrong.

This is how spelling reform happens. For example, some cat decides that it really would be better if through were spelled thru because it does not make sense that half of the letters in a popular word be silent, being wildly inefficient and putting an unnecessary burden on students of the lan­guage. Spelling reform is a struggle between tradition and reason, and sometimes, reason wins. I feel the same way about programming lan­guages. So if wun makes more sense to you than one, then please join me in the effort.

When normal people talk about ranges, like 1 to 10, the range is understood to end with 10. But pro­gram­mers often mean to to exclude the 10. This confusion is due to the common programming practice of numbering from 0 instead of 1. So I use to to mean what pro­gram­mers usually mean by to, and thru to mean what normal people mean by to. So 0 to 3 mean the range including 0 1 2 whilst 0 thru 3 mean the range including 0 1 2 3. To implies <less than and thru implies <=less than or equal.

And whilst on the subject of whilst, in this book about programming, while is used for discussion of iteration. When discussing concurrency or simultaneity I use whilst which I take to mean while at the same time.

Both cannot and can not are accept­able spellings, but cannot is much more popular. Hasnot is not accept­able whilst has not is. And willnot is not accept­able whilst will not is. That is why I can not use cannot. But if I am in a great hurry, I can still can’t.

To my many friends for whom English is not your first lan­guage: Welcome. Thank you for reading my book. Perhaps unfairly, English has become the lan­guage of the Internet and of Software Development. Your ability to read the primary docu­ment­ation directly is an important and valuable skill. I deeply respect that.

Examples

I use regular expressions. Unfortunately, regular expressions are extremely cryptic and confusing. I will attempt to mitigate that a bit by pumping lots of whitespace into them. Java­Script does not allow that whitespace, so when you see

const number_pattern = /
    ^
    ( -? \d+ )
    (?: \. ( \d* ) )?
    (?:
        [ e E ]
        ( [ + \- ]? \d+ )
    )?
    $
/;

be aware that it should be written all smushed together as

const number_pattern = /^(-?\d+)(?:\.(\d*))?(?:[eE]([+\-]?\d+))?$/;

I do not want to subject you to such unprintable ugliness, so I insert the whitespace.

In many of the chapters I will show examples of Java­Script expressions. I do that by using a special expression statement that ends not with a ;semicolon but instead with //slash slash followed by the result of the expression.

// An example of examples

3 + 4 === 7                                                 // true
NaN === NaN                                                 // false
typeof NaN                                                  // "number"
typeof null                                                 // "object"
0.1 + 0.2 === 0.3                                           // false
3472073 ** 7 + 4627011 ** 7 === 4710868 ** 7                // true

Before the end, all will be explained.