This is, in my opinion, the book to use to learn JavaScript at more than a surface level. The only other materials I recommend as much (but for a different level of learner) are the “You don’t know JavaScript” in-depth book series.
In 2015, I was consulting for a distance learning program, administered by a major California University, that wanted to replace their current textbook (one of those “Head First” O’Reilly books) with something that had a bit more meat but was very approachable. I immediately recommended this and it was fawned over by both the advisors and instructors. It was also the cheapest option they had in the running (even excluding the fact it can be read for free) as it was competing against traditional text books. One year later, students were polled on it and it was met with a lot of positivity as well.
One hundred percent agree on both this book and the “You don’t know JavaScript”. Both are free (search Kyle Simpson GitHub). I ended up buying the YDKJ first edition paperbacks but see the second edition of all of them are done or a work in progress. EJs is the one I tell my students to start with as IMO is more of a programming book that just happens to us JS. I can tell the ones that read it (it’s optional) and the ones that do not. I do a few random chapters every year and learn something that I either missed or forgot I knew every time. I am mostly using TS these days but also enjoy vanilla JS for side projects and prototypes. Note the YDKJ books can come off as very ‘only my opinion is the right one’ kind of like JS the good parts but just look past that and absorb the content, what you do with it after that is up to you regardless of the author’s opinion.
I remember reading the first edition back in maybe 2011 when I decided I should sit down and actually learn JavaScript beyond the superficial grasp I had of it from working on web things (mainly via Rails at the time). What a great book, I learned so much from it at the time. For years after, whenever anyone told me they wanted to learn programming, I told them to pick up this book as a first introduction to it. Plus, it was available for free on his website.
I've gotten rid of lots of old programming books over the years, but I've held on to my first edition copy of Eloquent Javascript. Lots of thanks to Marijn for writing this!
+1 for "You don't know js", it's a must read for any js programmer IMO.
I haven't read eloquent JS though, you say it's a different level of learner. Can you expand a bit? Is Eloquent for after "you don't know js" or vice-versa?
Edit: nevermind, reading the TOC of eloquent JS gave me a good enough idea
Thank you for mentioning YDKJS. I hadn’t heard of it before and am in the beginning of my first proper JS project for about 10 years; man has the JS world changed. I have already skimmed the first few chapters and am already understanding it all very concisely. I will be reading this properly via GitHub for sure.
If I put "You don’t know JavaScript" into Amazon I get approx 10 books at £20 each, is there a specific one / author I should look for, of even better and ISBN. Thanks!
Fancy seeing this here, some days after finishing the third version :)
I'm also glad to see the asynchronous programming chapter significantly reworked - it was materially weaker than the rest of the book because of some weird analogies involving crows and their nests that didn't seem to make any sort of sense to me.
The third edition also gave me the impression that it was a reasonable book to learn JS and the DOM (and a sprinkle of Node.js, for good measure), but that it was a book aimed primarily at experienced people who were transitioning to JS and the web - not beginners (despite the book's efforts at claiming suitability for beginner programmers).
I don't consider myself a good programmer. I struggled throughout my youth to grasp even the basics. This book pointed me in the right direction. Can't recommend it enough.
My go-to JavaScript book will always remain “JavaScript for impatient programmers”[1], a 639-page book written by Dr. Axel, PhD.
It's quite complete and detailed. But as if it wasn't enough the author wrote a second (smaller book) named “Deep JavaScript: Theory and techniques”[2].
Part of the force of this book comes from its explanation of fundamentals of computing, and how it relates to javascript. Another part is due to how interesting are the projects that it proposes that the reader build. I don't even like programming in javascript but was drawn to read the book.
I love this book, even since its first edition. It's very clear even on elementary stuff, e.g. see the section on bindings/variables: https://eloquentjavascript.net/02_program_structure.html#h-l... — avoids the pitfall of thinking of variables as “boxes”.
When I was just starting out I read this book and noticed a small mistake, I was really proud that one of my first contributions to any open source project was a PR to this repo.
Looks as if there will still be a paperback version released in the future as well for anyone that prefers that format.
I don't work in JS at all professionally but this book has intrigued me for a while at this point after seeing it recommended so often. I think I'll pick up a copy once the paperback is released.
It's a great explanation, but I've never heard the term 'binding' used to describe variables. It's usually reserved to function binding or bridge APIs like the DOM.
The tricky thing is that "boxes" are the right abstraction for primitive values. After that you need to explain how references work, and that's pretty much the same 'tentacle' concept. This method spares the reader one step, but might cause confusion once they face problems that require that understanding.
I'm currently going through a hard copy of the book's third edition. But I'm wondering whether the description of the language in the book is detailed enough. Could you share some opinions on whether it will be good to go through some other JavaScript books after it? I'm considering going through "JavaScript: The Definitive Guide"[1] or "The Modern JavaScript Tutorial"[2] after it.
"JavaScript: The Definitive Guide" does go deeper, with thorough examples in all the topics mentioned in the index. It also provides examples of static types using Flow instead of TypeScript.
>The field of programming is young and still developing rapidly, and it is varied enough to have room for wildly different approaches.
This was an interesting line of thought to digest. He's right, of course. Programming is probably still in it's infancy.
Studying and learning about programming however, can make you believe it's some ancient art mastered by the giants of our recent past, the perfection of which is never to be surpassed again.
The one odd thing in it is that it still claims SVG markup needs a namespace. Which it doesn't, SVG became part of the HTML5 spec and emphatically should _not_ use namespaces when used as "just another element" inside an HTML document.
(even though you do need a namespace when creating svg elements through createElementNS, both "of course" and "unfortunately", and of course you need namespaces if you're creating an actual stand-alone SVG document)
Like that this now includes a chapter on Node. I think it would be nice to see a follow-up book in a similar style that covers a bit more with Node, Deno and Bun.
I really like the Deno approach so far. I prefer TS mostly these days as well as the esm stroke modules. I think node just made usage harder in their approach. I understand why, I still disagree on the solution.
Seconding the sentiment on this thread, I used this book to learn JS 5 years ago, and it's awesome. I've never seen another resource as good. YDKJS is more of an advanced treatment. If you're a beginner it feels academic, while Eloquent JS is very practical and approachable.
> Every now and then, someone comes up with a new way to circumvent the limitations of a browser and do something harmful, ranging from leaking minor private information to taking over the whole machine that the browser runs on. The browser developers respond by fixing the hole, and all is well again—until the next problem is discovered, and hopefully publicized, rather than secretly exploited by some government agency or criminal organisation.
This is from the chapter on HTML and JS (emphasis mine). It is funny to see how govt agencies and criminal organisations are mentioned in the same breath. How did we end up here?
I have Zakas' Professional JavaScript for Web Developers and ECMAS 6 update. Was very happy with them (easy to read) but both are getting long in the tooth and the author seems to have lost interest in updates.
How does this one compare as an all-in-one? Being up to date is a win, but I'm wondering about the quality of the writing.
I don't mean to throw shade on the whole book, but I don't think the section on errors takes things in the right direction.
A distinction should be made between errors and exceptions. In JavaScript and many languages, we conflate the two and use exception handling as logic flow control. In my experience, this can end up being a headache and encourage unnecessarily weird structuring of code.
Look at this example from the page on errors:
---
function getAccount() {
let accountName = prompt("Enter an account name");
if (!Object.hasOwn(accounts, accountName)) {
throw new Error(`No such account: ${accountName}`);
}
return accountName;
}
---
The possibility that a user will enter a account name that doesn't exist is not an exception, but we are treating it like one in this case. In order to handle this exception when getAccount is called, we have to wrap it or some higher level scope in a try-block and then regex-match the error message if we want to handle it differently from other errors.
You might be saying "it's just an example", but there's plenty of production code in the wild that is written this way. Maybe this could be improved by subclassing Error, but now you're having to manage a bunch of clutter and using object-oriented features as a way to reliably determine what kind of exception you're dealing with.
I find this pattern to be preferable:
---
const ACCOUNT_NOT_FOUND_ERROR_CODE = 1;
function getAccount() {
let accountName = prompt("Enter an account name");
if (!Object.hasOwn(accounts, accountName)) {
return {
accountName: null,
error: {
code: ACCOUNT_NOT_FOUND_ERROR_CODE,
message: `No such account: ${accountName}`,
}
};
}
return { accountName, error: null };
}
---
Then we can call the function like this:
---
const { accountName, error } = getAccount();
if (error) {
if (error.code === ACCOUNT_NOT_FOUND_ERROR_CODE) {
errorModalService.show(error.message);
}
} else {
// do something with the account name
}
---
No doubt, you may still want to catch exceptions at a higher level scope, but at the nice thing here is that exceptions (almost) always represent actual unexpected conditions that aren't being handled properly while return values with error codes represent expected conditions and can be handled like any other logic in your code. It also reduces any ambiguity of how an error should be handled but without subclassing. An error can even contain more information than just a message if you want it to.
Also, if you really want to ignore an error for some reason, then you can just pretend that the error doesn't exist. No need to use a try-catch where the catch-block is a no-op.
I wish we'd encourage this sort of pattern, but maybe that's one of many pipe dreams of mine.
In other languages like Java this can work because of checked exceptions (can work, I know there are a lot of mediocre devs who don't know what to do with checked exceptions but that's another issue). But in JS this is a terrible way to deal with any problem that can be handled.
I'd agree, but incidentally I've also been extracting string labels into some higher level, such as a constant or message creator function that looks up the message by it's code in some dictionary. It helps with readability, particularly in modern view libraries, to just have all your labels in one place and not have to scan the JSX or HTML for the string literals, and likewise all modifications will produce more concise diffs, testing could be easier if you're doing string matching, localization is more manageable with fewer scattered external dependencies on translation hooks or w/e
1. Exceptions can have codes, too, you know, and often do.
2. In the example, the exception is meant to bubble up all the way to the consumer. Different consumers can then handle as they see fit, even just displaying the exception message to the user.
Any suggestions from the community on the best way to consume this site as an audio book? I know I could scrape and feed into a text-to-speech library but was wondering: is there is anything off-the-shelf?
[+] [-] samtho|2 years ago|reply
In 2015, I was consulting for a distance learning program, administered by a major California University, that wanted to replace their current textbook (one of those “Head First” O’Reilly books) with something that had a bit more meat but was very approachable. I immediately recommended this and it was fawned over by both the advisors and instructors. It was also the cheapest option they had in the running (even excluding the fact it can be read for free) as it was competing against traditional text books. One year later, students were polled on it and it was met with a lot of positivity as well.
[+] [-] Sn0wCoder|2 years ago|reply
[+] [-] mtalantikite|2 years ago|reply
I've gotten rid of lots of old programming books over the years, but I've held on to my first edition copy of Eloquent Javascript. Lots of thanks to Marijn for writing this!
[+] [-] redbell|2 years ago|reply
[+] [-] kabes|2 years ago|reply
I haven't read eloquent JS though, you say it's a different level of learner. Can you expand a bit? Is Eloquent for after "you don't know js" or vice-versa?
Edit: nevermind, reading the TOC of eloquent JS gave me a good enough idea
[+] [-] m4tthumphrey|2 years ago|reply
[+] [-] memonkey|2 years ago|reply
[+] [-] pwb25|2 years ago|reply
[+] [-] idk1|2 years ago|reply
[+] [-] fourside|2 years ago|reply
[deleted]
[+] [-] wes-k|2 years ago|reply
https://codemirror.net/
https://prosemirror.net/
[+] [-] felideon|2 years ago|reply
[+] [-] jamager|2 years ago|reply
[+] [-] NlightNFotis|2 years ago|reply
I'm also glad to see the asynchronous programming chapter significantly reworked - it was materially weaker than the rest of the book because of some weird analogies involving crows and their nests that didn't seem to make any sort of sense to me.
The third edition also gave me the impression that it was a reasonable book to learn JS and the DOM (and a sprinkle of Node.js, for good measure), but that it was a book aimed primarily at experienced people who were transitioning to JS and the web - not beginners (despite the book's efforts at claiming suitability for beginner programmers).
[+] [-] Jerrrry|2 years ago|reply
I am glad I am not the only one. I believe he over-abstracted it to it's own detriment.
I went to purchase a paperback earlier this week. Now I will wait for this one to hit print.
[+] [-] m1keil|2 years ago|reply
[+] [-] aydoubleyou|2 years ago|reply
[+] [-] culopatin|2 years ago|reply
[+] [-] noname120|2 years ago|reply
It's quite complete and detailed. But as if it wasn't enough the author wrote a second (smaller book) named “Deep JavaScript: Theory and techniques”[2].
Both are free to read online!
[1] https://exploringjs.com/impatient-js/
[2] https://exploringjs.com/deep-js/index.html
[+] [-] felipefar|2 years ago|reply
[+] [-] svat|2 years ago|reply
I was trying to find what's new in the 4th edition, and following links from the author's website https://marijnhaverbeke.nl/ found this on Mastodon (https://mastodon.social/@marijn/112020092273623390):
> The FOURTH EDITION of Eloquent JavaScript is now online, adjusted to the realities of 2024 and generally touched up.
[+] [-] arrowleaf|2 years ago|reply
When I was just starting out I read this book and noticed a small mistake, I was really proud that one of my first contributions to any open source project was a PR to this repo.
[+] [-] DenverSWE|2 years ago|reply
I don't work in JS at all professionally but this book has intrigued me for a while at this point after seeing it recommended so often. I think I'll pick up a copy once the paperback is released.
[+] [-] ricardobeat|2 years ago|reply
The tricky thing is that "boxes" are the right abstraction for primitive values. After that you need to explain how references work, and that's pretty much the same 'tentacle' concept. This method spares the reader one step, but might cause confusion once they face problems that require that understanding.
[+] [-] MikeTheGreat|2 years ago|reply
[+] [-] shippintoboston|2 years ago|reply
[deleted]
[+] [-] jmkni|2 years ago|reply
[+] [-] ibobev|2 years ago|reply
[1] https://www.amazon.com/JavaScript-Definitive-Most-Used-Progr...
[2] https://javascript.info/
[+] [-] XeO3|2 years ago|reply
[+] [-] veggieWHITES|2 years ago|reply
This was an interesting line of thought to digest. He's right, of course. Programming is probably still in it's infancy.
Studying and learning about programming however, can make you believe it's some ancient art mastered by the giants of our recent past, the perfection of which is never to be surpassed again.
[+] [-] TheRealPomax|2 years ago|reply
(even though you do need a namespace when creating svg elements through createElementNS, both "of course" and "unfortunately", and of course you need namespaces if you're creating an actual stand-alone SVG document)
[+] [-] tracker1|2 years ago|reply
I really like the Deno approach so far. I prefer TS mostly these days as well as the esm stroke modules. I think node just made usage harder in their approach. I understand why, I still disagree on the solution.
[+] [-] gassiss|2 years ago|reply
[+] [-] richrichie|2 years ago|reply
This is from the chapter on HTML and JS (emphasis mine). It is funny to see how govt agencies and criminal organisations are mentioned in the same breath. How did we end up here?
[+] [-] greenie_beans|2 years ago|reply
[+] [-] begueradj|2 years ago|reply
[+] [-] mixmastamyk|2 years ago|reply
How does this one compare as an all-in-one? Being up to date is a win, but I'm wondering about the quality of the writing.
[+] [-] ravenstine|2 years ago|reply
A distinction should be made between errors and exceptions. In JavaScript and many languages, we conflate the two and use exception handling as logic flow control. In my experience, this can end up being a headache and encourage unnecessarily weird structuring of code.
Look at this example from the page on errors:
---
function getAccount() {
}---
The possibility that a user will enter a account name that doesn't exist is not an exception, but we are treating it like one in this case. In order to handle this exception when getAccount is called, we have to wrap it or some higher level scope in a try-block and then regex-match the error message if we want to handle it differently from other errors.
You might be saying "it's just an example", but there's plenty of production code in the wild that is written this way. Maybe this could be improved by subclassing Error, but now you're having to manage a bunch of clutter and using object-oriented features as a way to reliably determine what kind of exception you're dealing with.
I find this pattern to be preferable:
---
const ACCOUNT_NOT_FOUND_ERROR_CODE = 1;
function getAccount() {
}---
Then we can call the function like this:
---
const { accountName, error } = getAccount();
if (error) {
} else { }---
No doubt, you may still want to catch exceptions at a higher level scope, but at the nice thing here is that exceptions (almost) always represent actual unexpected conditions that aren't being handled properly while return values with error codes represent expected conditions and can be handled like any other logic in your code. It also reduces any ambiguity of how an error should be handled but without subclassing. An error can even contain more information than just a message if you want it to.
Also, if you really want to ignore an error for some reason, then you can just pretend that the error doesn't exist. No need to use a try-catch where the catch-block is a no-op.
I wish we'd encourage this sort of pattern, but maybe that's one of many pipe dreams of mine.
[+] [-] svachalek|2 years ago|reply
[+] [-] brailsafe|2 years ago|reply
[+] [-] Exoristos|2 years ago|reply
[+] [-] rofrol|2 years ago|reply
[+] [-] synergy20|2 years ago|reply
[+] [-] isquaredr|2 years ago|reply
[+] [-] jslakro|2 years ago|reply