Hacker News new | past | comments | ask | show | jobs | submit login
A Modern JavaScript Tutorial (javascript.info)
893 points by ivanche on Dec 7, 2020 | hide | past | favorite | 292 comments



This site is absolutely awesome and I would suggest this to new comers and experienced folks alike. It covers all things related to javascript, explains the concepts really well in a practical day to day application point of view.

I might be sounding like a promoter for it, but it really added a lot of value for me personally, so just wanted to spread the good word.


I just wish it didn't have Disqus :(


What's wrong with Disqus? Seems relatively benign among things that people might be tempted to force upon the people who use their site.


The addon Privacy Badger blocks it by default.


I'm surprised I haven't seen this before - it's been under very active development since 2015 and has 11,000+ stars on GitHub: https://github.com/javascript-tutorial/en.javascript.info/gr...


Even more surprising, it's been submitted umpteen times before:

https://news.ycombinator.com/from?site=javascript.info

I sometimes wonder what are the dynamics that trigger the snowball on HN.


I think time of day, novelty, luck, and whether any mods notice the post and decide to give it a second wind.

By novelty I mean something that is easily recognized as new and important. It doesn’t help that something is new if no one catches the point of reading about it. Could be a bad title or a bad article. Or bad luck.

In terms of good luck I mean a couple of specific things especially:

- If a few people see it that are excited about it, either from hearing about it the first time or from knowing it in the past, and these people write positive comments about it, then others who come across the post may be encouraged to check it out and to upvote it too.

- “Micro zeitgeist”. If it’s about a topic that recently hit the front page and it adds something new about that, it could luck out. Why luck in this case? Because you probably don’t know ahead of submitting that people will care to read even more about some topic even if it was popular the day before. Perhaps instead people are tired of the topic.

- The other things submitted the same day did not gain enough traction to push this thing away.

- Evergreen topics that have not gotten traction in a while but that people care about.

- Topics that people in university and college are currently learning about so it catches their attention. I dunno how big the amount of people currently in university is versus people that are in jobs. But I remember that I learned about HN from some other students in a student union I was in back then. And I don’t know how students HN reading habits are compared to people in jobs either. I remember reading HN a lot when at the university. But I still read HN a lot. These days I read HN in the morning, the evening and at night though, not when I am working. But even if you have a job you might read HN in the lunch break, or perhaps you have some downtime where you are waiting for something at work and you read HN for a while.

There are other possible factors too that I have thought about in the past but these are the ones I can think of right now.

Please note that all of what I am saying here is only my thoughts based on my own habits and from what I’ve heard other people say and what I’ve seen.


To agree with and concretise what your saying - I think (without actually somehow checking) my most popular submissions have all been something that I was led to by another thing(s) I was reading on HN at the time.

Whether conscious or not (probably mostly conscious) I think they simply had the same temporal relevance for other people as they did for me.

All that said, I don't know what it would be in this case. I expect I'll find it useful though, being not really a JS person who does need to write some JS and would rather maintain decent JS than awful.

What it seems to lack, which I find a sticking point whenever I consider some greenfield personal project, is the dizzying array of 'tooling stuff' that JS has, and how it does or doesn't fit together, etc. There's just all sorts of weird layers and not quite equivalents and can be equivalents but could also be used togethers, half the stuff it's not even clear what it is or if it's necessary at all.

I really hope wasm brings more different options (hard to phrase that to not sound hypocritical!) one day; that we just have some tiny JS shim that everyone uses, and other than that it's totally arbitrary which language and ecosystem you use, JS an option, but no more obvious than anything else.


> What it seems to lack, which I find a sticking point whenever I consider some greenfield personal project, is the dizzying array of 'tooling stuff' that JS has, and how it does or doesn't fit together, etc. There's just all sorts of weird layers and not quite equivalents and can be equivalents but could also be used togethers, half the stuff it's not even clear what it is or if it's necessary at all.

Aha, yes, this. I am [currently] a JavaScript person and it is a shitshow. The cliché used to point and laugh at JS is framework churn, but that's not really much of a thing [imo], it's the tooling. The tools can be genuinely very good if you pick the right combination in the right context, but that's often more luck than judgement.

I suspect as wasm usage becomes more widespread, it'll get worse, not better, at least for a while. There's always a shining future to hope for (and despite the gripes, things have generally improved steadily over the years, so not too idealistic a hope).

If Rome[1] fulfils its goals (big if), then you might get what you want. Very early days though, and going to be very hard for the maintainers to keep control as the scope of the project expands.

Aside, but I think it would be interesting to figure out how much cargo culting is going on with JS tooling. Theory: most configurations of tooling beyond "install CRA/similar" are built up via Googling done when building out highly context-specific configs -> that brings back articles on how to set up tooling that was specific to the author's particular situation -> they are used in lieu of the tool's documentation because Things Just Need To Get Done Now and it's just some dev dependencies, whatever -> those configs are used in a situation they aren't needed -> process repeats.

[1] https://rome.tools/


Rome just sounds like XKCD standards.

It starts off by giving installation instructions for yarn/npm/npx. Which should I use if I'm starting a project and I heard on HN Rome is the easy one true way to do it? I don't already have yarn or npm or npx so there's no existing reason to care, but now I feel I need to find out about them and their potential tradeoffs since it's probably easier to choose now than change later.

And then you get past that and want to use LSP with your editor, and realise it's not one tool to rule them all after all anyway!


I get the analogy, but build/lint/format functionalities are currently split across multiple different tools and their many multiple plugins. They aren't standards, they're just a bunch of tools that people have to glue together every time they create a new project. Attempting to put them together into a single binary with no dependencies isn't creating another standard, it's just creating a single tool (one similar to those extant for other modern languages).

I realise you may be being slightly facetious to make a [fair] point, but if not: Yarn and NPM are package managers, NPM comes with Node. npx is a command line tool for npm that generally obseletes most need for globally installing packages, it is a small but nice nice recent improvement to the JS ecosystem.

LSP is a protocol implemented by plugins for text editors/IDEs, it's got nothing to do with a specific language, what do you mean by mentioning that?


Yarn and npm I'm familiar with, though I don't know why to prefer one over the other. Yarn's newer, I suppose that's pro or con depending who you talk to. Npx I had no idea.

LSP has two parts, a client implented by an editor (or plugin for one), and a server for whichever specific language.

If you always use vim but several languages, you need one language client for vim, and a language server for, yes, each specific language you want to write with it. `vls` for example for vue/js/etc. distributed with `vetur` which is God knows what also distributing God knows what else, and the rabbit hole continues. :)

