DEV Community

Discussion on: Most confusing and hard to understand parts of JavaScript?

Collapse
 
ahferroin7 profile image
Austin S. Hemmelgarn

this is probably the biggest one for me too. The binding rules are not immediately obvious, and it's compounded by how it behaves differently in arrow functions.

I don't quite get people complaining about anonymous functions as if they're JS specific though, most HLL's have them these days, they just don't force you to use them to quite the same degree that JS does (see for example lambda expressions in Python, I know quite a few Python developers who don't even know they exist because they're that rarely used).

The other really big one for me though is the whole ES6 module system. Short list of issues I have with it:

  • import foo behaves differently from almost every other widely used programming language. In most languages, that (or require foo, or using foo, or whatever else the language does instead of import) loads the module foo and binds it's contents to the name foo in the local scope. In JS, it loads the module foo, runs the top-level code, and then moves on to the next statement without doing anything else with the contents of the module foo. Were it not for the next point, I could probably tolerate this because it means you can have plain (non-modular) JS as a dependency of a module.
  • import foo as bar behaves differently from many other widely used programming languages. In most languages, that (or it's direct equivalent) is the same as import foo, just with a rebinding to a different name in the local scope. In JS, it loads the module foo and looks for an export called default and then binds that to the local name bar. This one wouldn't be an issue if it weren't for the next point.
  • There is no default 'default' export. You have to explicitly declare one instead of things being logical and having an implicit 'default' export that evaluated to a Module object like what the Promise returned by a dynamic import resolves to.
  • Because of how it serializes things, you have to use preload links or headers to get modules to download in parallel (were it not for this, bundling would be much less performance critical).
  • Because of how it all works, you either can't do conditional imports, or have to handle conditional imports asynchronously. This is a serious pain in the arse because it introduces asynchronous behaviour somewhere where it isn't necessarily needed.

Now, I'm not hugely fond of AMD or CJS either for their own reasons, but at least they're more sensible than what was decided on for ES6.