JavaScript Standard Style
English • Español (Latinoamérica) • Français • Italiano (Italian) • 日本語 (Japanese) • 한국어 (Korean) • Português (Brasil) • 简体中文 (Simplified Chinese) • 繁體中文 (Taiwanese Mandarin)
This is a summary of the standard JavaScript rules.
The best way to learn about standard is to just install it and give it a try on
your code.
Rules
-
Use 2 spaces for indentation.
eslint:
indent{console} -
Use single quotes for strings except to avoid escaping.
eslint:
quotesconsole // ✓ okconsole // ✗ avoidconsole // ✗ avoid// ✓ okconsole // ✓ ok -
No unused variables.
eslint:
no-unused-vars{var result = // ✗ avoid} -
Add a space after keywords.
eslint:
keyword-spacingif condition ... // ✓ okifcondition ... // ✗ avoid -
Add a space before a function declaration's parentheses.
eslint:
space-before-function-paren{ ... } // ✓ ok{ ... } // ✗ avoid// ✓ ok// ✗ avoid -
Always use
===instead of==.
Exception:obj == nullis allowed to check fornull || undefined.eslint:
eqeqeqif name === 'John' // ✓ okif name == 'John' // ✗ avoidif name !== 'John' // ✓ okif name != 'John' // ✗ avoid -
Infix operators must be spaced.
eslint:
space-infix-ops// ✓ okvar x = 2var message = 'hello, ' + name + '!'// ✗ avoidvar x=2var message = 'hello, '+name+'!' -
Commas should have a space after them.
eslint:
comma-spacing// ✓ okvar list = 1 2 3 4{ ... }// ✗ avoidvar list = 1234{ ... } -
Keep else statements on the same line as their curly braces.
eslint:
brace-style// ✓ okif condition// ...else// ...// ✗ avoidif condition// ...else// ... -
For multi-line if statements, use curly braces.
eslint:
curly// ✓ okif optionsquiet !== true console// ✓ okif optionsquiet !== trueconsole// ✗ avoidif optionsquiet !== trueconsole -
Always handle the
errfunction parameter.eslint:
handle-callback-err// ✓ 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
windowis okay too, though such code will not run in a Worker which usesselfinstead ofwindow.eslint:
no-undefwindow // ✓ ok -
Multiple blank lines not allowed.
eslint:
no-multiple-empty-lines// ✓ okvar value = 'hello world'console// ✗ avoidvar value = 'hello world'console -
For the ternary operator in a multi-line setting, place
?and:on their own lines.eslint:
operator-linebreak// ✓ okvar location = envdevelopment ? 'localhost' : 'www.api.com'// ✓ okvar location = envdevelopment? 'localhost': 'www.api.com'// ✗ avoidvar location = envdevelopment ?'localhost' :'www.api.com' -
For var declarations, write each declaration in its own statement.
eslint:
one-var// ✓ okvar silent = truevar verbose = true// ✗ avoidvar silent = true verbose = true// ✗ avoidvar silent = trueverbose = true -
Wrap conditional assignments with additional parentheses. This makes it clear that the expression is intentionally an assignment (
=) rather than a typo for equality (===).eslint:
no-cond-assign// ✓ okwhile m = text// ...// ✗ avoidwhile m = text// ... -
Add spaces inside single line blocks.
eslint:
block-spacing{return true} // ✗ avoid{ return true } // ✓ ok -
Use camelcase when naming variables and functions.
eslint:
camelcase{ } // ✗ avoid{ } // ✓ okvar my_var = 'hello' // ✗ avoidvar myVar = 'hello' // ✓ ok -
Trailing commas not allowed.
eslint:
comma-danglevar obj =message: 'hello' // ✗ avoid -
Commas must be placed at the end of the current line.
eslint:
comma-stylevar obj =foo: 'foo'bar: 'bar' // ✗ avoidvar obj =foo: 'foo'bar: 'bar' // ✓ ok -
Dot should be on the same line as property.
eslint:
dot-locationconsole// ✗ avoidconsole// ✓ ok -
Files must end with a newline.
eslint:
eol-last -
No space between function identifiers and their invocations.
eslint:
func-call-spacingconsole // ✗ avoidconsole // ✓ ok -
Add space between colon and value in key value pairs.
eslint:
key-spacingvar obj = 'key' : 'value' // ✗ avoidvar obj = 'key' :'value' // ✗ avoidvar obj = 'key':'value' // ✗ avoidvar obj = 'key': 'value' // ✓ ok -
Constructor names must begin with a capital letter.
eslint:
new-cap{}var dog = // ✗ avoid{}var dog = // ✓ ok -
Constructor with no arguments must be invoked with parentheses.
eslint:
new-parens{}var dog = // ✗ avoidvar dog = // ✓ ok -
Objects must contain a getter when a setter is defined.
eslint:
accessor-pairsvar person ={ // ✗ avoidthis_name = value}var person ={this_name = value}{ // ✓ okreturn this_name} -
Constructors of derived classes must call
super.eslint:
constructor-super{super // ✗ avoidthislegs = 4}{ // ✗ avoidthislegs = 4}{super // ✓ okthislegs = 4} -
Use array literals instead of array constructors.
eslint:
no-array-constructorvar nums = 1 2 3 // ✗ avoidvar nums = 1 2 3 // ✓ ok -
Avoid using
arguments.calleeandarguments.caller.eslint:
no-caller{if n <= 0 returnargumentscalleen - 1 // ✗ avoid}{if n <= 0 return// ✓ ok} -
Avoid modifying variables of class declarations.
eslint:
no-class-assign{}Dog = 'Fido' // ✗ avoid -
Avoid modifying variables declared using
const.eslint:
no-const-assignconst score = 100score = 125 // ✗ avoid -
Avoid using constant expressions in conditions (except loops).
eslint:
no-constant-conditionif false // ✗ avoid// ...if x === 0 // ✓ ok// ...while true // ✓ ok// ... -
No control characters in regular expressions.
eslint:
no-control-regexvar pattern = /\x1f/ // ✗ avoidvar pattern = /\x20/ // ✓ ok -
No
debuggerstatements.eslint:
no-debugger{debugger // ✗ avoidreturn a + b} -
No
deleteoperator on variables.eslint:
no-delete-varvar namedelete name // ✗ avoid -
No duplicate arguments in function definitions.
eslint:
no-dupe-args{ // ✗ avoid// ...}{ // ✓ ok// ...} -
No duplicate name in class members.
eslint:
no-dupe-class-members{}{} // ✗ avoid -
No duplicate keys in object literals.
eslint:
no-dupe-keysvar user =name: 'Jane Doe'name: 'John Doe' // ✗ avoid -
No duplicate
caselabels inswitchstatements.eslint:
no-duplicate-case -
Use a single import statement per module.
eslint:
no-duplicate-imports -
No empty character classes in regular expressions.
eslint:
no-empty-character-classconst myRegex = /^abc[]/ // ✗ avoidconst myRegex = /^abc[a-z]/ // ✓ ok -
No empty destructuring patterns.
eslint:
no-empty-patternconst a: = foo // ✗ avoidconst a: b = foo // ✓ ok -
No using
eval().eslint:
no-eval// ✗ avoidvar result = userpropName // ✓ ok -
No reassigning exceptions in
catchclauses.eslint:
no-ex-assigntry// ...catch ee = 'new value' // ✗ avoidtry// ...catch econst newVal = 'new value' // ✓ ok -
No extending native objects.
eslint:
no-extend-nativeObjectprototypeage = 21 // ✗ avoid -
Avoid unnecessary function binding.
eslint:
no-extra-bindconst name = {} // ✗ avoidconst name = {this} // ✓ ok -
Avoid unnecessary boolean casts.
eslint:
no-extra-boolean-castconst result = trueif !!result // ✗ avoid// ...const result = trueif result // ✓ ok// ... -
No unnecessary parentheses around function expressions.
eslint:
no-extra-parensconst myFunc = { } // ✗ avoidconst myFunc = { } // ✓ ok -
Use
breakto prevent fallthrough inswitchcases.eslint:
no-fallthrough -
No floating decimals.
eslint:
no-floating-decimalconst discount = 5 // ✗ avoidconst discount = 05 // ✓ ok -
Avoid reassigning function declarations.
eslint:
no-func-assign{ }myFunc = myOtherFunc // ✗ avoid -
No reassigning read-only global variables.
eslint:
no-global-assignwindow = {} // ✗ avoid -
No implied
eval().eslint:
no-implied-eval// ✗ avoid// ✓ ok -
No function declarations in nested blocks.
eslint:
no-inner-declarationsif authenticated{} // ✗ avoid -
No invalid regular expression strings in
RegExpconstructors.eslint:
no-invalid-regexpRegExp'[a-z' // ✗ avoidRegExp'[a-z]' // ✓ ok -
No irregular whitespace.
eslint:
no-irregular-whitespace/*<NBSP>*/{} // ✗ avoid -
No using
__iterator__.eslint:
no-iteratorFooprototype {} // ✗ avoid -
No labels that share a name with an in scope variable.
eslint:
no-label-varvar score = 100{score: while true // ✗ avoidscore -= 10if score > 0 continue scorebreak} -
No label statements.
eslint:
no-labelslabel:while truebreak label // ✗ avoid -
No unnecessary nested blocks.
eslint:
no-lone-blocks{// ✗ avoid}{// ✓ ok} -
Avoid mixing spaces and tabs for indentation.
eslint:
no-mixed-spaces-and-tabs -
Do not use multiple spaces except for indentation.
eslint:
no-multi-spacesconst id = 1234 // ✗ avoidconst id = 1234 // ✓ ok -
No multiline strings.
eslint:
no-multi-strconst message = 'Hello \world' // ✗ avoid -
No
newwithout assigning object to a variable.eslint:
no-new// ✗ avoidconst character = // ✓ ok -
No using the
Functionconstructor.eslint:
no-new-funcvar sum = 'a' 'b' 'return a + b' // ✗ avoid -
No using the
Objectconstructor.eslint:
no-new-objectlet config = // ✗ avoid -
No using
new require.eslint:
no-new-requireconst myModule = 'my-module' // ✗ avoid -
No using the
Symbolconstructor.eslint:
no-new-symbolconst foo = 'foo' // ✗ avoid -
No using primitive wrapper instances.
eslint:
no-new-wrappersconst message = 'hello' // ✗ avoid -
No calling global object properties as functions.
eslint:
no-obj-callsconst math = Math // ✗ avoid -
No octal literals.
eslint:
no-octalconst octal = 042 // ✗ avoidconst decimal = 34 // ✓ okconst octalString = '042' // ✓ ok -
No octal escape sequences in string literals.
eslint:
no-octal-escapeconst copyright = 'Copyright \251' // ✗ avoid -
Avoid string concatenation when using
__dirnameand__filename.eslint:
no-path-concatconst pathToFile = __dirname + '/app.js' // ✗ avoidconst pathToFile = path // ✓ ok -
Avoid using
__proto__. UsegetPrototypeOfinstead.eslint:
no-protoconst foo = obj__proto__ // ✗ avoidconst foo = Object // ✓ ok -
No redeclaring variables.
eslint:
no-redeclarelet name = 'John'let name = 'Jane' // ✗ avoidlet name = 'John'name = 'Jane' // ✓ ok -
Avoid multiple spaces in regular expression literals.
eslint:
no-regex-spacesconst regexp = /test value/ // ✗ avoidconst regexp = /test {3}value/ // ✓ okconst regexp = /test value/ // ✓ ok -
Assignments in return statements must be surrounded by parentheses.
eslint:
no-return-assign{return result = a + b // ✗ avoid}{return result = a + b // ✓ ok} -
Avoid assigning a variable to itself
eslint:
no-self-assignname = name // ✗ avoid -
Avoid comparing a variable to itself.
eslint:
no-self-compareif score === score {} // ✗ avoid -
Avoid using the comma operator.
eslint:
no-sequencesif !!test {} // ✗ avoid -
Restricted names should not be shadowed.
eslint:
no-shadow-restricted-nameslet undefined = 'value' // ✗ avoid -
Sparse arrays are not allowed.
eslint:
no-sparse-arrayslet fruits = 'apple' 'orange' // ✗ avoid -
Tabs should not be used
eslint:
no-tabs -
Regular strings must not contain template literal placeholders.
eslint:
no-template-curly-in-stringconst message = 'Hello ${name}' // ✗ avoidconst message = `Hello ` // ✓ ok -
super()must be called before usingthis.eslint:
no-this-before-super{thislegs = 4 // ✗ avoidsuper} -
Only
throwanErrorobject.eslint:
no-throw-literalthrow 'error' // ✗ avoidthrow 'error' // ✓ ok -
Whitespace not allowed at end of line.
eslint:
no-trailing-spaces -
Initializing to
undefinedis not allowed.eslint:
no-undef-initlet name = undefined // ✗ avoidlet namename = 'value' // ✓ ok -
No unmodified conditions of loops.
eslint:
no-unmodified-loop-conditionfor let i = 0; i < itemslength; j++ ... // ✗ avoidfor let i = 0; i < itemslength; i++ ... // ✓ ok -
No ternary operators when simpler alternatives exist.
eslint:
no-unneeded-ternarylet score = val ? val : 0 // ✗ avoidlet score = val || 0 // ✓ ok -
No unreachable code after
return,throw,continue, andbreakstatements.eslint:
no-unreachable{return trueconsole // ✗ avoid} -
No flow control statements in
finallyblocks.eslint:
no-unsafe-finallytry// ...catch e// ...finallyreturn 42 // ✗ avoid -
The left operand of relational operators must not be negated.
eslint:
no-unsafe-negationif !key in obj {} // ✗ avoidif !key in obj {} // ✓ ok -
Avoid unnecessary use of
.call()and.apply().eslint:
no-useless-callsum // ✗ avoid -
Avoid using unnecessary computed property keys on objects.
eslint:
no-useless-computed-keyconst user = 'name': 'John Doe' // ✗ avoidconst user = name: 'John Doe' // ✓ ok -
No unnecessary constructor.
eslint:
no-useless-constructor{ // ✗ avoid} -
No unnecessary use of escape.
eslint:
no-useless-escapelet message = 'Hell\o' // ✗ avoid -
Renaming import, export, and destructured assignments to the same name is not allowed.
eslint:
no-useless-rename -
No whitespace before properties.
eslint:
no-whitespace-before-propertyuser name // ✗ avoidusername // ✓ ok -
No using
withstatements.eslint:
no-withwith val ... // ✗ avoid -
Maintain consistency of newlines between object properties.
eslint:
object-property-newlineconst user =name: 'Jane Doe' age: 30username: 'jdoe86' // ✗ avoidconst user = name: 'Jane Doe' age: 30 username: 'jdoe86' // ✓ okconst user =name: 'Jane Doe'age: 30username: 'jdoe86'// ✓ ok -
No padding within blocks.
eslint:
padded-blocksif user// ✗ avoidconst name =if userconst name = // ✓ ok -
No whitespace between spread operators and their expressions.
eslint:
rest-spread-spacing// ✗ avoid// ✓ ok -
Semicolons must have a space after and no space before.
eslint:
semi-spacingfor let i = 0 ;i < itemslength ;i++ ... // ✗ avoidfor let i = 0; i < itemslength; i++ ... // ✓ ok -
Must have a space before blocks.
eslint:
space-before-blocksif admin... // ✗ avoidif admin ... // ✓ ok -
No spaces inside parentheses.
eslint:
space-in-parens// ✗ avoid// ✓ ok -
Unary operators must have a space after.
eslint:
space-unary-opstypeof!admin // ✗ avoidtypeof !admin // ✓ ok -
Use spaces inside comments.
eslint:
spaced-comment//comment // ✗ avoid// comment // ✓ ok/*comment*/ // ✗ avoid/* comment */ // ✓ ok -
No spacing in template strings.
eslint:
template-curly-spacingconst message = `Hello, ` // ✗ avoidconst message = `Hello, ` // ✓ ok -
Use
isNaN()when checking forNaN.eslint:
use-isnanif price === NaN // ✗ avoidif // ✓ ok -
typeofmust be compared to a valid string.eslint:
valid-typeoftypeof name === 'undefimed' // ✗ avoidtypeof name === 'undefined' // ✓ ok -
Immediately Invoked Function Expressions (IIFEs) must be wrapped.
eslint:
wrap-iifeconst getName = { } // ✗ avoidconst getName = { } // ✓ okconst getName = { } // ✓ ok -
The
*inyield*expressions must have a space before and after.eslint:
yield-star-spacing// ✗ avoid// ✓ ok -
Avoid Yoda conditions.
eslint:
yodaif 42 === age // ✗ avoidif age === 42 // ✓ ok
Semicolons
-
eslint:
semiwindow // ✓ okwindow; // ✗ avoid -
Never start a line with
(,[,`, or a handful of other unlikely possibilities.This is the only gotcha with omitting semicolons, and
standardprotects 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.)eslint:
no-unexpected-multiline// ✓ ok; {window}// ✗ avoid{window}// ✓ ok;1 2 3// ✗ avoid1 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
Helpful reading
- An Open Letter to JavaScript Leaders Regarding Semicolons
- JavaScript Semicolon Insertion – Everything you need to know
And a helpful video:
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,
\nends 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
\nchars in JSON and parenthesized constructs, and withvarstatements 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.