(And your language server might be the only linter and formatter you need/want, so they're then wasted being in Rome, is what made me think of it.)


> Yarn and npm I'm familiar with, though I don't know why to prefer one over the other. Yarn's newer, I suppose that's pro or con depending who you talk to

So Yarn was created to deal with issues in NPM (amongst other things: speed, problems with package duplication, no lockfile). AFAICS from watching Ryan Dahl talking about the process of his developing Node, NPM was kind of an afterthought, so it has some flaws that are difficult to fix because they're so ingrained into how Node works.

So Yarn [v1] has a very similar API, and uses the NPM registry, and works in a very similar way (dependencies go in node_modules, etc etc). Most of the time, when you see the choice, the author of the documentation is talking about NPM vs. Yarn v1.

Competition from Yarn [v1] was a generally good thing despite the slight confusion it causes, because what it did was force NPM to update to include some of Yarn's better features, in an attempt to gain feature parity.

The existence of Yarn v2 is also now [imo] important because of its two main features that differentiate it from NPM. Its API is basically the same as NPM, but the way it works is not, and yes, it's confusing. It works (and works very well), but I think its core value (and the reason why IMO it should be pushed alongside NPM despite the confusion that is likely to cause) is that it's acting as a testbed for features that are probably useful to the JS ecosystem. And the wider the usage, the more those features can be battle tested:

- it has full support for monorepos (storing all code for all associated projects in a single repo) which can make development easier in what would seem to be a large set of contexts.

- it allows a user to dispense with node_modules through a mechanism called plug and play. Dependency management is much better than NPM, issues with dependencies are easier to locate, and unless there are new deps added, there is no install step after the initial one (I can push my code to a repo, someone can clone the repo and just start the application immediately). This IME has fairly significant DX benefits, as well as making CI tasks take significantly less time and resource.


This is not a tutorial [1]. It's more like a guide [2].

[1]: https://documentation.divio.com/tutorials/

[2]: https://documentation.divio.com/how-to-guides/

Edit: I don't mention this to be nitpicky. I mention it because I wish that we would collectively start standardizing those terms. I think it would be helpful if, whenever we saw "… guide" or "… tutorial" we had a general idea about the structure and purpose of the contents. The Divio links above do a great job at explaining each doc type. I'm simply sharing this idea for people who have never considered being more careful about how they label their docs and would like to start following general technical writing community practices. As a practicing technical writer I can tell you that the TW community mostly agrees upon what each doc type entails ("tutorials" and "references" have strong consensus; "guides" less so).


I looked at those links. Here's what I got from them:

1. Tutorials "are lessons that take the reader by the hand through a series of steps." They "are oriented towards learning how."

2. How-to guides "take the reader through steps."

3. "How-to guides are wholly distinct from tutorials."

If I found a "community" around a topic, do I then get to decide what words mean? By consensus, of course.


You can see a good breakdown of what they mean by each label in this table:

https://documentation.divio.com/introduction/#the-secret

It's certainly a valuable take, even if you disagree with the claim that all 4 functions are required for good documentation.


What specifically are you referring to in that table? The original article is a lesson on how to use JavaScript, from scratch, for a beginner. That perfectly fulfills all four requirements in the "tutorial" column:

> oriented to: learning

> must: allow the newcomer to get started

> its form: a lesson

> analogy: teaching a small child how to cook

It does not satify all the requirements of any other column.


'And thirdly, the code is more what you'd call "guidelines" than actual rules.'


This is a tutorial. It almost fits the definition of "tutorial" at the link you posted, but not quite, but that's because the definition at the link you posted is a bit flawed. It definitely is not a how-to guide, and the links you posted strongly support that.

> How-to guides take the reader through the steps required to solve a real-world problem.

That is from the linked article on how-to guide. By "real-world problem" it means something specific you might want to do to a real code base, like "switch to a different database engine" or "add user authenticaion". That's why it includes the qualification "real-world". The original article definitely does not fall into that category.

> * A tutorial is what you decide a beginner needs to know.

> * A how-to guide is an answer to a question that only a user with some experience could even formulate.

That was some extra clarification from the linked article on the difference between tutorial and how-to guide. That makes it even more clear that the article is more like a tutorial than a how-to guide.

> Tutorials are lessons that take the reader by the hand through a series of steps to complete a project of some kind.

That's from the page about tutorials. The article introduces a reader to a substantial new topic from scratch and guides them through it, but it doesn't do so by making them complete a specific project, so it doesn't fit this definition.

But that doesn't stop it from being a "tutorial". The requirement that tutorials have to involve completing a sample project is invented by the author of that page and not part of the usual definition of that word.

This final point is pure conjecture, but I suspect the author of that page was just trying to strongly encourage people to base tutorials around sample projects. It's fair to encourage that, because often tutorials are improved by basing them around a single unifying project (but not always). But putting it in their definition of the word was a mistake, because that's not what that word means, and it's only created confusion.


Do you have a good JS tutorial for beginners that meets the definitions you are proposing to compare and contrast?


Remember when some people advocated not using semicolons to end statements? Good times...

https://javascript.info/structure


https://news.ycombinator.com/item?id=2024328

Here’s an example great bike shed discussion from ~10y ago about whether or not to use semicolons with JavaScript.

“If you don’t understand how statements in JavaScript are terminated, then you just don’t know JavaScript very well, and shouldn’t write JavaScript programs professionally without supervision, and you definitely should not tell anyone else how to write their JavaScript programs.”

Those were the fun days! :)


Something I always thought was interesting about that argument is how a similar line of reasoning could apply to the `==` and `===` comparison operators.

Just about anyone who's ever written JS probably knows about the heavy lean towards "always use `===`". And it's not without good reason, because there are more than handful of not-entirely-intuitive implicit coercions/comparison corners associated with `==`. Personally, I think it's OK to use it, but I understand that it requires knowing the rules associated with use and most of all comes with the overhead of keeping them in mind when you do so. Most of the time it will be OK if you know even most of the rules. Sometimes it will not be OK. More often the overhead will cost you attention to other things. Some people have made the call "wouldn't it be simpler if we just did strict comparison and saved our attention for other things?" and while it's not my first choice, I can understand and respect it.

The statement termination thing strikes me as pretty much the same. Sure, if you know the rules, you can do it freely. But it takes something explicit that you don't have to think about and turns it into something implicit that you do. It isn't going to be a problem most of the time, but sometimes it will not be OK. A little more often the overhead will cost you attention to other things. Following the rule that semicolons terminate statements hasn't ever cost me anything.

The weird thing in my experience was the frequent overlap between antisemicolonists and always===ists. My theory is that mostly these people came from Ruby and Python, liked less punctuation for subjective aesthetic reasons, and didn't actually know the coercion rules well or particularly like JS, but that's speculation.


“Explicit is better than implicit.”


Reminds me of a CS teacher for our intro Haskell course at university who would dock points for unnecessary use of parentheses, since he considered that it showed we didn't understand order of operations or how our program was parsed.


The programming language Occam, in its time the primary language to program Transputers, did not have operator precedence, so you had to use parentheses for anything. It was a huge pain, but probably still better than avoiding the edge cases of what you describe...

https://en.wikipedia.org/wiki/Occam_(programming_language)


That sounds like a bad professor. It doesn't cost anything to add parenthesis for clarity. I enjoy well written code but we're not writing literature here, it's okay to be explicit.


Yea it was very weird. I think most people realized that his way wasn't the right way.


I used to be on the "always use semicolons" side of this argument. Having shipped multiple projects using both methods my verdict is clear: It doesn't matter. Why it doesn't matter you ask? Because 1) I am enforcing either decision with eslint rules and 2) i write unit tests 3) code is transpiled (thus semicolons are handled perfectly at the output). Having these three in place, I have yet to encounter a single "gotcha" out of omitting semicolons.

If for any reason you absolutelly can't have these in place, better be safe and use semicolons.

Edit: for the "gotcha" explained in the link, prettier will automatically insert a semicolon before the array.


>I have yet to encounter a single "gotcha" out of omitting semicolons.

keyword "yet". It seems like such a insignificant win, with the downside being some very hard to debug runtime error because one element of your build chain has a bug or misses an edge case.

I honestly don't see the logic.


I explained the logic: By having tooling and tests it place, I am protected against gotchas and I haven't ever encountered a problem. Thus, i do not advocate you must ommit semicolons. I am saying "it doesn't matter what you do" provided you have the tooling in place. Do whatever feels best, what you like, what you feel comfortable with.

And here is the upside: I've minimized the time I spend arguing about this detail with my colleagues to 0s. Because it doesn't matter :)


It just makes the code slightly easier to read. The semicolon is just noise.


Semicolons aren't noise; you've read the statement before you even get to them so how can they be noise? Noise would be type info added to languages that didn't have it before, such as TypeScript. Generics can get pretty gnarley too, when you have nested typing info involved.


Noise as in new line already terminates. That’s one reason Python and Ruby code are cleaner to read.


I disagree that the semicolon is noise Thought the Javascript interpretter (usually) does not need it the semicolon is good for humans who read the code after you Sure it is possible to read the code without the semicolons with some practice but the semicolons are standard in many other related languages among them Java C++ PHP and MySQL Now you personally might not use those other languages very often but many of us especially those who occasionally wear a devops hat do And if the code is not meant to be read by humans also then why are we not writing in assembly


"It doesn't matter" really is the perfect summation of this.

We have tooling that can solve this to prevent pointless bike shedding.


Exactly. I almost always use TS instead of JS, for example, which flags gotcha scenarios (which I usually rewrite to avoid) and inserts semicolons for me in the final code. It’s just noise in my source.


I've run into that in a few places and it always baffles me that people would intentionally choose to add even more gotchas to javascript. Don't get me wrong, I think aesthetics in code are important but not to the point of deliberately increasing the chance of hard to find bugs.


Yeah...

There was a big push for that a while back. The JavaScript community can be silly.


I don't know whether I use them or not, to be honest (and I just finished a project in js). My code looks like whatever the almost-default (tab-width: 4) output of prettier is.

It's nice to not waste a single braincycle on these things anymore.


This. I just use an auto-formatter for the Standard style. If the Standard linter says it looks ok, it looks ok to me, and I move on with my day.


Debate over one character whose presence in code has no downside other than that a subset of programmers get to feel less arrogant. Sometimes I cannot stand this industry.


So what changed this? This was a hill that people were willing to die on.


I still don't use them :)


Isn’t step 1 of “modern JavaScript” to install TypeScript? :)


