Skip to content

Instantly share code, notes, and snippets.

@mikermcneil
Last active December 14, 2022 13:53
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save mikermcneil/d8bfb2e3da7c7b243297c9c117ed5f15 to your computer and use it in GitHub Desktop.
Some things I've learned about writing Javascript

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, since typeof null === 'object'
  • 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()
  • 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)
    • 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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment