- Use 2 spaces for indentation.
{ console }
- Use single quotes for strings except to avoid escaping.
console // ✓ ok console // ✗ avoid console // ✗ avoid // ✓ ok console // ✓ ok
- No unused variables.
{ var result = // ✗ avoid }
- Add a space after keywords.
if condition ... // ✓ ok if condition ... // ✗ avoid
- Add a space before a function declaration’s parentheses.
{ ... } // ✓ ok { ... } // ✗ avoid // ✓ ok // ✗ avoid
- Always use
===
instead of==
.
Exception:obj == null
is allowed to check fornull || undefined
.if name === 'John' // ✓ ok if name == 'John' // ✗ avoid if name !== 'John' // ✓ ok if name != 'John' // ✗ avoid
- Infix operators must be spaced.
// ✓ ok var x = 2 var message = 'hello, ' + name + '!'
// ✗ avoid var x=2 var message = 'hello, '+name+'!'
- Commas should have a space after them.
// ✓ ok var list = 1 2 3 4 { ... }
// ✗ avoid var list = 1234 { ... }
- Keep else statements on the same line as their curly braces.
// ✓ ok if condition // ... else // ...
// ✗ avoid if condition // ... else // ...
- For multi-line if statements, use curly braces.
// ✓ ok if optionsquiet !== true console
// ✓ ok if optionsquiet !== true console
// ✗ avoid if optionsquiet !== true console
- Always handle the
err
function parameter.// ✓ ok
// ✗ avoid
- Declare browser globals with a
/* global */
comment.
Exceptions are:window
,document
, andnavigator
.
Prevents accidental use of poorly-named browser globals likeopen
,length
,event
, andname
./* global alert, prompt */
Explicitly referencing the function or property on
window
is okay too, though such code will not run in a Worker which usesself
instead ofwindow
.window // ✓ ok
- Multiple blank lines not allowed
// ✓ ok var value = 'hello world' console
// ✗ avoid var value = 'hello world' console
- For the ternary operator in a multi-line setting, place
?
and:
on their own lines.// ✓ ok var location = envdevelopment ? 'localhost' : 'www.api.com' // ✓ ok var location = envdevelopment ? 'localhost' : 'www.api.com' // ✗ avoid var location = envdevelopment ? 'localhost' : 'www.api.com'
- For var declarations, write each declaration in its own statement.
// ✓ ok
var silent = true var verbose = true // ✗ avoid var silent = true verbose = true // ✗ avoid var silent = true verbose = true
- Wrap conditional assignments with additional parentheses. This makes it clear that the expression is intentionally an assignment (
=
) rather than a typo for equality (===
).// ✓ ok
while m = text // ... // ✗ avoid while m = text // ...
- Add spaces inside single line blocks.
{return true} // ✗ avoid { return true } // ✓ ok
- Use camelcase when naming variables and functions.
{ } // ✗ avoid { } // ✓ ok var my_var = 'hello' // ✗ avoid var myVar = 'hello' // ✓ ok
- Trailing commas not allowed.
var obj = message: 'hello' // ✗ avoid
- Commas must be placed at the end of the current line.
var obj = foo: 'foo' : 'bar' // ✗ avoid bar var obj = foo: 'foo' bar: 'bar' // ✓ ok
- Dot should be on the same line as property.
console // ✗ avoid console // ✓ ok
- Files must end with a newline.
- No space between function identifiers and their invocations.
console // ✗ avoid console // ✓ ok
- Add space between colon and value in key value pairs.
var obj = 'key' : 'value' // ✗ avoid var obj = 'key' :'value' // ✗ avoid var obj = 'key':'value' // ✗ avoid var obj = 'key': 'value' // ✓ ok
- Constructor names must begin with a capital letter.
{} var dog = // ✗ avoid
{} var dog = // ✓ ok
- Constructor with no arguments must be invoked with parentheses.
{} var dog = // ✗ avoid var dog = // ✓ ok
- Objects must contain a getter when a setter is defined.
var person = { // ✗ avoid this_name = value }
var person = { this_name = value } { // ✓ ok return this_name }
- Constructors of derived classes must call
super
.{ super // ✗ avoid thislegs = 4 }
{ // ✗ avoid thislegs = 4 }
{ super // ✓ ok thislegs = 4 }
- Use array literals instead of array constructors.
var nums = 1 2 3 // ✗ avoid var nums = 1 2 3 // ✓ ok
- Avoid using
arguments.callee
andarguments.caller
.{ if n <= 0 return argumentscallee n - 1 // ✗ avoid }
{ if n <= 0 return // ✓ ok }
- Avoid modifying variables of class declarations.
{} Dog = 'Fido' // ✗ avoid
- Avoid modifying variables declared using
const
.const score = 100 score = 125 // ✗ avoid
- Avoid using constant expressions in conditions (except loops).
if false // ✗ avoid // ... if x === 0 // ✓ ok // ... while true // ✓ ok // ...
- No control characters in regular expressions.
var pattern = /\x1f/ // ✗ avoid var pattern = /\x20/ // ✓ ok
- No
debugger
statements.{ debugger // ✗ avoid return a + b }
- No
delete
operator on variables.var name delete name // ✗ avoid
- No duplicate arguments in function definitions.
{ // ✗ avoid // ... } { // ✓ ok // ... }
- No duplicate name in class members.
{} {} // ✗ avoid
- No duplicate keys in object literals.
var user = name: 'Jane Doe' name: 'John Doe' // ✗ avoid
- No duplicate
case
labels inswitch
statements. - Use a single import statement per module.
- No empty character classes in regular expressions.
const myRegex = /^abc[]/ // ✗ avoid const myRegex = /^abc[a-z]/ // ✓ ok
- No empty destructuring patterns.
const a: = foo // ✗ avoid const a: b = foo // ✓ ok
- No using
eval()
.// ✗ avoid var result = user propName // ✓ ok
- No reassigning exceptions in
catch
clauses.try // ... catch e e = 'new value' // ✗ avoid
try // ... catch e const newVal = 'new value' // ✓ ok
- No extending native objects.
Objectprototypeage = 21 // ✗ avoid
- Avoid unnecessary function binding.
const name = { } // ✗ avoid
const name = { this } // ✓ ok
- Avoid unnecessary boolean casts.
const result = true if !!result // ✗ avoid // ...
const result = true if result // ✓ ok // ...
- No unnecessary parentheses around function expressions.
const myFunc = { } // ✗ avoid const myFunc = { } // ✓ ok
- Use
break
to prevent fallthrough inswitch
cases. - No floating decimals.
const discount = 5// ✗ avoid const discount = 0 5// ✓ ok
- Avoid reassigning function declarations.
{ } myFunc = myOtherFunc // ✗ avoid
- No reassigning read-only global variables.
window = {} // ✗ avoid
- No implied
eval()
.// ✗ avoid // ✓ ok
- No function declarations in nested blocks.
if authenticated {} // ✗ avoid
- No invalid regular expression strings in
RegExp
constructors.RegExp'[a-z' // ✗ avoid RegExp'[a-z]' // ✓ ok
- No irregular whitespace.
/*<NBSP>*/{} // ✗ avoid
- No using
__iterator__
.Fooprototype {} // ✗ avoid
- No labels that share a name with an in scope variable.
var score = 100 { score: while true // ✗ avoid score -= 10 if score > 0 continue score break }
- No label statements.
label: while true break label // ✗ avoid
- No unnecessary nested blocks.
{ // ✗ avoid }
{ // ✓ ok }
- Avoid mixing spaces and tabs for indentation.
- Do not use multiple spaces except for indentation.
const id = 1234 // ✗ avoid const id = 1234 // ✓ ok
- No multiline strings.
const message = 'Hello \ world' // ✗ avoid
- No
new
without assigning object to a variable.// ✗ avoid const character = // ✓ ok
- No using the
Function
constructor.var sum = 'a' 'b' 'return a + b' // ✗ avoid
- No using the
Object
constructor.let config = // ✗ avoid
- No using
new require
.const myModule = 'my-module' // ✗ avoid
- No using the
Symbol
constructor.const foo = 'foo' // ✗ avoid
- No using primitive wrapper instances.
const message = 'hello' // ✗ avoid
- No calling global object properties as functions.
const math = Math // ✗ avoid
- No octal literals.
const octal = 042 // ✗ avoid const decimal = 34 // ✓ ok const octalString = '042' // ✓ ok
- No octal escape sequences in string literals.
const copyright = 'Copyright \251' // ✗ avoid
- Avoid string concatenation when using
__dirname
and__filename
.const pathToFile = __dirname + '/app.js' // ✗ avoid const pathToFile = path // ✓ ok
- Avoid using
__proto__
. UsegetPrototypeOf
instead.const foo = obj__proto__ // ✗ avoid const foo = Object // ✓ ok
- No redeclaring variables.
let name = 'John' let name = 'Jane' // ✗ avoid let name = 'John' name = 'Jane' // ✓ ok
- Avoid multiple spaces in regular expression literals.
const regexp = /test value/ // ✗ avoid const regexp = /test {3}value/ // ✓ ok const regexp = /test value/ // ✓ ok
- Assignments in return statements must be surrounded by parentheses.
{ return result = a + b // ✗ avoid } { return result = a + b // ✓ ok }
- Avoid assigning a variable to itself.
name = name // ✗ avoid
- Avoid comparing a variable to itself.
if score === score {} // ✗ avoid
- Avoid using the comma operator.
if !!test {} // ✗ avoid
- Restricted names should not be shadowed.
let undefined = 'value' // ✗ avoid
- Sparse arrays are not allowed.
let fruits = 'apple' 'orange' // ✗ avoid
- Tabs should not be used.
- Regular strings must not contain template literal placeholders.
const message = 'Hello ${name}' // ✗ avoid const message = `Hello ` // ✓ ok
super()
must be called before usingthis
.{ thislegs = 4 // ✗ avoid super }
- Only
throw
anError
object.throw 'error' // ✗ avoid throw 'error' // ✓ ok
- Whitespace not allowed at end of line.
- Initializing to
undefined
is not allowed.let name = undefined // ✗ avoid let name name = 'value' // ✓ ok
- No unmodified conditions of loops.
for let i = 0; i < itemslength; j++ ... // ✗ avoid for let i = 0; i < itemslength; i++ ... // ✓ ok
- No ternary operators when simpler alternatives exist.
let score = val ? val : 0 // ✗ avoid let score = val || 0 // ✓ ok
- No unreachable code after
return
,throw
,continue
, andbreak
statements.{ return true console // ✗ avoid }
- No flow control statements in
finally
blocks.try // ... catch e // ... finally return 42 // ✗ avoid
- The left operand of relational operators must not be negated.
if !key in obj {} // ✗ avoid if ! key in obj {} // ✓ ok
- Avoid unnecessary use of
.call()
and.apply()
.sum // ✗ avoid
- Avoid using unnecessary computed property keys on objects.
const user = 'name': 'John Doe' // ✗ avoid const user = name: 'John Doe' // ✓ ok
- No unnecessary constructor.
{ // ✗ avoid }
- No unnecessary use of escape.
let message = 'Hell\o' // ✗ avoid
- Renaming import, export, and destructured assignments to the same name is not allowed.
- No whitespace before properties.
user name // ✗ avoid username // ✓ ok
- No using
with
statements.with val ... // ✗ avoid
- Maintain consistency of newlines between object properties.
const user = name: 'Jane Doe' age: 30 username: 'jdoe86' // ✗ avoid const user = name: 'Jane Doe' age: 30 username: 'jdoe86' // ✓ ok const user = name: 'Jane Doe' age: 30 username: 'jdoe86' // ✓ ok
- No padding within blocks.
if user // ✗ avoid const name = if user const name = // ✓ ok
- No whitespace between spread operators and their expressions.
// ✗ avoid // ✓ ok
- Semicolons must have a space after and no space before.
for let i = 0 ;i < itemslength ;i++ ... // ✗ avoid for let i = 0; i < itemslength; i++ ... // ✓ ok
- Must have a space before blocks.
if admin... // ✗ avoid if admin ... // ✓ ok
- No spaces inside parentheses.
// ✗ avoid // ✓ ok
- Unary operators must have a space after.
typeof!admin // ✗ avoid typeof !admin // ✓ ok
- Use spaces inside comments.
//comment // ✗ avoid // comment // ✓ ok
/*comment*/ // ✗ avoid /* comment */ // ✓ ok
- No spacing in template strings.
const message = `Hello, ` // ✗ avoid const message = `Hello, ` // ✓ ok
- Use
isNaN()
when checking forNaN
.if price === NaN // ✗ avoid if // ✓ ok
typeof
must be compared to a valid string.typeof name === 'undefimed' // ✗ avoid typeof name === 'undefined' // ✓ ok
- Immediately Invoked Function Expressions (IIFEs) must be wrapped.
const getName = { } // ✗ avoid const getName = { } // ✓ ok const getName = { } // ✓ ok
- The
*
inyield*
expressions must have a space before and after.// ✗ avoid // ✓ ok
- Avoid Yoda conditions.
if 42 === age // ✗ avoid if age === 42 // ✓ ok
Semicolons
- No semicolons. (see: 1, 2, 3)eslint:
semi
window // ✓ okwindow; // ✗ avoid - Never start a line with
(
,[
,`
, or a handful of other unlikely possibilities.This is the only gotcha with omitting semicolons, andstandard
protects you from this potential issue.(The full list is:[
,(
,`
,+
,*
,/
,-
,,
,.
, but most of these will never appear at the start of a line in real code.)// ✓ ok ; { window } // ✗ avoid { window }
// ✓ ok ;1 2 3 // ✗ avoid 1 2 3
// ✓ ok ;`hello` // ✗ avoid `hello`
Note: If you’re often writing code like this, you may be trying to be too clever.
Clever short-hands are discouraged, in favor of clear and readable expressions, whenever possible.
Instead of this:
;1 2 3This is strongly preferred:
var nums = 1 2 3nums
All popular code minifiers in use today use AST-based minification, so they can handle semicolon-less JavaScript with no issues (since semicolons are not required in JavaScript).
Excerpt from “An Open Letter to JavaScript Leaders Regarding Semicolons”:
[Relying on automatic semicolon insertion] is quite safe, and perfectly valid JS that every browser understands. Closure compiler, yuicompressor, packer, and jsmin all can properly minify it. There is no performance impact anywhere.
I am sorry that, instead of educating you, the leaders in this language community have given you lies and fear. That was shameful. I recommend learning how statements in JS are actually terminated (and in which cases they are not terminated), so that you can write code that you find beautiful.
In general,
\n
ends a statement unless:
- The statement has an unclosed paren, array literal, or object literal or ends in some other way that is not a valid way to end a statement. (For instance, ending with
.
or,
.)- The line is
--
or++
(in which case it will decrement/increment the next token.)- It is a
for()
,while()
,do
,if()
, orelse
, and there is no{
- The next line starts with
[
,(
,+
,*
,/
,-
,,
,.
, or some other binary operator that can only be found between two tokens in a single expression.The first is pretty obvious. Even JSLint is ok with
\n
chars in JSON and parenthesized constructs, and withvar
statements that span multiple lines ending in,
.The second is super weird. I’ve never seen a case (outside of these sorts of conversations) where you’d want to do write
i\n++\nj
, but, point of fact, that’s parsed asi; ++j
, noti++; j
.The third is well understood, if generally despised.
if (x)\ny()
is equivalent toif (x) { y() }
. The construct doesn’t end until it reaches either a block, or a statement.
;
is a valid JavaScript statement, soif(x);
is equivalent toif(x){}
or, “If x, do nothing.” This is more commonly applied to loops where the loop check also is the update function. Unusual, but not unheard of.The fourth is generally the fud-inducing “oh noes, you need semicolons!” case. But, as it turns out, it’s quite easy to prefix those lines with semicolons if you don’t mean them to be continuations of the previous line. For example, instead of this:
;123;you could do this:
;123The advantage is that the prefixes are easier to notice, once you are accustomed to never seeing lines starting with
(
or[
without semis.