Amazing how many JS devs I meet (or work with) that are against the very idea of Typescript.


Because it fails to meet the 'it's the platform stupid' maxim.

ie languages aren't nearly quite so important as the platform.

Stuff wasn't written in js because early js was a brilliant language - it was because the platform - the web - was brilliant.

Many have written 'better' languages that compile to js - https://github.com/jashkenas/coffeescript/wiki/List-of-langu...

and while typescript is one of the better, more supported ones, isn't it just another one?

Surely in the end it just adds complexity and fragmentation of the ecosystem?


Hardly just another one, and hardly fragmenting. It’s absorbed the vast majority of effort previously dedicated to Flow (the fragment in its own target space), and has continually gained in the JS community proper. It’s not just (or intended to be) a “compile to JS” language, it’s (almost) just annotated JS where the annotations provide additional tooling value.

The resistance in the JS community isn’t to “yet another language”, it’s to the perceived complexity of TS strictness/appeasing the compiler. I’m saying this not based on polling so obviously take it with a grain of salt, but I routinely search Twitter, GitHub and rando blogs for TS content and that sentiment represents nearly 100% of the anti-TS content I encounter.

And largely I find that in React-focused communities. Which having spent the last several years using TS on Node in production, and the last couple months working on a web project in React, it’s not remotely surprising. React and many libraries built on it have ridiculously complex types. That’s not because of TS but interacting with and satisfying those types at compile time is extremely frustrating even to me as a seasoned TS dev who has built libraries that take advantage of many advanced features in the type system (I just don’t expose that complexity to the API consumer).


Front end library type definitions are a nightmare because they are usually retrofitted onto code that uses JavaScript idioms that take heavy advantage of metaprogramming and it's dynamic nature. It's also compounded (in my opinion) by developers that insist on making everything inferable instead of just putting a few generic parameters here and there and saving an enormous amount of complexities. Native typescript libraries are generally extremely easy to work with, however.


I think many JS developers are also somewhat blind to the breadth of types of sites that are written, and so don't understand how valuable a type system can be on the web.

Most websites are what I'd call "broad and shallow". For any individual action the corresponding code path is small. Most code in these sites is easy to write and easy to debug in vanilla JS. Typescript adds boilerplate and compiler times for type safety the development team was doing fine without.

However there are some sites, usually very complex SPAs, that are necessarily "deep". Even small user actions absolutely must cause >10k lines of code to run. Type systems are often very valuable for the development of such sites.

It's my experience that some developers who've only ever worked on "broad and shallow" sites fail to appreciate what a time saver a type system can be for the right "deep" website.


In before someone comments: "But chances are you are not the person who needs something as complicated as TS therefore it's useless." and "If your code is more than a thousand lines then you're doing it wrong, all code should be <1000 lines that you throw out immediately and replace with new code".


I'd guess I'd have to question why you need 10K lines of code for a single web page - perhaps you need to break up your SPA?


Because applications on the web are increasingly that -- full applications.

I create scientific models and simulations for use in schools. Whether it's simulating a hurricane, or continental drift, electronics, or molecular interactions, the simulations themselves need to run on the browser, and all the UI that provides the users with all the affordances to interact with the model needs to also be written in JS/TS.

I think your questions are just revealing a failure of imagination/experience for what kinds of applications run on the web these days.


Hmm - I think that's my point - it's no longer the web is it - just a way to deliver traditional applications.

I can see if you want to write an Excel in the web - that you might have a complex code base - but surely that's the exception - not the rule?

So back to the statement of 'modern web = ts'

Isn't that wrong - these applications aren't really web - and are the exception, not the norm?


> it's no longer the web is it - just a way to deliver traditional applications

This statement is meaningless to me. What makes it "no longer the web?"

"The web" now includes fully-fledged applications. It's fine to make a distinction between things that are full applications and things that are close to blogs, if you like, but it doesn't change the fact that many people develop full applications for the web.

And I think this is clearly a lot more common you are recognizing.


The fact you ask this question gets at my point I think.

For several years I've been writing a large computer algebra system(CAS) that runs on a webpage. Every time the user puts some input into a text box the CAS runs. Depending on the input it may run as many as ~40k lines of code. There are no coherent lines upon which to split the CAS as far as anyone developing it can tell.

The CAS must run on the browser both to deliver on real time performance requirements and to keep server costs manageable (certain inputs will get even high end CPUs humming).

If breaking this SPA up is possible, it's not apparent even to engineers with >10 years of experience developing highly complex applications.

Other similarly complex applications run on the web, even if it's unusual.


The trick is to not break it up. Adding more lose ends will just make the ball of twine more complicated. What you can break out though is independent code that is the same for many apps, that code can be made into a module and reused across apps. Pure mathematical functions can be turned into a library.

But what could probably help keep your sanity for a CAS is to add a test case for every change to make sure the same input produce the same output in the future. As well as performance tests to avoid performance regressions.


I totally agree, we do all of these things. It was just a little less clear early on in the project what the best structure for the project was :)


Do you think the Zoom web client should have fewer than 10k lines? Or be broken up? What about Google Docs?


Aren't those the exception and not the rule.

Hence the statement modern web = ts is wrong.

Personally I used the zoom native client and not the web one.

I spend most of my time in offline office and not the web version



I don't run windows 7 - so the zero day issue wouldn't have been a problem.

That's like saying don't use the web version cos your out of date browser can be exploited.


> Surely in the end it just adds complexity and fragmentation of the ecosystem?

Lol. I switched to TS from pure JS a couple years ago and could never imagine going back. I am so much more productive in TS than JS:

1. Typeahead is crucial, and even when just working on my own projects it makes me much faster.

2. Refactoring is a scary nightmare in pure JS, but so much easier with TS.

3. I have yet to see any sizable, multi-person pure JS project not become an incomprehensible nightmare after a couple years. TS makes large codebases much easier to maintain.

There are other reasons.

