152 comments

[ 2.5 ms ] story [ 244 ms ] thread
This is the ES6 guide I send around to those who are trying to get up to speed with JavaScript -- its fantastic.
Having seen this updated version I'm not terribly impressed at their guide for ES6. No mention of symbols (which are pretty important if you're using classes), generators are ignored almost entirely, a pretty poor explanation of modules, etc.
You're in luck! They published this in GitHub so you can suggest changes you think might make things better.
This has always been one characteristic of open source standpoints that I'm not such a big fan of. It's too tightly coupled to expect everyone with constructive criticism to also contribute. Yes, it would be good if they did. But it would strike a serious blow to many projects' mental capital if the only feedback they took from users was from those users capable (either technically or in possession of enough free time) of contributing the changes themselves.
Well, style guides are fairly subjective projects compared to most other open source projects, so while it might be worth my while suggesting things, it's not likely airbnb is going to change their style guide because I think differently to them.

Edit: Looking at some issues in the style guide repo, AirBnB seems reluctant to add or change the style guide to deviate from what they do internally (for instance, generators are rarely used, therefore they aren't encouraged).

Did you even read it? They don't use the meme 'symbols' but clearly mention 'dynamic property names'.

https://github.com/airbnb/javascript#3.4

Dynamic property names are quite different to Symbols in ECMAScript 6.
Use a global const for keygen, 'symbol' is most likely just a syntactic sugar for global const...
Well a Symbol is guaranteed to be unique (unless you use the symbol registry) and can't be converted to a string - things that you can't say about a global const that is a string.
Um:

> Don't use generators for now.

>> Why? They don't transpile well to ES5.

Same thing with Symbols?

Why are they worried about working by reference on numbers?

  // bad
  var a = 1;
  var b = 2;

  // good
  const a = 1;
  const b = 2;
Assuming I'm not misunderstanding your question, it appears to cover that right above the snippet:

"Why? This ensures that you can't reassign your references (mutation), which can lead to bugs and difficult to comprehend code."

So it's not about working by reference but avoiding inadvertent reassignment and resulting unpredictability.

> Assuming I'm not misunderstanding your question

Numbers are not passed by reference.

It's a lazy example, that has the potential to confuse. I would agree with the downvoters I'm being petty, but c'mon... it's the very first thing you read in your JavaScript guide & it's flawed.

In JS `const` just means that you can't reassign that variable, not that the value it references can't change:

  const a = {foo: 5};
  a.foo = 42; // This is perfectly valid.
  a = 'nope'; // But this isn't. It raises a SyntaxError.
The purpose of the code wasn't to illustrate how to use const.

It was to show how they want you to always use const with complex types.

'const' is misleading, it doesn't set your variables as immutable. Fine for expression, but not for actual practicality.
It does set your variables as immutable, just not your values. It makes sense if you see variables in these languages for what they are: references to values.
Love this guide. Adhere to it as tightly as possible for most new projects, saves a lot of mental overhead. Use the ES5 version for team frontend projects. :)
Amen! Though I am partial to idiomatic.js' whitespace suggestions:

https://github.com/rwaldron/idiomatic.js#spacing

Much easier to skim/parse quickly, at least for me.

