An opinionated style guide for JavaScript code.
this
this
class
prototype
Always use "function expressions":
/**
* {@link add} adds two numbers.
* @arg {number} a
* @arg {number} b
* @return {number}
*/
const add = function(a, b) {
return a + b;
};
Never use "arrow function expressions" or "function declarations".
Never throw
.
Instead, return errors:
/**
* {@link add} adds two numbers.
* @arg {unknown} a
* @arg {unknown} b
* @return {number | Error}
*/
const add = function(a, b) {
if (typeof a !== "number" || typeof b !== "number") {
return Error("can only add numbers");
}
return a + b;
};
When using builtin or library functions that throw,
surround them with try-catch
and return the
(optionally wrapped)
error in the catch block.
Use
Error.cause
and
AggregateError
when appropriate.
Proxy
They are great debugging tools in codebases that are not already littered with them.
The alternative is "sometimes use semicolons" which is worse.
"
for strings'
when the string contains "
+
is often more readableconst
vs. let
(vs. var
)I don't know yet.
For now, I use const
whenever I can,
let
otherwise.
But learning about the "Temporal Dead Zone"
and its performance implications in JavaScript engines
have shifted me towards even considering var
again.
-
as word separator where appropriateimport * as name from "./name.js"
style importsindex.js
files to aggregate folder exportsindex.js
filesName enums like so:
/** @enum {string} */
const Color = {
RED: "#f00",
GREEN: "#0f0",
BLUE: "#00f",
};
All the rules above are trying to lead to a more grokkable code base. Breaking some of the rules to optimize specific parts of the code is fine.
E.g. using accessors/Proxy
sparingly might be useful,
but if you use them too much,
it will make your code harder to grok and debug.
Using prototype
sparingly,
e.g. to significantly optimize memory usage
of a specific kind of object with lots of instances,
is fine.
But keep in mind not to optimize before measuring.
Some of the rules are mostly valuable because they demand consistency. If you're consistent the other way, e.g. using arrow functions consistently instead of using function expressions consistently, that is close to as valuable.
TODO