If anything, the consolidation onto TS from previous competing type systems for JS (e.g. I think Flow is dead for all intents and purposes, and I've seen a number of projects migrate onto TS from Flow) results in less fragmentation.


I understand the power of types - I just wonder why the heck you are writing so much JS/TS code?

Are you doing server stuff with it?

You could argue here there are much better languages and platforms for that.


Yes, in my current tech stack our entire backend is in Node with TypeScript, and the front end is React with TypeScript.

> You could argue here there are much better languages and platforms for that.

You could, but I think you'd be wrong. I come from a background of using Java on the backend for over a decade, then some time with various backend languages including Python and Ruby. This is the first time in my career when everything (front end and back end) are essentially on the same stack, and there are huge, gigantic productivity improvements to that. Most of it stems from it being easy for developers to switch between front end and back end code. E.g. it's very easy for front end developers to dig in and debug something that's not right on the back end, and usually to fix it themselves. Same thing goes for backend devs investigating how APIs are used by the front end. In all my previous jobs it was relatively rare (certainly not never but not that common) for devs to cross that divide, mainly because setting up the environment in a totally different stack was time consuming and annoying, and mentally context switching into a different language was difficult, if all you wanted to do was dig in on one particular endpoint, for example.

But even discounting that, I am much more productive in TS than I ever was with Java, primarily because the structural typing of TS makes thing much easier to refactor compared to the nominal typing of Java. Sure, there are some cases (mainly WRT scalability) where Java may be a better choice, but the idea that TS/Node is not an awesome choice for the server is outdated IMO.


>primarily because the structural typing of TS makes thing much easier to refactor compared to the nominal typing of Java.

That's interesting. This year I switched from server-side Java to server-side TS and I find that refactoring is incredibly painful when compared to Java. I think any productivity gains in the greenfield portion of a TS project are quickly offset by the pain of refactoring and debugging during maintenance. It's really disappointing, as I quite like TS.


I'm curious, could you give an example where refactoring is more difficult? I find TS much more easy to refactor because since the structural typing basically just says, for example, "This method argument needs to have these properties of these types", if I find out "Uh oh, this method actually needs one more piece of data", in Java I'd have to change the definition of the type that was passed in which could have lots more unintended side-effects, while in TS I can essentially "localize" my changes just to wherever I call that method.

The "blast radius" if you will with nominal type systems is just always much larger.


have you worked with GUIs much? complex interactive UIs take a surprising amount of code, doubly so if what you're doing isn't covered well by your platform/toolkit's native inputs.

i'm working on a webapp with a scheduling thing and even drawing a nice-but-not-interactive day schedule is a bunch of work. consider a day view that lays out overlapping events next to each other:

   Dec 8
  -----------
   9
  10  AAA
  11  AAA BBB
  12  AAA BBB
  13      BBB
  14  CCC BBB
  15  CCC
  16  
  17  DDDDDDD
  18  DDDDDDD
  19
like, even laying out those boxes takes a bunch of code. and then you need interactivity, the actual "app" part - you want drag-n-drop that snaps to columns and switches you to another day if you drag it to the side, and selections, and menus, and hovery-popupy things, and undo, and so on... it adds up quickly


But you can split it with with web components and es6 modules to be sane without resorting to a pre-processor so you code won't run directly on the platform.


Have you seen the size of frontend codebases? Even modest SPAs reach into the tens of thousands of lines. Or the size of large Express.js driven backends? A huge portion of the web is driven by JS/TS.


>> Even modest SPAs reach into the tens of thousands of lines.

I still don't get how we got from fifty lines of code for a form with simple client side validation to a React/Vue/Angular/Next version that needs 100 different modules and a thousand lines of code to replicate. Why do people see this as a huge advancement in front-end development?


Because people are writing applications, not forms. As software engineering has gotten easier, customers have demanded more complicated applications.

Modest SPAs do have a lot of code. So does a C++ Win32 application that calls into some central datastore. The complexity is not a byproduct of languages or libraries, but rather the customer's complicated needs.


Those libraries are providing a lot more than just simple validation though. Bunch of advanced validation rules, masking, etc. I'm sure if you dive into any of those modules you'd be able to see why. Not saying there isn't dependency bloat but it's not like people are creating these for the sake of it.


What text editor did you use before? I think the biggest advantage is an IDE, not the language itself.


As a daily user of IntelliJ IDEA—which, IME, has the best autocomplete and code suggestions of any IDE for dynamically typed languages—there is a world of a difference between the quality of suggestions for a codebase using TypeScript and one written in vanilla JS. Without concrete types, the IDE often has to guess the possible type(s) that a value can have, whereas with TS, there is (generally) no such ambiguity.


I don't really experience this issue and I use Web storm which is basically the same thing. I find that the dynamic type hinting plus the combination of using JS Doc formatted comments rarely leaves me with any ambiguity when writing vanilla JavaScript.


Are you using types in your JS Doc comments? If so, that's not vanilla JavaScript.


It is because it runs in the browser unprocessed.

You edit a file and reload, no munging pipeline,


JS Doc is just comments. (But the typechecker can still read them.)


Unlike other languages, typescript adds zero runtime overhead, and the APIs that one writes in TS are trivially consumable from JS. Consuming JS from TS is also made as easy as possible, including the option to set types aside entirely for some parts of your code using the "any" type, which means "don't type check this, just trust me that it works".

TS really is different from other compile-to-js languages in this respect.


It adds in developer overhead and for someone writing in JS that is often what you are trying to minimize.


It adds overhead on initial write, saves massive overhead every day after that.

There is JS code I deal with once a month where the manipulation of types is so complex I probably burn ~30 minutes every time I have to touch it. If that was was transformed into TS (which is going to happen eventually) that'd be 30 minutes saved per month, on this one particular flow of data.

I've done refactorings that were only possible because TS existed.

A lot of JS unit tests consist of "ensure these fields exist on this object after it has been called by these functions."

Typescript removes the need for those tests.

And it removes the need to update those tests every time the code changes (just change the declarations appropriately!). And it removes the need to run those tests on every commit.

That said, the overall code/compile/run time savings is possibly not in TS's favor due to how slow the compiler is. :/


Doesn't plain JS add developer overhead in the form of bugs and code the team doesn't understand a few weeks or months later?


> It adds in developer overhead and for someone writing in JS that is often what you are trying to minimize.

Typescript compiler supports (some) JS DOC

https://www.typescriptlang.org/docs/handbook/jsdoc-supported...

So you can use the compiler as a static analysis tool without buying into the language itself completely, which I do and just stick type definitions to comments when needed.


As I said, it's not a bad attempt, and it's presence has probably given renewed impetus to js lang improvements.

Though the attempts at close compatibility mean it's not properly type safe despite it's name.

In the end, it's still a 'splitter' to quote Monty Python.


> Though the attempts at close compatibility mean it's not properly type safe despite its name.

Every type checked language I've used, from Haskell to Java to Idris to C++ to Rust has ways to override the type checker (and either do the type checking at runtime, or, as C++ is often want to do, just YOLO it). It's not just the language but the codebase and the norms it and its dependencies use.

Some TypeScript codebases, the types are usually accurate, but not enough to rely on them, so you still need to do runtime checks in many places. In others, if something says (string|null) then you know with confidence that it is either a string or the null value, nothing more and nothing less.


Pretty annoyed with Typescript too. Mostly because of its popularity.

Before Typescript most compile-to-js languages existed in their own world. You might have not liked them. But you'd never have to deal with them.

Typescript has become so popular that many top javascript libraries use it too. Whatever you think of it, sooner or later you'll be working with Typescript code.


This is pretty much how I feel about Javascript itself.


Related. I'm dealing a lib that says Typescript is optional, but we give you lots of boilerplate if you don't use it.


You mean you didn't love Coffeescript?

(I'm joking)


It's terrible. The amazing issues that TS can introduce to a codebase are terrifying, and TS has breaking releases on a regular cadence. As someone who has to do maintenance on a legacy TS platform it was miserable and literally involved flipping through TS versions to find one that worked.

My issues are not with strongly typed languages, they're specifically with TS.


What issues does TS introduce into a codebase that weren't already there? This sounds kinda like arguing that if we write fewer tests we'll have fewer bugs.


In our case: 1) slow and long transpilation times, 2) although not that common these days but missing typings used to cause some head scratch 3) overly permissive/overly restrictive type definitions 4) wrongly configured sourcemaps 5) unreadable type definitions/declarations... The list is long but these are off the top of my head


Getting a configuration together that consumes all your dependencies and generates code without crapping a ton of meaningless warnings about duplicate type definitions in its own type mappings for runtime types is non-trivial and requires setting more than a few non-default compiler options, none of which are named anything that means anything.

I still don't know how it's possible to safely, cleanly make a library that other projects can consume comfortably with just TypeScript.


I've been thinking a lot about why this is, and I think one reason is because TS adds mental overhead to the language, while simultaneously removing other mental overhead.

However, for JS programmers, worrying about types is habitual. Offloading that task to a robot is great, but it doesn't mean the habit will just disappear. Thus to them, TS seems to mainly add overhead.


> for JS programmers, worrying about types is habitual

Couldn't the same be said for COBOL programmes and GOTOs?


Yeah I guess I'd generalize it as programming having two kinds of learning. First is memorization of syntax and semantics of the language. Second is a kind of shadow learning, or "street smarts" for survival in the language; which parts of town to avoid and which paths avoid dark alleys, etc. These habits are hard to quantify, and beginner programmers especially tend to apply the "street smarts" from their first language to every future language, which creates problems.


I've spent enough time converting nearly illegible coffee script back to JS that I didn't want to do it again. I believe TS has its has benefits, I just don't care.


I get CoffeeScript vibes from TypeScript, and look at where CoffeScript is now.


I don't get this. What do you mean by coffeescript vibes? They are super different languages...


In that JavaScript only needs to adopt a few of its features for the benefits of welding yet another compiles-to-JS toolchain on to projects to dwindle in comparison to writing ES8+.


The difference between CoffeeScript and TypeScript was that CoffeeScript offered syntax that people preferred, whereas TypeScript provides write-time checking of errors. It is more similar to ESLint in that regard, and is better understood as a linter than as a separate language like CoffeeScript.

Even if TS's type annotations would be added to the language (like it practically almost has been, through Babel supporting it), you'd still want to run a tool as you write it to actually check that those annotations are adhered to, rather than having your code crash on the user when they are not. TypeScript is that tool.


Adding optional type annotations to JS would be interesting. It might help with VM optimization.


Python already does type annotations, and I have no use for Mypy other than using it for type checking in my editors via LSP. I don't import it or use it as a dependency at all in projects.

I feel like JavaScript adopting type annotations in a similar manner will make TypeScript look the same as Mypy in many regards: nice to have, but not necessary most of the time because the parent language ships with most of its features.


> and look at where CoffeScript is now

Largely absorbed by modern javascript? ;-)


If you look below, this is my point. It's inevitable for JavaScript to adopt most of TS' flagship features.


I'm not against the idea of typescript as I'd just rather not have a compile step.


Hi there.


For real projects, but for someone just getting started I think it makes a lot of sense to start with core language fundamentals (I notice that, at least from the table of contents, there was no mention of build systems or frameworks either). Lots of newly-minted JS devs today know relatively little about what it means to use plain JS, which means they don't have as much perspective on what their TypeScript and JSX actually turn into, which has a meaningful effect on informing decisions.


and step 2: install prettier, step 3: eslint plugins.


I was half expecting the first page to explain what nodejs is and how to install it. Pleasantly surprised by most of this.


Lot of upvotes for the site so please do support the author(s) by buying the book[0].

All parts together is $18 (epub + pdf). I am not a front-end developer so not much use for me personally but spreading the good word :)

https://javascript.info/ebook


Excellent. Wish all documentation\tutorial sites were this clean.


When you say "clean" are you referring to the formatting of the page?


Not sure what OP was referring to, but I find both the formatting and the tone of voice to be exceptionally clean and mature. I am incredibly jealous of the writer's skill to write like this.


and structuring of the content, i believe.


> According to your browser language headers, you know Chinese. Please help to translate the tutorial into your language! Thank you!

I'm curious. How are my language preferences exposed through HTTP headers?

I think this was a charming way to request volunteers for translation, but I was a bit taken aback.


I have figured it out experimentally (Chrome & Ukrainian): if you visit a website in language X and click Never Translate, Chrome silently adds language X to the end of the list (Accept-Language that is). I have not found a way to forcibly turn it off.

Edit: check out chrome://translate-internals/ if you are interested



The Accept-Language HTTP request header is my guess


I get the same question (after a while) here: https://www.wpf-tutorial.com/


This was probably set at the operating system level, i.e. you selected "zh_ZH"/Chinese at some point during setup. Upon installing a browser, it reads your OS language preference & then passes that through to websites via the accept-language header.


[flagged]


I think this is a little harsh. The comment does point out a feature on the topic site. I'm personally glad that they brought it up because as an English speaker I didn't see this feature exposed. Internationalisation is a complex yet required feature for large websites these days, and a clever feature like this to find translations is great!


> I think this is a little harsh

Only if you read the question and assume that it is something besides a question. How does a person ask the question that I asked and mark it unambiguously as a question, not a statement (and do it without unnecessary baggage)? How do I convince people to answer the question instead of reply the way you did, to something you received instead of what I asked? Is that question not tolerable (it got flagged) but the other commenter's is fine?


Yes, I think you should assume something else.

I provided a reply above from my point of view: I use a computer that has English as a primary language, my Chrome install is also English and I don't live in Ukraine. And of course, I have never added Ukrainian language in my Chrome settings. And yet it "guessed" that I speak Ukrainian. The key bit here is that browsers may modify the list of languages even after you go to the settings and remove all languages except for English (for the record, Chrome also "forgets" that I told it never to translate Ukrainian after I remove Ukrainian from the Accept-Language settings, which is annoying).

So, I guess you are a native English speaker and simply never had any exposure to this "customer journey". I hope my explanation gives you a glimpse into why an experienced software engineer may be still surprised to see a website detect a language they are not using in the system.


I think you replied to the wrong thread.


It comes off as condescending. Generally, being incredulous of the way someone thinks isn't a respectful way to engage with them (I'm sure most of us are guilty of it at times, but usually in frustration with people that we have a personal relationship with). If you're going to ask someone something that might offend them, I would suggest starting with a show of goodwill. Also, extensive use of hypothetical "thought-quotes" is very easily construed as mocking or belittling, even if you were just trying to be precise about your meaning.

A better way to ask might have been: "I'm curious, and I don't mean to be rude, but what caused you to post this comment here instead of searching for the answer?"


That recommendation strikes me as much closer to an attempt to make a statement with a rhetorical question than the question I actually asked. Even the most charitable assumption of good faith would most likely yield a response lacking detail and devoid of any insights that I was after.


You could add that "I'm asking because the process of typing an off-topic comment on a forum and waiting for replies strikes me as an inefficient way to get an answer to this question, and I'm genuinely trying to understand that thought process."

I highly doubt it would have performed worse than your strategy, which at best resulted in a derail about tone, and at worst scared off the person you were asking and others who may have otherwise taken time to give the deep and thoughtful answer you were looking for.

It seems clear that you find niceties and pleasantries to be not genuine or unnecessary, and I can sympathize, but they go a long way in terms of making people feel comfortable and opening up to you.


> It seems clear that you find niceties and pleasantries to be not genuine or unnecessary

Wrong. It seems clear you all like making assumptions and treating them as unshakeable truth.

I scarcely think that your suggested wording (your second attempt, keep in mind) would have satisfied even you without this conversational backdrop providing context.

> I highly doubt it would have performed worse than your strategy,

Those aren't the goalposts we're shooting for. You've subtly given yourself an easier target to hit than the one that was presented.


> Wrong. It seems clear you all like making assumptions and treating them as unshakeable truth.

Can you explain, then, why 1) your original post was devoid of any such language, and 2) you dismissed my suggestion, which added some, as being likely to cynically have the opposite effect of what was intended?

I get what you're saying. People often do couch cynicism and trolling in pleasantries. Which makes it difficult to appear genuine when asking a tough question like that. But that means you have to try extra hard if you want results, not give up entirely and go full autism on someone that clearly isn't going to respond well to that.


There's a perverse irony in the way your responses here exude condescension while ostensibly trying educate and inform about the sort of things that people respond to. Although it looks like you came here to argue (which now explains the presumptuousness), I didn't, and I'm not wasting any (more) of my time indulging you.

> I get what you're saying. People often do couch cynicism and trolling in pleasantries.

No, apparently you don't, because that's not at all what I said or what I'm trying to say. Aside from failing at that, you almost succeeded at deflecting, but not quite. The attempt to change the subject and avoid responding directly is yet more reason to stop this here.


> There's a perverse irony in the way your responses here exude condescension while ostensibly trying educate and inform about the sort of things that people respond to.

That's a fair point, and later last night I regretted having used some unhelpful rhetoric. I often struggle to resist that temptation. In my defense though I was only going toe to toe with someone who had already demonstrated a willingness to dispense with courtesy in the name of pure inquiry.


Shoehorning big words into a message usually has the opposite of the intended effect. This instance is not the exception.


Because your question reads as a relatively transparent thinly veiled insult, like you're questioning his ability to be curious about the world, and contributes very little to the discussion.


You haven't given me anything actionable. Read the question I asked, understand against your instincts that it is a question and not the insult you assumed it to be, and then tell me a way to ask that question that doesn't make you feel the way you do right now. Is there one?

Disagree strongly on "contributes very little to the discussion".


Maybe he did fo that but wanted to inform the OP that this was surprising to him. Given that the OP is looking for translators it is valuable feedback imo.


maybe: since I'm already here I'll ask the question because on this particular site somebody knows the answer and can probably give me a better starting point for learning about the subject than the average search engine!

Also it will serve as a notice to people that not everybody knows these things and might be put out by this sort of question.


I've done this more than a few times because this is a good community to get direct answers from when it comes to questions like the OP's.


I don't understand.


I feel I need this so badly. The last time I wrote something in JavaScript was around 10 years ago and I want to get up to date. One of the chapters is named "the old 'var'". I didn't know it was old, which proves the need to learn.


Looks well written, but it seems undecided on whether it's targeting experienced programmers or newcomers. I have to disagree with priyatham_'s position that it effectively targets both.

The Loops section gives a very brief description of what loops are. This doesn't introduce anything of value to an experienced programmer, and it's nowhere near enough of an explanation for teaching imperative programming to a beginner.

Personally I'd suggest targeting experienced programmers. I only learnt JavaScript relatively recently, and I found it very frustrating that every JavaScript tutorial I could find was aimed at beginners (and that isn't an exaggeration).


Looks really nice, although ...

For as good as the TOC and layout is, there's always something I miss when I read books from a website. I miss the spatial context: how much material I already covered? How much is left?

I like the linearity of regular books (that includes PDFs). If the book is a website the next best thing for me is when the whole thing is just a single page. Worst thing are epubs :-p (hate the way the layout works with those and how slow epub readers tend to be).

ps. I saw I can buy a PDF of this site, but just commenting in general.


I think comparing gaps with exploringjs.com (separated by ecmascript versions) would be worth a shot.


Note that the Russian version of the site has more information than the English version, you can translate the page into English to read it (or just learn Russian)


sighs and opens Russian learning book


The Russian version simply adds a CSS section for JS developers and an extra page at the end of the first section, I don't know if the content of the chapters differs from the English version.


You're right, the English version is now updated, it used to not be as up to date as the Russian version.


