Permalink
373 lines (265 sloc) 9.33 KB

JavaScript Standard Style

Read in: Português Spanish

js-standard-style

This is a TL;DR 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

    function hello (name) {
      console.log('hi', name)
    }
  • Use single quotes for strings except to avoid escaping.

    eslint: quotes

    console.log('hello there')
    $("<div class='box'>")
  • No unused variables.

    eslint: no-unused-vars

    function myFunction () {
      var result = something()   // ✗ avoid
    }
  • Add a space after keywords.

    eslint: keyword-spacing

    if (condition) { ... }   // ✓ ok
    if(condition) { ... }    // ✗ avoid
  • Add a space before a function declaration's parentheses.

    eslint: space-before-function-paren

    function name (arg) { ... }   // ✓ ok
    function name(arg) { ... }    // ✗ avoid
    
    run(function () { ... })      // ✓ ok
    run(function() { ... })       // ✗ avoid
  • Always use === instead of ==.
    Exception: obj == null is allowed to check for null || undefined.

    eslint: eqeqeq

    if (name === 'John')   // ✓ ok
    if (name == 'John')    // ✗ avoid
    if (name !== 'John')   // ✓ ok
    if (name != 'John')    // ✗ avoid
  • Infix operators must be spaced.

    eslint: space-infix-ops

    // ✓ ok
    var x = 2
    var message = 'hello, ' + name + '!'
    // ✗ avoid
    var x=2
    var message = 'hello, '+name+'!'
  • Commas should have a space after them.

    eslint: comma-spacing

    // ✓ ok
    var list = [1, 2, 3, 4]
    function greet (name, options) { ... }
    // ✗ avoid
    var list = [1,2,3,4]
    function greet (name,options) { ... }
  • Keep else statements on the same line as their curly braces.

    eslint: brace-style

    // ✓ ok
    if (condition) {
      // ...
    } else {
      // ...
    }
    // ✗ avoid
    if (condition) {
      // ...
    }
    else {
      // ...
    }
  • For multi-line if statements, use curly braces.

    eslint: curly

    // ✓ ok
    if (options.quiet !== true) console.log('done')
    // ✓ ok
    if (options.quiet !== true) {
      console.log('done')
    }
    // ✗ avoid
    if (options.quiet !== true)
      console.log('done')
  • Always handle the err function parameter.

    eslint: handle-callback-err

    // ✓ ok
    run(function (err) {
      if (err) throw err
      window.alert('done')
    })
    // ✗ avoid
    run(function (err) {
      window.alert('done')
    })
  • Always prefix browser globals with window..
    Exceptions are: document, console and navigator.

    eslint: no-undef

    window.alert('hi')   // ✓ ok
  • Multiple blank lines not allowed.

    eslint: no-multiple-empty-lines

    // ✓ ok
    var value = 'hello world'
    console.log(value)
    // ✗ avoid
    var value = 'hello world'
    
    
    console.log(value)
  • For the ternary operator in a multi-line setting, place ? and : on their own lines.

    eslint: operator-linebreak

    // ✓ 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'
  • For var declarations, write each declaration in its own statement.

    eslint: one-var

    // ✓ 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 (===).

    eslint: no-cond-assign

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

Semicolons

  • No semicolons. (see: 1, 2, 3)

    eslint: semi

    window.alert('hi')   // ✓ ok
    window.alert('hi');  // ✗ avoid
  • Never start a line with (, [, or `. This is the only gotcha with omitting semicolons, and standard protects you from this potential issue.

    eslint: no-unexpected-multiline

    // ✓ ok
    ;(function () {
      window.alert('ok')
    }())
    
    // ✗ avoid
    (function () {
      window.alert('ok')
    }())
    // ✓ ok
    ;[1, 2, 3].forEach(bar)
    
    // ✗ avoid
    [1, 2, 3].forEach(bar)
    // ✓ 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:

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

    This is much preferred:

    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:

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

you could do this:

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.

End quote from "An Open Letter to JavaScript Leaders Regarding Semicolons".