No, no, no, this has to go away. The insertion of spaces before ) and after ( is something I see from time to time in JS code, and it is really difficult for me to read. Three.js unfortunately uses this, and mrdoob even has his own style guide. His style guide is probably the only thing I don't like about his work.

No school I've studied or worked at teaches this style, and JS traditionally has never been written like this[1][2]. And now I see it elsewhere as well. In some Java projects, for example. Where does this come from?

There are currently no known hard facts (conclusions from studies) about which of the whitespace styles have the best readability. So let's just all stick to the most common way of doing things, shall we :)

  [1] JavaScript The Good Parts
  [2] Google JS Style Guide http://google.github.io/styleguide/javascriptguide.xml
I agree. 'Cramped' there is more 'readable' to me. This is probably a matter of personal preference.
Ah, C layout orthodoxy at its finest: shove as much crap separated only by operators without whitespace on one line as you can. (not exactly what you said, but I'm extrapolating uncharitably)

I guess you could lampoon me as COBOL orthdoxy, liking spaces between symbols, but Lisp was good at using whitespace, rather than commas, between symbols as well.

The fact that `typeof` is no longer safe [1][2] is news to me - it feels like they put in air bags and removed the seat belts.

  [1]: https://github.com/airbnb/javascript#14.1
  [2]: http://es-discourse.com/t/why-typeof-is-no-longer-safe/15
That's... interesting. I guess it makes a little sense -- `let` seems to be for developers who don't like `var` semantics. Usually that seems to be about wanting block instead of function scope, but maybe there's a contingent that dislikes `undefined` too.
`let` doesn't disappear `undefined` though.

    >> let a;
    >> a;
    undefined
The only code affected by this would be code that uses typeof to check for the existence of a variable the same code defines later, which sounds like dumb code to begin with. I don't think there's any valid uses of typeof on possibly undefined variables besides checking for browser built-ins.
Using typeof(foo) === "undefined" is actually something that comes from back when it was pretty common to pollute the global namespace. There were actual javascript plugins/libraries/snippets that defined undefined and thus broke code that compared to it.
It's not an issue since using a non-hoisted variable before it was declared is an error.

Your editor should immediately highlight this error with a squiggly line.

I'd like to see the justifications for some of these, particularly 3.5 which I see as only obscuring that the current context is a function.
Major advantage: fewer characters to type and parse (parse with your eyes, that is).

Major disadvantage: in the short term it might be difficult to parse.

Possible additional major disadvantage: programmers may never adapt and find it difficult to parse for ever more.

Yeah, I'm not sold on "fewer characters" as a win. 'cause then we can have the code golf arguments that inevitably get into the nutty realm.

For visual parsing, consistency matters. In an object literal dec I expect:

  name : value
That's easy to parse visually. Not good is when suddenly we get:

  nameandvalue(){
in the space that our brain expects the former.
I didn't know you could do this!

      // good
      const obj = {
        id: 5,
        name: 'San Francisco',
        [getKey('enabled')]: true,
      };
Next to arrow functions and optional arguments, better object syntax is one of the big reasons you should be using Babel today. You know how sometimes you need to precalculate values that are going to be returned in an object, so at the end of the function, you return something like this?

  return {
    foo: foo,
    bar: bar,
    baz: baz
  };
You don't have to do that in ES6.

  return {foo, bar, baz};
Keys without values use variables with the same name as their values.
Yep, computed property names is another ES6 feature
Maybe this is the IPA talking, but I don't think I ever want to work at a company with a style guide again.

This is no worse that others I've seen, but they all codify what some group found useful at some point in time, and then that becomes Company Policy set in stone for the rest of time.

At 472 commits my guess is it's truly a "guide" rather than a rulebook and a living, changing one at that!
It looks like airbnb does a good job updating theirs, but I can sympathize with the parent comment. I've found coding style guides that end up obtuse, easily outdated, and arbitrarily fit to the preferences of it's creators. They often stagnate and are blindly followed just for the sake of following. A lot of the best practices in the document are things that should be screened for at the hiring stage, and many of the others are heavily debatable preferences that are only going to make a developer with an opposing opinion feel needlessly boxed.

Not that they are a bad thing and airbnb's looks really solid to me, but writing a coding style guide means you now need to maintain and curate it periodically – a process that is easy to neglect.

The alternative is that every coder has their own style and over time every file becomes random and wildly inconsistent. That doesn't sound good to me either.
It makes sense to me that each team decides their coding standard.

5 or 20 engineers who work in the same code base should have some more or less formal standards for that code.

There's a middle ground though.

On my team, the long-standing rule is that you need to make a best effort to stick to the module's existing style. So we're not gonna bust your balls because you don't split at exactly 100 characters or whatever... but if you never wrap your lines and if you insist on indenting things completely differently than everyone else then yeah, you're creating a problem.

It also helps that our "style guide" is pretty minimal. Brace conventions, indentation, spaces before conditions, etc. Things that have a serious impact on readability and ease of debugging and that can easily be auto-formatted. What we don't specify is the higher order stuff -- provided you are internally consistent. We don't mind if API A uses one naming scheme and API B uses another, provided that we don't have a mix of different ones in the same API. Same for how something like object extension is handled. This falls into the realm of "we assume our developers will make the best technical choice", but so far it works.

There's always a complaint that specifying the braces, spacing, etc. is stupid, and if it required a lot of human intervention or was treated as a serious offense I'd agree. For us it doesn't, and it's not. The purpose is to limit the amount of visual friction when switching from one file to another. What the code is doing is the important part -- presentation should be as uniform as possible to limit distraction. Add in the fact that we've got an Eclipse profile with all the spacing, etc. setup the way that we do it, and it's pretty easy to keep things tidy.

I can see both sides. I hate it when code is all over the place, different files indented in different ways, no consistency on bracket placement, etc. But then again, I just hate it when rules grow so strict you can't ever break them. For example when line like this in strictly-pep8-compiliant codebase:

    return "some very long string"
is exactly 81 characters long. I'd much rather place some "# ignore this" comment on it than break a line there, forcing a "\" after return.
Genuine question: Do people still adhere to 80 character limits for lines? I expected that everyone would have relaxed those with all the extra resolution we have. I use 100 at work.
Yes. Some almost religiously.
I like using split panes in my editor: When I'm not at my desk, I can just fit two 80 character panes in. When I'm at my desk I can fit three!

I don't follow it religiously, but I try and fit everything into 80 characters where possible (my editor has an indicator for the 80-character mark).

Agreed, also I like to have a portrait monitor for code and browser, can see more without scrolling, so 80 helps.
For me the big win with 80 is that I can easily do a side-by-side diff in my IDE without needing to expand the diff window at the expense of the outline, package, and other views. And horizontal scrolling in a diff view sucks. A lot.
I keep a ruler at 80char but treat it as a soft limit. It seems to work okay, functionally its probably about the same as a 100char limit but there's something psychologically better about being able to break the limit and not worry about it.
I often switch between working on my desktop and my laptop. keeping to a limit of about 80 characters makes it easier when working on the laptop. And as others have said, I often split screens when working on my desktop as well, so it helps there too.

I also find that very long lines can be a code smell - deeply nested callbacks or a case of 'divitis' in html markup.

When working with html, I find it convenient to put attributes on separate lines if there are more than a couple of short ones. This naturally helps keep line length down. Having them on separate lines helps with editing a bit too.

Every sane linter has //NOLINT support.
Yes. But not every code reviewer has a //NONITPICK option.
I hear you. E.g. - I find go-format to be vile. I remember "non New Jersey" languages from back in the 80s, and find K&R syntax / format worship sickening.

Yes, leave an existing file in its existing layout. No, don't get your shorts in a twisty if both double quotes and single quotes are used in places when the language treats them EXACTLY the same (i.e. - no value interpolation).

Don't force me to copy Java idioms (UGHHHHH!) in an otherwise functional programming language. I don't care about how to use "this" (other than to read somebody else's crap OOP code); I'm using variables in closures that happen to be bundled into an "object". I'm using currying for "dependency injection", rather than writing crap classes with one "do it" method for 90% of instances of "class". (alas, I do most of my work in Java, and only a little JavaScript, which is why the java-isms in JS upset me so much -- Java clowns, GO AWAY!!!)

This is an unfocused rant, I apologize, but I hear your complaint about mandated arbitrary stupidity. I don't know why you got downvoted. People didn't just not agree, you offended them. Go figure.

Very nice work, but not sure that I'm onboard with switching `var` to `const | let`. Is the only difference between `var` and `let` scoping?
Not just scoping. The hoisting rules have changed. There's some discussion earlier in the comments regarding `typeof` no longer being safe to use with `let` and `const` declarations. `typeof` with a `var` before its declaration is fine because of hoisting, but with `let` produces a reference error.
I didn't even know there were "hoisting" rules - I put all my variables on one var line at the top of the file, then assign them later. Well, except for lately, function variables in JSDoc work better when the function-var is immediately assigned :-(
The best part of this guide is that they included a eslint and jslint rules file.

https://github.com/airbnb/javascript/tree/master/linters

My team adopted this style guide and was easily able to add it as a eslint step to our existing gulp files and run it automatically. This let us use the guide without making everyone memorize the syntax differences between their personal style first.

Looks like a lot of good stuff but it's incredibly verbose and dense. It's important to adhere to standards but I'm not entirely convinced this doesn't end up being counter-productive. But as long as it's a guide and not a 100% "you must follow every little thing" and you can change things then maybe it's not so bad.

Still hard to get used to so many using ES6 already. I'm still not a big fan of transpiling but some days I feel like I'm the only one.

Yes, there is a mix of pragmatic advice (with citations) along with stylistic opinions. I think the ES5 version is also quite good. Look at the number of forks, though. I might use this as the basis for a style guide for my organization. I think I'll probably fork it, though, and remove the opinionated bits. I did enjoy the writing style.
2.2 seems completely arbitrary to me. If your functions are so big that you need block scope, you're doing it wrong IMO.
How else would you use conditions or loops?
The style guide doesn't actually use block scope for if/loop.

Many items in the guide are...reasonable, but the explanations are gibberish or don't match the code.

the same way you would in es5?
(comment deleted)
// bad const item = new Object();

// good const item = {};

Literally useless differentiation.

Seems pretty useful to me. If I see "new Object()", I know the code was written by someone who doesn't know JS very well, so I should look more carefully for bugs.
Same functionality, less characters. This also helps being consistent.
That's why they call it Style Guide. You know - Style?
// bad const items = new Array();

// good const items = [];

They obviously spent a lot of time on this guide, lots of investor dollars, and it's of almost no use.

Making sure everyone within your company writes the same style code, makes it more readable and easier to find bugs. You can also start doing automatic linting and hinting. On top of that, they made the top on hacker news which will help finding new devs.
Imagine this:

a = new Array(10);

b = [10];

alert(a[0]);

alert(b[0]);

Do you know the difference?

This is just one reason. Also [] will be faster. Just google the differences and why [] is recommended to use.

  > new Array('a')
  ["a"]
  > new Array(2, 3)
  [2, 3]
  > new Array(2)
  [undefined, undefined]
  > new Array(2.3)
  RangeError: invalid array length
  > new Array(2.3, 4.5)
  [2.3, 4.5]
The Array constructor is really bogus. It switches to a different mode if a single number is passed.

ES6 added `Array.of` for this reason:

  > Array.of()
  []
  > Array.of(1)
  [1]
  > Array.of(1, 2)
  [1, 2]
I don't really think it's needed though. Spread and rest already take care of the common use cases.
Regarding using single quotes for strings (https://github.com/airbnb/javascript#6.1), I found it interesting that it's one of the rare sections where there's no rationale offered.

I guess it's just a stylistic choice in the end, but when we set up our own internal/informal style guide, my teammate and I spent a little while trying to come up with a justification for single vs double quotes. We ended up choosing double quotes based on the fact that JSON already made that decision for us: it requires strings be double-quoted.

(Although again, it's far from an important matter, as long as you're consistent), anybody has interesting rationales to share in favor of single quotes?

At least in Ruby, you can only do string interpolation with strings in double quotes.
JavaScript up to ES5 doesn't support string interpolation at all. ES6 introduces backticks `before${var}after` for that, but there's still no functional difference between single and double quotes.
Interesting they chose that, considering it's deprecated in bash and python.
Coffeescript as well. I try to use single quotes whenever possible, so if a string is templated it stands out a bit with the double quotes.
If JSON requires the string to be double-quoted, then it's more convenient to use singe quotes, since your embedded JSON string (if you ever used it) won't need to have its quotes escaped.
Interesting. Is that common in your workflow to embed JSON as string literals in JavaScript? Never had to do that. I'd probably use ES6 backticks, so as to have multiline support and skip the need to escape both single and double quotes.
Right, why write

    '{ "foo": "bar" }'
when you could write

    JSON.stringify({ foo: "bar" })
and get a static guarantee of valid JSON?
My rationale for single quotes is also that JSON chose for you -- if you have JSON-formatted strings in your javascript and you use single quotes for your strings, you don't have to escape the double quotes.
Do you do that more or less frequently than writing strings with apostrophes?
I'd find it very worrying that you have JSON-formatted strings in JS code. Why would you do that, when there's also a native representation?
Typing single quotes is one keystroke ('), typing double quotes is two (shift+').
> Typing single quotes is one keystroke

Not on my keyboard.

Also, C uses double quotes (and JSON, and many, many more languages). That used to be my rationale. These days I get away with saying that 'foo' and `foo` look too similar.

I believe the most commonly ones used do.
(comment deleted)
We enforce double quotes for html attributes, mainly because we enforce single quotes for PHP so when you're writing mixed HTML/PHP in the view scripts we don't need to escape any of them. Single quotes for javascript would allow for the same, though we also have a strict no inline javascript policy as well.

Mainly our rationale is, pick one and be consistent. Single quotes where there first so they win, same deal with indentation amount.

If you use contractions like don\'t inside of a string then you need to escape the apostrophe if you\'re using single quotes, which is annoying and can make the string a bit harder for humans to parse. I like the aesthetics of double-quotes better too, though that\'s not a compelling reason.
You can use template strings in ES6 and avoid that whole problem.
Well, one simple typographical way to solve this is not to use a quotation character (') when what is meant is an apostrophe character (’).
Ouch, I'd be afraid that this may become the source of subtle bugs.
"Don’t say “Hello”"

Proper typography solves all.

My toy programming language uses “ and ” for string literals. It counts nesting, so you can write “Don’t say “Hello””. There is no escaping. In fact, you can quote any piece of code by simply enclosing it in “ and ”. Code is commented out by turning it into an unused string literal.

For such cases I find the Python style most appropriate. It says that you use some consistent default (e.g. always single quote), but for all a strings that require escaping, you should use the delimiter with the least (preferably no) escaping.

Note that this is easier in Python than JavaScript because Python provides more string delimiters:

    'He said hello.'

    'He said "hello".'

    "Don't say hello.'

    '''Don't say "hello".'''

    r'Some regex\sstuff'
The only problem is that sometimes it leads to bugs when people mix different delimiters - like in your third example :)
Note that as of ES6 there is the template string literals using backticks so it looks like JS is at parity with your example.

    'He said hello.'
    'He said "hello".'
    "Don't say hello."
    `Don't say "Hello".`
    /some regex\sstuff/
Mainstream support just isn't there yet.
You could use ` backticks instead and use both " and ' in strings without worry
we use double quotes for HTML and single quotes for JS. that makes it easy to embed HTML snippets in Js code and JS snippets in HTML attribute values without escaping.
I use double quotes for most strings and single quotes for characters, just because it's perfectly valid without having to learn new habits.

If I have HTML in a JavaScript string, I don't quote the attributes at all unless necessary, instead focusing on more pressing matters like how to get that shit out of my JavaScript.

> We ended up choosing double quotes based on the fact that JSON already made that decision for us: it requires strings be double-quoted.

My personal style guide is to copy Erlang: double quotes for text, single quotes for programmatic strings (atoms/symbols). The single quote is slightly more convenient to type on a qwerty keyboard, but text regularly contains single quotes (apostrophes). It also provides a semantic visual shortcut.

CoffeeScript follows a more common style: double-quoted strings for interpolated values and single-quoted strings are literal.
Single quotes are a big big pain if you have strings with apostrophes (which is common in names: O'Brian, d'Alembert).

You can escape them, but that's an extra pain and strain on readability; you can use some other character but that will usually cause problems down the road.

Why so many people insist on single quotes is a mystery...

The rationale I have for using single quotes over double quotes in javascript is that when embedding HTML elements, attributes are often quoted in double quotes.

So it's much nicer to write

    '<a href="www.google.com">Google</a>'
than to constantly escape argument strings.
In ES6, that's no longer a problem since most HTML elements will involve interpolation with template strings and backticks.

    `<a href="${ site.url }">${ site.name }</a>`

    "<a href='www.google.com'>Google</a>"
Will work as well though.
Single quotes are less busy. Strings are all over my angular app usually, so having half the number of little lines flying around is much more pleasing to my eyes.
Use const for all of your references; avoid using var. If you must mutate references, use let instead of var.

In my 15 years of programming javascript I've never once seen this matter.

That's because let and const where officially introduced in JavaScript this year, see the JavaScript standard ES6 (or ES2015).
Airbnb's technical quality has been obviously crap for its entire existence. Why are we taking engineering cues from a glorified room rental site that is frequently buggy?
Don't think of it as advice from a crappy site. Think of it as developers at a big company sharing how they do things. Take what you want from it, or just use it as a conversation jumping off point.
I've used AirBnB several times and never found it buggy enough to impair my main objective of booking a place to stay. It seems to be as robust as it needs to be.
As an alternative style guide, consider giving standard [0] a try. The hook is: "No decisions to make. No .eslintrc, .jshintrc, or .jscsrc files to manage. It just works." You don't have to configure anything, you just run it on your project and it'll tell you what to change.

[0] https://github.com/feross/standard

Styleguides are a matter of taste and there are probably no two people in the world with the same taste. Was there a voting of this?
I think I'd go nuts in a codebase with their whitespace and brackets rules.

Sure, cramming the opening bracket onto the previous line is just ugly and something you could learn to live with. But there's a special type of rage that can only be generated by clicking on to the start of a line and having your cursor land 1-2 spaces to the left of it.

Why would anybody do that to their code voluntarily?

Wait, are you saying that you put the opening bracket on the next line? That would drive me crazy.
Just like it drives you crazy to put opening bracket on the same line - it drives other people crazy to put it on the next line.
Some style preferences are subjective, but some have very good reasons for being the way they are. Here's a simple JavaScript function that returns an object...

    function blah()
    {
      return
      {
        key: "value"
      };
    }
...except it returns undefined when invoked:

    console.log(blah());
    undefined
Can you spot the bug? With so little code, it should be obvious, right? Before reading on, stop for a minute and really try to find the error.

...

Figured it out?

...

The answer is that JavaScript has automatic semicolon insertion. That means there's effectively a semicolon on the same line as return. ASI is why, in JavaScript, you always put the curly brace on the same line. Sure, you could try to remember the ASI rules, but you're guaranteed to be safe if you just put your braces on the same line. And considering how much code a typical programmer writes, you are almost guaranteed to inflict an ASI bug on yourself if you don't do this.

AFAIK, return statements are literally the only place where brace style is affected by ASI.

    var result =
    {
        key: "value"
    };

    return result;
works fine, plus it lets you more easily break on the return statement and verify/modify what will be returned when debugging. It would be kind of awkward to see braces like that in JavaScript, but a style guide could just ban returning object literals and make the ASI issue moot (at least regarding braces; you still have the other gotchas with forgetting a comma in a variable declaration, etc).
God I hate the term "semicolon insertion". It's a line oriented language, like shell or BASIC. You only need semicolons when you put multiple statements on a line (like a minifier does). Alas, like Ruby, JS does not require, or allow, an explicit line continuation, such as a backslash or ampersand.

I hate the asshole at Netscape who decided the browser scripting language had to be modeled after Java (C/C++, in other words), especially when it was clearly meant to be a functional programming language that worked with lists and property lists.

Man, I'm feeling "troll-ish" tonight. Not that I'm lying, just being blunt.

I'm curious as I haven't found a good coding style guide about object inheritance in ES5.

I usually write this even though it's a bit verbose:

  function Child() {
    Parent.call(this);
  }
  Child.prototype = Object.create(Parent.prototype);
  Child.prototype.constructor = Child;
Any opinion on this or link to a good guide?
ES6 actually solves this with it's new Class syntax.

  class Child extends Parent {
  }