This is great. However, it gives the example of copying a variable by assigning another variable to it. This doesn't copy a variable's contents - it makes the new variable a pointer to the original variable.

As someone who doesn't use Javascript much... is there a way to force it to copy the current state of the original variable to the new variable, without it being a reference and without having to use something like lodash?


You will need to clone the object somehow. The simplest solution is to go through each of the object properties and create a new object with those same properties (_.clone). Alternatively, recursively go through each property in the object and then keep going deeper through each property that is an object until you get a copy of everything to assign to a new object (_.deepClone)


I think the only reasonable thing that js can do here is what it does - copy the reference. Also, there is a simple way to copy all properties from a object: const copy = { ...object }; Of course, if these properties are themselves objects, then changes in one of them will appear in the other.

One way to have a deep copy which shares nothing is const copy = JSON.parse(JSON.stringify(object)); but that may not always work. In short, copying a arbitrarily large object will probably waste memory, so it should be a little hard so you don't do it unless it's really necessary.


In addition to the cloning stuff, I've seen use of an immutables library [0] to make this stuff a little more explicit and simple. Not sure if that's still fashionable though.

[0] e.g. https://immutable-js.github.io/immutable-js/


The cheaty way is `let copy = JSON.parse(JSON.stringify(val))`. Doesn't work for functions or cyclic structures though.


There is a chapter called ‘ninja code’, which is full of terrible advice. A small example.

> The ideal name for a variable is data. Use it everywhere you can.

There is one small comment at the top of the chapter, which says ‘Irony detected’. Is there really a whole chapter written Ironically? It would be very easy to read this and think it was real advice.

(And if it is real advice, and I’m completely misunderstanding, then I can’t possibly recommend this book).


I understand that often subtleties of language, particularly when it comes to irony or sarcasm, can be lost in textual content (particularly supposedly-formal content like educational materials), and that generally this is something to be avoided.

However, after reading that chapter, I really can't help thinking that you simply weren't paying any attention.

It's not just written in sarcastic tone (something that yes, could be easy to miss for many), but it's also littered with active dissuasion and explicit explanations of the pitfalls of using this style.

Examples:

> If you write like that, a developer who comes across this line and tries to understand what is the value of i is going to have a merry time. Then come to you, seeking for an answer.

> A quick read of such code becomes impossible. And when there’s a typo… Ummm… We’re stuck for long

> A fellow programmer who wants to work with elem in the second half of the function will be surprised… Only during the debugging, after examining the code they will find out that they’re working with a clone!

> First, the code becomes longer and less readable, and the second, a fellow developer may spend a long time trying to figure out what the underscores mean.

You can argue that the chapter is inappropriate, but I don't think you can reasonably argue that it's misleading.


>There is one small comment at the top of the chapter, which says ‘Irony detected’.

The whole chapter is littered with clearly tongue in cheek remarks.


People will absolutely not get that and take the advice to heart.


I doubt many will. It's not subtle.


I see you've met the entire front end team where I work...


I think that page would benefit to first more clearly define what a JavaScript Ninja is and why it's good for you to become one. Something along the lines:

"A JavaScript Ninja writes code that is brilliantly mysterious. When people read such code it should induce confusion and if at all possible, fear. Clarity is for the feeble. Obviousness is overrated. Obfuscation and secrecy: that is the way of the Ninja. So, how do you become a Ninja?"


> There is a chapter called ‘ninja code’, which is full of terrible advice.

How someone interprets a tongue-in-cheek chapter could be a good litmus test of their reading comprehension, grasp on the fundamentals, and (last, but not the least) basic sense of humour. I’d hate to see it removed.

If someone takes this section literally, I would be immensely curious how they reconciled in their mind that advice with what they (supposedly) read in preceding sections.


This reminded me of a brilliant and hilarious presentation on microservices : https://youtu.be/X0tjziAQfNQ


yes, it's a whole chapter written ironically. I too find this to be misleading.


The ninja code section is pure sarcasm, right?

I'm not sure now which sections are and aren't.


That page has an 'irony warning' so just watch out for those on other pages!

It might just be my sense of humour (I'm the sort of person that doesn't need an '/s' tag and feels that it shouldn't be necessary if you told the joke properly), but it was pretty obvious to me even without the irony warning that the page was intended as a joke.

It looks like it was heavily inspired by the classic 'Tao of Programming' [0]. It uses a very similar style and even quotes the actual Tao Te Ching.

[0] http://www.mit.edu/~xela/tao.html


I am with you on not wanting or needing to see /s ... but on a tutorial, where people actually struggle to understand anything at first read, using unmarked irony is maybe not the most helpful for them.

Oh and a second thought on /s. For some time I only got my news through satire sites like the onion. And after I switched back to "real news" sites, I could not believe it was not satire. I mean come on, the world and the internet was always full of dumb people, but when even very high ranking people and institution say really out of the world things in all seriousness - I came to the conclusion, marking irony as irony is sadly sometimes important, in those interesting times we live ...


Yeah, when we live in a world where people legitimately believe that Bill Gates is trying to use COVID vaccines to install microchips into people, you can't always be sure that someone giving an insane opinion isn being ironic or sarcastic.


I mean, we allways had flat earthers (even though I couldn't believe they were serious either, when I first stumbled upon them).

But this new level is a bit unsettling.


The Ninja code section seem to have been largely based on this classic article, which I personally found more humorous to read: https://github.com/Droogans/unmaintainable-code?fbclid=IwAR1...


Interestingly Golang encourages one letter variable names and it's not sarcasm this time : https://github.com/golang/go/wiki/CodeReviewComments#variabl...

Golang's landscape is full of one letter variables and abbreviations and it's not great.


It's only encouraged within certain contexts. Like it says, short lived stuff can be named "x" or "i". We already do this in almost every language. "c" for "count" or "i" for "index" isn't specific to Go, I've seen and done that in every language I've used.

Stuff that isn't easily understood should be named appropriately but shortness is encouraged.

If you're storing an index in a global variable or a struct field then it should be called "index" not "i".

Method receivers are usually always kept short because they're pretty self explanatory and the first thing you look at in a function.


i and j are very understandle.

I did browse the go code randomly and for example t, s, and b are terrible variable names in my opinion in this example : https://github.com/golang/go/blob/3ce865d7a0b88714cc433454ae...

You can find a lot of code like this.


That strikes me as perfectly readable. t for template, b for bytes, and s for string. What else would you call them?


Sure, what bothers me is how inconsistent it is. Function parameter of type Template is `t` but local variable of type Template is `tmpl`.


Yes, I would have named the other one returnTmpl or something.


template, bytes, string.


`bytes` is the name of a stdlib package. `string` is the name of a built in type. `template` is technically available, but only because it’s the name of this package, so it can’t refer to itself.


True, but they are all available. The stdlib bytes packages is not loaded, and it's valid to use `string` as a variable name, I just tried.

But even if these names were not available, I don't think using `tpl` or `t` or `b` is what should be preferred.


template, file, text


Is file a file object? A file path?

All three are “the template”. So, they use polish-ish notation: the template as []byte, template as string, and template as *template.Template.


In just two hours we discovered so much! Let's keep digging.


I’m not sure I follow. Is two hours a long time or a short time?

I use Go a lot, so I’m used to it’s conventions. b for bytes is obvious to me because I know ReadFile returns bytes (not a file handle or a buffer), but I can see why if you lack context, it can look odd. OTOH, I don’t use Rust, so when I read snippets with 'a lifetimes, they always look “wrong” to me.


That's easy. `b` stands for file


I never understood that. Is it really that hard to spell out full variable names? It’s so much more legible, there is autocomplete on virtually any editor (even the ones that aren’t IDEs), and you write code once but read it hundreds of times. Why even try to save 8 bytes at the expense of readability?


Short variable names make code more readable in some scenarios, not less.

  fooBarBazThings.each(t => t.DoThing())
  for (int i = 0; i < len(things); i++) { // i used here }
Some local code patterns are seen so often you understand it in one go. Something like

  fooBarBazThings.each(fooBarBazThing => fooBarBazThing.DoThing())
  for (int thingIndex = 0; thingIndex < lengthOfThings; thingIndex += 1) { // thingIndex used here }
Just clutters things up.


I disagree. I always use descriptive variable names. I have no idea what ‘t’ is. ‘thing’ is 4 bytes more. Not the end of the world, but much more readable. Same for ‘i’ vs ‘index’.


This is a bit of a false dichotomy, because the names don't have to be that long.

  fooBarBazThings.each(thing => thing.DoThing())
It's more useful when the receiver of the method doesn't tell you as much, eg:

  getRecentPurchases().values().forEach(price -> priceStats.accept(price));


Modified obfuscator can make your code even more readable. It can simplify functions in addition to variables. Also, it improves job security, which is important in times of covid.


I kind of agree with their reasoning, the exception being when you can have a lot of complicated looping/control flow breaks or transient variables close to their usage. Seeing 'array[i][j][k]' is never fun.


The section is clearly dripping with irony. They even have an "Irony detected" box at the very top which acts as the sarcasm/satire tag so many people seem to use to bang over our heads that it's not serious.


It has an alert at the top that says, "Irony Detected".


It is hilarious. Lao Tzu quotes make it simply perfect.


It is funnier to me because the quotes are actual historical quotes (to be fair, there probably was no "Laozi" historically), whereas you see fake quotes for Laozi/Confucius/Buddha all over the internet.


I prefer post-modern javascript, the kind that works universally across all browsers starting with Netscape 2.0


Aside from newer methods the only syntax gotchas in my code are template strings and let/const. That makes the code really quick and simple to convert to an old IE friendly application.


alert("Reached here #23");


More like:

//alert('DEBUG: SomeFunction: condition is TRUE');

Then, depending on what browser I'm debugging in, the post-processor changes that to either console.log, document.title=, or alert(

:)


> ... how it's done now

Intro section has no context, especially how this relates to Crockford's "the good parts".

Is it inspired by it, in conflict with it, a superset, a subset? How did newer standards affect it? how is 'modern' defined? How is 'now' defined?


I've had this site's Regex section bookmarked for awhile and it's been a great tutorial and reference. I can't speak to the other content but if it's similar, it would be of good quality.


Never rely on Americans to spot irony


I looked at this page first and assumed that it was all a gag.

https://javascript.info/ninja-code

>Show your original thinking! Let the call of checkPermission return not true/false, but a complex object with the results of the check.

>Those developers who try to write if (checkPermission(..)), will wonder why it doesn’t work. Tell them: “Read the docs!”. And give this article.


Then it will always be truthly if it returns an object, or 0 means success? :)

The proper way is callback convention err. Then you can write if(!err) ...


It was tongue in cheek though... the summary tells you as much.


I mean, I read it, and assumed the rest of the guide was also tongue in cheek.


Every single example on that page was clear bunk -- showing the worst habits of some developers, and making clear why they are terrible.

I think if you've gotten as far as that chapter, it would be pretty impossible not to realize it was tongue in cheek.

At the top of the page is a big warning triangle that says "Irony detected."

No other chapter includes such a prominent warning. I think it's pretty clear that the "gag" is specific to that chapter.


Looks like a great resource. There does not seem to be anything on database connections (e.g. MySQL, PostgreSQL etc) and related topics (e.g. building a CRUD framework). Are database connections only considered in a client/server context (e.g. through Node.js)? What am I missing? How does the IndexedDB section relate to these considerations?


The website is really very good. I started to learn JavaScript last week and worked through the JavaScript Wikibook. Unfortunately it is not as complex as the website linked above. I can continue working with it really well. I also like the structure and design, which makes the tutorials really easy to read. A great project.


The site is awesome, but I wish they had an all-in-ONE-page option. Navigating through X sections and links is a chore.


Thanks for sharing. I found this quote very appropriated:

In older scripts, you may also find another keyword: var instead of let


True for reading legacy JS. For newer code, you can still identify noobies (and "experts") by the conspicuous usage of let instead of const.


While I certainly prefer immutability there are many who do not, and that preference does not make you better or more experienced than them.


So glad people still make things like this despite so many tutorials and books already being available. This means people still care to make something purely for sake of making it better - obviously nobody would be interested if it wasn't. Crafting tutorials should be considered an art.


Hmmm there are a lot of language footguns or advanced features that don't have any disclaimers for beginners. I don't think a beginner should be told to use Proxy object handlers before learning the basics of JS, async and functional programming.


Wow, this is really well put together! Anyone know an equally good guide for Python?


Still fantastic!

When I teach Javascript to students, javascript.info is one of the main sources I use besides MDN.

PS My copy of JS the good parts is getting a bit dusty somewhere in the garage...


https://javascript.info/ninja-code hah this is a great read :)


It is a nice tour of JS features.

Some things missing: Typed arrays, template literals, Internationalization API (Intl).

Date will be replaced with TC39 Temporal soon.


Suppose I've been living under a rock this whole time and my knowledge of JS is something along `it's a language you use when you want a message box to appear and annoy your visitors`, i.e. completely out of touch.

How could you explain me, strictly from the language design point, not practicality/how widespread it is/how easy is to find a job/etc, why JS? What are the strong points which make it a better language than lua/python/lisp/tcl/ruby? Thanks.


Well for client side code running on a website, it’s your only option. I guess nowadays many client support web assembly, but for all practical purposes you need to use JavaScript to do any client side web programming.

On the server the advantage is much less clear-cut, but a lot of it boils down to “we want to use the same language for the front end and the backend“. Although in my experience this is actually a horrible idea, and tends to result in very messy code and lots of work arounds in practice.

Anyway for me personally I continue to use JavaScript because of a combination of wanting to build lightly-interactive webpages and because that really is what the job market demands. So many companies are dead-set on hiring someone with node, react, and whatever other JavaScript experience. I tried taking it off my resume at one point because I kind of hate it, but if you’re at all involved in full stack web development it’ll really hurt your career if you don’t do JavaScript.


The Ninja section is priceless.


JavaScript has some really nice features that this tutorial does not mention 1) First class functions 2) Prototype 3) Function scope 4) What async means and how to master it Those I think is essential in order to understand JavaScript.


This website covers every nitty gritty detail of javascript, even DOM specific aspects like https://javascript.info/bubbling-and-capturing (just look at how well it is written). I would be highly surprised if it did not even mention those javascript basics. A brief look at its table of contents shows that indeed it mentions those, and I am baffled why the other commentor is getting downvoted for calling you out.


For example the article about callbacks basically says "use Promises" which is even more complicated then first class functions.

Helpful resource: http://callbackhell.com/


What are you talking about? Did you even take a look at the table of contents?


I didn’t downvote, but calling people out for not reading the article — even if it seems blindingly true — is against HN rules and always gets downvoted.


Now I'm being downvoted because my comment seems like a non-sequitur. But prior to an edit, my parent was wondering why they were being downvoted, which is what I replied to.


Like the email based one more. But this seems more complete.


Oh no! It's already out of date! (That's a JS changes too fast joke)

But seriously, calling it 'modern' is pointless. It's not adding anything valuable and its just going to become out of date (and thus wrong).


It's not pointless. In the context of JS 'modern' generally means es6+ or node as opposed to es5.


just say es6, though, i guess?


Honestly, it’s fine if documentation goes out of date, otherwise what’s the point of writing anything at all? The onus is on the reader to check the publish date of what they are reading, and to cross reference it with other sources to ensure accuracy.


I'd be careful about relying on "updated" dates too heavily. As a professional technical writer, I've seen that some people bump the "updated" timestamp for any update, no matter how small. At other times it's bumped automatically by the build system. I think the best practice is to only bump the timestamp for substantial updates, or to use an explicit changelog at the bottom of the doc. But that practice isn't standardized across docs sites.


I encounter this "article update" problem a lot with Java blogs... Baeldung instantly comes to mind. Every article I find there was last updated on 2020, but don't seem to have actually changed.


That’s a good point to call out, thanks! There is so much involved in being a “defensive reader” heh


Nothing will become inaccurate, because JS never introduces breaking changes.

The guide might come to lack some newer things over time, but I doubt those will include any major paradigm shifts, because the past ~10 years have likely been the most dynamic that JS will ever see in terms of idioms and best-practices. JS made a radical shift into a mature language, and now it is mostly on the other side of that transition. So writing a "modern" (post-transition) tutorial makes perfect sense to me, and I don't think it will become irrelevant any time soon.


> Nothing will become inaccurate, because JS never introduces breaking changes.

Can you help me debug why `document.createElement('button').attachEvent('onclick', e=>alert('attachEvent!'))` isn't working then?

You might object that DOM APIs aren't part of JS proper and that's true, but this guide covers `addEventListener` on this page: https://javascript.info/introduction-browser-events

Sticking only to JS language features, I assume you can help track down why my `with()` statement doesn't work. Or why `function testing() { console.log(this.location.href); } testing();` throws an error but only if I package my code as an ES Module instead of an AMD bundle.

I agree that breaking changes like this are increasingly unlikely to happen, and I think the changes that have been made are easily net positive. But the claim that they never happen is simply not true.


I do include the DOM API in my statement, but I do not include non-standardized browser APIs, which attachEvent seems to be.

I'll refine my statement to "The JS standard never introduces breaking changes".

attachEvent never was part of any standard, and is therefore subject to breakage. Non-standard APIs should never be part of a comprehensive guide to the language in the first place.


I was worried that leading with `attachEvent` would get a response about only `attachEvent`.

The `with` statement is described on page 75 of the ES3 standard[0]. It does not work in an ES Module or in a strict mode context. This is a breaking change.

[0]: https://www-archive.mozilla.org/js/language/E262-3.pdf


Strict mode was invented as a way of introducing a handful of "breaking" changes without them actually being breaking, since it's opt-in. JavaScript had some egregious design issues from the beginning and strict mode is a remedy to some of them.

But when most people say "breaking changes" they mean things that suddenly cause legacy code to stop working, and non-strict mode will almost certainly be supported ad infinitum, so I don't really count that. It's also almost certainly never going to happen again.


JS (the language) may never introduce breaking changes, but JS (the ecosystem) sure does. With a quite normal react app, breaking changes are a constant battle. Clone the repo, oops, one package was upgraded that broke another; upgrade that one, oops, it breaks another. The package manager is supposed to deal with that, but it (effectively) doesn't.


This aspect is irrelevant to the discussion because the OP only covers the language itself.


I think it’s precisely the fact that js is constantly changing that they’ve branded this as “modern”.


Disagree. I've been writing JavaScript for twenty years, and I'm very aware that there's a lot of "new" stuff that I need to brush up on. When I saw it call itself "modern" I instantly assumed that it would be covering the kind of information I need to know.


I, as a JS dev of 10+ years, wouldn't consider this "modern". I didn't see

- for in loop - for of loop

as a couple examples, and those have been around for at least a few years now. There's probably more missing too. To what the above person said. The usage of "modern" or "latest" or similar is going to fall behind and make for bad searching.


> - for in loop - for of loop

It's 2020 and you still use loops? ;-)

source: https://github.com/buildo/eslint-plugin-no-loops


Disallowing for..of iterators is the reason I cannot use or recommend the Airbnb lint preset. A very nice example of an anno 2014-2017 cargo cult that clearly hasn't held up. https://github.com/airbnb/javascript/issues/1271


Don't worry, there's plenty of 2020 cargo culting to replace it.


for/of is an iterator. It consumes the Symbol.iterator interface and is totally different from the for(i++) statement.

That eslint rule is a good example of a cargo cult. The second link in its rationalization argues for using underscore over touching a dangerous loop yourself.


i think it's great on how it brushed on forms and web api's, but in your case it seems exploringjs.com would be a fit (grouped by ecmascript versions).

OTOH out of scope are server-side JS (NodeJS), transpilers like babel, bundlers like webpack, and of course package managers like npm and yarn


to be fair. anything after 'use strict' can be consider 'modern'. However with the rate ES7 - 10 is going. Yeah this wouldn't be modern.


Make a merge request.


I swear this tutorial comes out fresh every other month


Excellent resources. Is there one like this for Java?


The default way promises are used is now async/await. `.then()` should not be introduced as anything more than 'you may find this in older codebases'.


> The default way promises are used is now async/await. `.then()` should not be introduced as anything more than 'you may find this in older codebases'.

No, because you might have to write explicit promises in the browser with async API that are callback based.

You need to understand how promises work to use async/await at first place anyway.

Just like it's better to understand how prototypal inheritance works in JS BEFORE even using a single class declaration.


"Just like it's better to understand how prototypal inheritance works in JS BEFORE even using a single class declaration. "

About that, does JS class inheritance now work like classes in java for example? Or is it still just syntactic sugar for the prototype inheritance? By your wording, I assume the later?


Correct. It's still prototype based. Thus making the class keyword actually MORE confusing for people from other languages, IMO.



Wow. I was hoping, at some point things would improve a bit.


Agreed. I find myself using a pretty small subset of the language which definitely doesn't include the class keyword. Doubt I'll ever find it useful.


Yeah, like many people, I ended up making my own inheritance routines. Then when class came out, I was half rejoicing, half regretting to put up the work. But well, no thanks. I rather keep using my own far from perfect way of things.


Yes because you can and should promisify old libraries.


No because some async Web API are just a bit more complex than just 'promisify' this or that.


Which ones?


Maybe some codebases mandate it, but it's very common to use either style when it makes the most sense. The classic syntax is by no means deprecated or superseded by async/await.


async/await is excellent syntax when you want things to happen one after another. That's the usual case, and that's what I find myself using 95% of the time.

However, when you want a more fine-grained concurrent execution of different asynchronous things, then() still could be very useful.


Can you give an example of more fine grained control with then?


Often times operations are order-independent. Specifying those as sequential `await`-s does not make a lot of sense in those situations. I guess less fine grained control is desirable under such circumstances :-)

There's also other useful utilities such as Promise.all(), Promise.any() and Promise.race().


const [result1, result3] = await Promise.all([task1(), task2.then(res => task3(res))])


Could that be written

  const task2then3 = async () => task3(await task2());
  const [result1, result3] = await Promise.all([task1(), task2then3()])


I'd just:

    async function getResult3(){
      const res = await task2()
      return task3(res))
    }

    const [result1, result3] = await Promise.all([task1(), 
    getResult3()])


That’s probably good general advice.

One problem. I’m increasingly coming across devs who’ve never used Promises directly, only async/await. They’re introducing all kinds of problems into code because they don’t have that foundational understanding of Promises. I think it’s essential to know how Promises work, even if we generally recommend async/await.

Also, Promise interface can do things that async/await cannot, such as Promise.all, and other unusual async execution scenarios. It’s important to have those tools in your belt.


100%, people should definitely understand Promise.all() and Promise.any().


> Promise interface can do things that async/await cannot, such as Promise.all

PS I should clarify await and Promise.all/any work fine:

    await Promise.all(items)


  (async () => { set(await get()); })();
 
  get().then(r => set(r));
Ignoring error handling I'll often choose the second option.


Much cleaner. You can go even further by using point-free style:

    get().then(set)
It's the try/catch blocks that make async/await truly worse than native promises. I use them sparingly because so often the .then syntax is both clearer and terser.


What don't you like about try/catch? I find the opposite true, the .then/.catch is more confusing.


try/catch introduces new block scopes and interrupt control flow. I find this example very readable, but expanding it into try/catches would make it rather long winded and harder to see the pattern at work as you extend the sequence:

    get()
        .then(handleResult)
        .catch(useFallbackResult)
        .then(updateState)
I prefer concision and functional expressiveness because it reduces the surface area for writing buggy code. Much like how using map instead writing a for loop can eliminate out of range index bugs, chaining promises brings useful guarantees about how the code I do write can be interpreted.


OK. I'll do:

  const result = await get()
  set(result)
But you do you.

Current node and console have top level await BTW.


That only works in an async function. The then example doesn't have that requirement. So the alternative shouldn't either.


Yes, your example isn't complaining about then() being clearer than await (because it isn't) but rather complaining that top level await isn't everywhere yet.

In other words, your complaints have disappeared in node, and will soon in browsers: https://github.com/tc39/proposal-top-level-await

So yes:

    set(await get())


Sometimes you may need to handle a promise in a function that can't be made async.


If a function is inherently sync, then it shouldn't be using promises.


Can you point to anything other than saying "this is obvious"?


No, just experience with a lot of codebases.

Here's a simple question to ask yourself: what if non-IO operations allowed you to use the .then() syntax? If you have the choice to use:

   1 + 1.then(function(result) { ... }
vs

   const result = 1 + 1
Which would you choose?


Using then() doesn't pause execution of the callsite function, while await does. Surely that's a relevant difference here?

It doesn't seem unreasonable to use then() to express: "Run this anonymous function whenever the async thing completes. Meanwhile let's do this other stuff right now."


Both codebases can't do anything until `result` has a value.


Needs to be updated on a regular basis.


It's open source and they're actively looking for contributors.


This site is a great resource. The event delegation section is something I have bookmarked as when entering a new contract I typically don't have access to my own code to use as a reference.


Is there a good tutorial that covers all the various frameworks that are in use? Modern Javascript has become very complicated due to the proliferation of these frameworks more so than the programming language.


Tbh if you know JavaScript well all these frameworks work like js. I build couple websites using vanilla js and when using any framework I can tell what it is doing behind the curtains because I have done it myself dozen or times in multiple lines of normal js




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: