JavaScript Standard Style

EnglishEspañol (Latinoamérica)FrançaisBahasa IndonesiaItaliano (Italian)日本語 (Japanese)한국어 (Korean)Português (Brasil)简体中文 (Simplified Chinese)繁體中文 (Taiwanese Mandarin)

js-standard-style

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

eslint: indent

js function hello (name) { console.log('hi', name) }

eslint: quotes

``js console.log('hello there') // ✓ ok console.log("hello there") // ✗ avoid console.log(hello there`) // ✗ avoid

$("

") // ✓ ok console.log(hello ${name}) // ✓ ok ```

eslint: no-unused-vars

js function myFunction () { var result = something() // ✗ avoid }

eslint: keyword-spacing

js if (condition) { ... } // ✓ ok if(condition) { ... } // ✗ avoid

eslint: space-before-function-paren

```js function name (arg) { ... } // ✓ ok function name(arg) { ... } // ✗ avoid

run(function () { ... }) // ✓ ok run(function() { ... }) // ✗ avoid ```

eslint: eqeqeq

js if (name === 'John') // ✓ ok if (name == 'John') // ✗ avoid

js if (name !== 'John') // ✓ ok if (name != 'John') // ✗ avoid

eslint: space-infix-ops

js // ✓ ok var x = 2 var message = 'hello, ' + name + '!'

js // ✗ avoid var x=2 var message = 'hello, '+name+'!'

eslint: comma-spacing

js // ✓ ok var list = [1, 2, 3, 4] function greet (name, options) { ... }

js // ✗ avoid var list = [1,2,3,4] function greet (name,options) { ... }

eslint: brace-style

js // ✓ ok if (condition) { // ... } else { // ... }

js // ✗ avoid if (condition) { // ... } else { // ... }

eslint: curly

js // ✓ ok if (options.quiet !== true) console.log('done')

js // ✓ ok if (options.quiet !== true) { console.log('done') }

js // ✗ avoid if (options.quiet !== true) console.log('done')

eslint: handle-callback-err js // ✓ ok run(function (err) { if (err) throw err window.alert('done') })

js // ✗ avoid run(function (err) { window.alert('done') })

```js / global alert, prompt /

alert('hi') prompt('ok?') ```

Explicitly referencing the function or property on window is okay too, though such code will not run in a Worker which uses self instead of window.

eslint: no-undef

js window.alert('hi') // ✓ ok

eslint: no-multiple-empty-lines

js // ✓ ok var value = 'hello world' console.log(value)

js // ✗ avoid var value = 'hello world' // blank line // blank line console.log(value)

eslint: operator-linebreak

```js // ✓ ok var location = env.development ? 'localhost' : 'www.api.com'

// ✓ ok var location = env.development ? 'localhost' : 'www.api.com'

// ✗ avoid var location = env.development ? 'localhost' : 'www.api.com' ```

eslint: one-var

```js // ✓ ok var silent = true var verbose = true

// ✗ avoid var silent = true, verbose = true

// ✗ avoid var silent = true, verbose = true ```

eslint: no-cond-assign

```js // ✓ ok while ((m = text.match(expr))) { // ... }

// ✗ avoid while (m = text.match(expr)) { // ... } ```

eslint: block-spacing

js function foo () {return true} // ✗ avoid function foo () { return true } // ✓ ok

eslint: camelcase

```js function my_function () { } // ✗ avoid function myFunction () { } // ✓ ok

var my_var = 'hello'           // ✗ avoid
var myVar = 'hello'            // ✓ ok

```

eslint: comma-dangle

js var obj = { message: 'hello', // ✗ avoid }

eslint: comma-style

```js var obj = { foo: 'foo' ,bar: 'bar' // ✗ avoid }

var obj = {
  foo: 'foo',
  bar: 'bar'   // ✓ ok
}

```

eslint: dot-location

```js console. log('hello') // ✗ avoid

console
  .log('hello') // ✓ ok

```

eslint: eol-last

eslint: func-call-spacing

js console.log ('hello') // ✗ avoid console.log('hello') // ✓ ok

eslint: key-spacing

js var obj = { 'key' : 'value' } // ✗ avoid var obj = { 'key' :'value' } // ✗ avoid var obj = { 'key':'value' } // ✗ avoid var obj = { 'key': 'value' } // ✓ ok

eslint: new-cap

```js function animal () {} var dog = new animal() // ✗ avoid

function Animal () {} var dog = new Animal() // ✓ ok ```

eslint: new-parens

js function Animal () {} var dog = new Animal // ✗ avoid var dog = new Animal() // ✓ ok

eslint: accessor-pairs

```js var person = { set name (value) { // ✗ avoid this._name = value } }

var person = { set name (value) { this._name = value }, get name () { // ✓ ok return this._name } } ```

eslint: constructor-super

```js class Dog { constructor () { super() // ✗ avoid this.legs = 4 } }

class Dog extends Animal { constructor () { // ✗ avoid this.legs = 4 } }

class Dog extends Animal { constructor () { super() // ✓ ok this.legs = 4 } } ```

eslint: no-array-constructor

js var nums = new Array(1, 2, 3) // ✗ avoid var nums = [1, 2, 3] // ✓ ok

eslint: no-caller

```js function foo (n) { if (n <= 0) return

arguments.callee(n - 1)   // ✗ avoid

}

function foo (n) { if (n <= 0) return

foo(n - 1)                // ✓ ok

} ```

eslint: no-class-assign

js class Dog {} Dog = 'Fido' // ✗ avoid

eslint: no-const-assign

js const score = 100 score = 125 // ✗ avoid

eslint: no-constant-condition

```js if (false) { // ✗ avoid // ... }

if (x === 0) { // ✓ ok // ... }

while (true) { // ✓ ok // ... } ```

eslint: no-control-regex

js var pattern = /\x1f/ // ✗ avoid var pattern = /\x20/ // ✓ ok

eslint: no-debugger

js function sum (a, b) { debugger // ✗ avoid return a + b }

eslint: no-delete-var

js var name delete name // ✗ avoid

eslint: no-dupe-args

```js function sum (a, b, a) { // ✗ avoid // ... }

function sum (a, b, c) { // ✓ ok // ... } ```

eslint: no-dupe-class-members

js class Dog { bark () {} bark () {} // ✗ avoid }

eslint: no-dupe-keys

js var user = { name: 'Jane Doe', name: 'John Doe' // ✗ avoid }

eslint: no-duplicate-case

js switch (id) { case 1: // ... case 1: // ✗ avoid }

eslint: no-duplicate-imports

```js import { myFunc1 } from 'module' import { myFunc2 } from 'module' // ✗ avoid

import { myFunc1, myFunc2 } from 'module' // ✓ ok ```

eslint: no-empty-character-class

js const myRegex = /^abc[]/ // ✗ avoid const myRegex = /^abc[a-z]/ // ✓ ok

eslint: no-empty-pattern

js const { a: {} } = foo // ✗ avoid const { a: { b } } = foo // ✓ ok

eslint: no-eval

js eval( "var result = user." + propName ) // ✗ avoid var result = user[propName] // ✓ ok

eslint: no-ex-assign

```js try { // ... } catch (e) { e = 'new value' // ✗ avoid }

try { // ... } catch (e) { const newVal = 'new value' // ✓ ok } ```

eslint: no-extend-native

js Object.prototype.age = 21 // ✗ avoid

eslint: no-extra-bind

```js const name = function () { getName() }.bind(user) // ✗ avoid

const name = function () { this.getName() }.bind(user) // ✓ ok ```

eslint: no-extra-boolean-cast

```js const result = true if (!!result) { // ✗ avoid // ... }

const result = true if (result) { // ✓ ok // ... } ```

eslint: no-extra-parens

js const myFunc = (function () { }) // ✗ avoid const myFunc = function () { } // ✓ ok

eslint: no-fallthrough

```js switch (filter) { case 1: doSomething() // ✗ avoid case 2: doSomethingElse() }

switch (filter) { case 1: doSomething() break // ✓ ok case 2: doSomethingElse() }

switch (filter) { case 1: doSomething() // fallthrough // ✓ ok case 2: doSomethingElse() } ```

eslint: no-floating-decimal

js const discount = .5 // ✗ avoid const discount = 0.5 // ✓ ok

eslint: no-func-assign

js function myFunc () { } myFunc = myOtherFunc // ✗ avoid

eslint: no-global-assign

js window = {} // ✗ avoid

eslint: no-implied-eval

js setTimeout("alert('Hello world')") // ✗ avoid setTimeout(function () { alert('Hello world') }) // ✓ ok

eslint: no-inner-declarations

js if (authenticated) { function setAuthUser () {} // ✗ avoid }

eslint: no-invalid-regexp

js RegExp('[a-z') // ✗ avoid RegExp('[a-z]') // ✓ ok

eslint: no-irregular-whitespace

js function myFunc () /*<NBSP>*/{} // ✗ avoid

eslint: no-iterator

js Foo.prototype.__iterator__ = function () {} // ✗ avoid

eslint: no-label-var

js var score = 100 function game () { score: while (true) { // ✗ avoid score -= 10 if (score > 0) continue score break } }

eslint: no-labels

js label: while (true) { break label // ✗ avoid }

eslint: no-lone-blocks

```js function myFunc () { { // ✗ avoid myOtherFunc() } }

function myFunc () { myOtherFunc() // ✓ ok } ```

eslint: no-mixed-spaces-and-tabs

eslint: no-multi-spaces

js const id = 1234 // ✗ avoid const id = 1234 // ✓ ok

eslint: no-multi-str

js const message = 'Hello \ world' // ✗ avoid

eslint: no-new

js new Character() // ✗ avoid const character = new Character() // ✓ ok

eslint: no-new-func

js var sum = new Function('a', 'b', 'return a + b') // ✗ avoid

eslint: no-new-object

js let config = new Object() // ✗ avoid

eslint: no-new-require

js const myModule = new require('my-module') // ✗ avoid

eslint: no-new-symbol

js const foo = new Symbol('foo') // ✗ avoid

eslint: no-new-wrappers

js const message = new String('hello') // ✗ avoid

eslint: no-obj-calls

js const math = Math() // ✗ avoid

eslint: no-octal

js const octal = 042 // ✗ avoid const decimal = 34 // ✓ ok const octalString = '042' // ✓ ok

eslint: no-octal-escape

js const copyright = 'Copyright \251' // ✗ avoid

eslint: no-path-concat

js const pathToFile = __dirname + '/app.js' // ✗ avoid const pathToFile = path.join(__dirname, 'app.js') // ✓ ok

eslint: no-proto

js const foo = obj.__proto__ // ✗ avoid const foo = Object.getPrototypeOf(obj) // ✓ ok

eslint: no-redeclare

```js let name = 'John' let name = 'Jane' // ✗ avoid

let name = 'John' name = 'Jane' // ✓ ok ```

eslint: no-regex-spaces

```js const regexp = /test value/ // ✗ avoid

const regexp = /test {3}value/ // ✓ ok const regexp = /test value/ // ✓ ok ```

eslint: no-return-assign

```js function sum (a, b) { return result = a + b // ✗ avoid }

function sum (a, b) { return (result = a + b) // ✓ ok } ```

eslint: no-self-assign

js name = name // ✗ avoid

eslint: no-self-compare

js if (score === score) {} // ✗ avoid

eslint: no-sequences

js if (doSomething(), !!test) {} // ✗ avoid

eslint: no-shadow-restricted-names

js let undefined = 'value' // ✗ avoid

eslint: no-sparse-arrays

js let fruits = ['apple',, 'orange'] // ✗ avoid

eslint: no-tabs

eslint: no-template-curly-in-string

js const message = 'Hello ${name}' // ✗ avoid const message = `Hello ${name}` // ✓ ok

eslint: no-this-before-super

js class Dog extends Animal { constructor () { this.legs = 4 // ✗ avoid super() } }

eslint: no-throw-literal

js throw 'error' // ✗ avoid throw new Error('error') // ✓ ok

eslint: no-trailing-spaces

eslint: no-undef-init

```js let name = undefined // ✗ avoid

let name name = 'value' // ✓ ok ```

eslint: no-unmodified-loop-condition

js for (let i = 0; i < items.length; j++) {...} // ✗ avoid for (let i = 0; i < items.length; i++) {...} // ✓ ok

eslint: no-unneeded-ternary

js let score = val ? val : 0 // ✗ avoid let score = val || 0 // ✓ ok

eslint: no-unreachable

js function doSomething () { return true console.log('never called') // ✗ avoid }

eslint: no-unsafe-finally

js try { // ... } catch (e) { // ... } finally { return 42 // ✗ avoid }

eslint: no-unsafe-negation

js if (!key in obj) {} // ✗ avoid if (!(key in obj)) {} // ✓ ok

eslint: no-useless-call

js sum.call(null, 1, 2, 3) // ✗ avoid

eslint: no-useless-computed-key

js const user = { ['name']: 'John Doe' } // ✗ avoid const user = { name: 'John Doe' } // ✓ ok

eslint: no-useless-constructor

js class Car { constructor () { // ✗ avoid } }

eslint: no-useless-escape

js let message = 'Hell\o' // ✗ avoid

eslint: no-useless-rename

js import { config as config } from './config' // ✗ avoid import { config } from './config' // ✓ ok

eslint: no-whitespace-before-property

js user .name // ✗ avoid user.name // ✓ ok

eslint: no-with

js with (val) {...} // ✗ avoid

eslint: object-property-newline

```js 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 ```

eslint: padded-blocks

```js if (user) { // ✗ avoid const name = getName()

}

if (user) { const name = getName() // ✓ ok } ```

eslint: rest-spread-spacing

js fn(... args) // ✗ avoid fn(...args) // ✓ ok

eslint: semi-spacing

js for (let i = 0 ;i < items.length ;i++) {...} // ✗ avoid for (let i = 0; i < items.length; i++) {...} // ✓ ok

eslint: space-before-blocks

js if (admin){...} // ✗ avoid if (admin) {...} // ✓ ok

eslint: space-in-parens

js getName( name ) // ✗ avoid getName(name) // ✓ ok

eslint: space-unary-ops

js typeof!admin // ✗ avoid typeof !admin // ✓ ok

eslint: spaced-comment

```js //comment // ✗ avoid // comment // ✓ ok

/comment/ // ✗ avoid / comment / // ✓ ok ```

eslint: template-curly-spacing

js const message = `Hello, ${ name }` // ✗ avoid const message = `Hello, ${name}` // ✓ ok

eslint: use-isnan

js if (price === NaN) { } // ✗ avoid if (isNaN(price)) { } // ✓ ok

eslint: valid-typeof

js typeof name === 'undefimed' // ✗ avoid typeof name === 'undefined' // ✓ ok

eslint: wrap-iife

```js const getName = function () { }() // ✗ avoid

const getName = (function () { }()) // ✓ ok const getName = (function () { })() // ✓ ok ```

eslint: yield-star-spacing

js yield* increment() // ✗ avoid yield * increment() // ✓ ok

eslint: yoda

js if (42 === age) { } // ✗ avoid if (age === 42) { } // ✓ ok

Semicolons

eslint: semi

js window.alert('hi') // ✓ ok window.alert('hi'); // ✗ avoid

This is the only gotcha with omitting semicolons, and standard 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.)

eslint: no-unexpected-multiline

```js // ✓ ok ;(function () { window.alert('ok') }())

// ✗ avoid (function () { window.alert('ok') }()) ```

```js // ✓ ok ;[1, 2, 3].forEach(bar)

// ✗ avoid [1, 2, 3].forEach(bar) ```

``js // ✓ ok ;hello`.indexOf('o')

// ✗ avoid hello.indexOf('o') ```

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:

js ;[1, 2, 3].forEach(bar)

This is strongly preferred:

js var nums = [1, 2, 3] nums.forEach(bar)

Helpful reading

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, \n ends a statement unless: 1. 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 ,.) 2. The line is -- or ++ (in which case it will decrement/increment the next token.) 3. It is a for(), while(), do, if(), or else, and there is no { 4. 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 with var 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 as i; ++j, not i++; j.

The third is well understood, if generally despised. if (x)\ny() is equivalent to if (x) { y() }. The construct doesn’t end until it reaches either a block, or a statement.

; is a valid JavaScript statement, so if(x); is equivalent to if(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:

js foo(); [1,2,3].forEach(bar);

you could do this:

js foo() ;[1,2,3].forEach(bar)

The advantage is that the prefixes are easier to notice, once you are accustomed to never seeing lines starting with ( or [ without semis.