You know, if you simplify something, you don't have to work as hard, learn as much, or bother other people with as much complexity.
That's how I like to write code anyway. More conventions, fewer ways to do things, less cognitive load.
More creative energy to make good decisions. More brain space to move quickly.
Here's what I'd say if I was teaching a younger version of myself advanced JavaScript:
- data types
- made a commitment not to use classes,
new
, or constructors at all (plenty of other ways to look clever) - realized that, ok, technically using
new
to instantiate your own custom Object you created with a constructor is technically 2x more efficient, and yet, that it's such a low-level operation that it just doesn't matter, and even it it did, it wouldn't be worth all the hassle 99.999% of the time - learned about all the falsy literals in JavaScript (
undefined
,''
,0
,NaN
,false
,null
) - made a commitment to never, ever use
==
and always use===
- learned that the two exceptions to the absolute correctness of the
===
operator are (a)NaN !== NaN
and (b)-0 === 0
- put in one's repitoire the rarely-used equivalent of four equal signs, and when to use it (specifically to overcome the limitations
===
; in other words: (a)Object.is(-0, 0)
and (b)Object.is(NaN,NaN)
) - understood that a variable and a literal are always interchangable
- understood equality by reference versus by value for objects (i.e.
[]
and{}
) - understood that one should never rely on
typeof
for something that mgiht be null, sincetypeof null === 'object'
- made a commitment not to use classes,
- flow control
- made a commitment to always use
await
, and never callbacks or Promise, except when absolutely necessary - made a commitment to never return a Promise from an async function, and always just to return or throw like normal
- made a commitment to forever eschew inline function declarations, which are like telling someone a story out of order. Instead, it's better to tell the story in the order that the events happened. And it's better to create code that tells its story in the order it will run when executed. The only way you write a named function is by putting it into its own file (one named function per file). It's a subroutine. A definition. A "how to"..
- realized that Lodash is much less necessary with modern js, but there is still a place for more advanced functions like
_.intersection()
,_.uniq()
,_.escape()
- made a commitment to always use
- security
- understood to only ever escape at the moment of injection
- …into URLs (
encodeURIComponent()
) - …into HTML text nodes (
_.escape()
) - …into HTML attribute values (you have to be more stringent than with normal HTML escaping)
- …into URLs (
- understood it is very rare to be in a situation where you want to write code to unescape something. If you're unescaping something, check your premises. You'll write code to escape stuff 99 times for every one time you write code to unescape something.
- understood you're almost always better off escaping data as close to the destination as possible (e.g. as close as possible to the spot in the code where it is being concatenated into a URL, or into an HTML document, or into a SQL query)
- understood it's a good idea to always escape, even if the data is trusted data that doesn't come from a user. It's worth it to keep up the habit.
- understood to only ever escape at the moment of injection