- I prefer projects to be four space indents, though you can convince me to use tabs if we're starting a project together.
- Opening brackets do not belong on their own line.
- Spaces go on both sides of operators, always.
- Spaces never go on the inside of parenthesis except for curly braces of single line functions.
- That said, single line function expressions/declarations should be avoided. Mostly their usecase is IRC.
Semicolons are not optional. JavaScript has Automatic Semicolon Insertion, but that's a sloppy code allowance algorithm, not something you should rely on.
If you can, use map
, filter
, reduce
, etc. If you cannot, create functions for the abstract operation you are doing, and write the domain specific code using those. There should never be a for
loop inside your domain code.
- Always use double quoted strings. JSON, among other languages, only works with double quoted strings, and using single quoted strings makes it harder to transfer the strings to these other formats. Even when it would make no sense to transfer, having two syntactic forms for doing the same thing makes no sense.
- Do not use the multi-line string functionality added by EcmaScript 5. Use
\n
or multiple strings instead. - When creating strings by splicing together literals and variables, use a
format
function like Node'sutil.format
.
- Never use
new
. With EcmaScript 5, it could be written as a function, but as a syntactic form, it hinders expressiveness and readability. Exception is made with initializing objects from the standard library and other libraries. - Try to avoid using
this
when possible. Implicitly passed state is hard to reason about.
++
&--
. These operators are not worth their weight in ink, brain cell matter, potential bugs, ect.|
,&
,^
unless you are working primarily with binary data.!!
and other clever combinations of operators. Just useBoolean()
or the equivalent. It's more readable in the long run.switch
. Use object dispatch instead. There are rare casesswitch
is more readable, and can be used. In that case, whitespace can also be used for lining things up.
The only errors that should be thrown are programmer errors. For instance, a function that takes an object with specfic properties on it and stores it in a database can throw if not all of those properties are there. But if a function takes user input for a command and then finds it cannot executes it because the user doesn't have the necessary permissions, a Result (see r-result
on npm) should be returned with the failure reason instead.
In a Promise<T, E>, return
is to resolve
as throw
is to reject
.
Sweet.js is a great language for adding macros to JavaScript. There's no style qualms about using them. Just don't make your own language.
JavaScript has parametric polymorphism such that a function argument can take any value, and you can inspect the value to figure out what type it is, and dispatch behavior on it.
Parametric polymorphism should only be used to normalize the parameters so that you can provide more features to an already published function or to allow callers to not have to box up data when they only need to pass a single non-defaultable primitive value.
- For trivial cases and precondition failures, return early. Do not have an
if
statement where one side is a single linereturn
and the other is not.