Airbnb JavaScript Style Guide
github.com
github.com
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.
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?
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.
Mainly our rationale is, pick one and be consistent. Single quotes where there first so they win, same deal with indentation amount.
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' 'He said hello.'
'He said "hello".'
"Don't say hello."
`Don't say "Hello".`
/some regex\sstuff/
Mainstream support just isn't there yet.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.
I can't personally imagine this solution would be any less confusing, given that the new preferred apostrophe character according to this source is specifically a right single quote character.
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.
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.
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...
So it's much nicer to write
'<a href="www.google.com">Google</a>'
than to constantly escape argument strings. `<a href="${ site.url }">${ site.name }</a>` "<a href='www.google.com'>Google</a>"
Will work as well though.https://github.com/airbnb/javascript/tree/master/react#quote...
'{ "foo": "bar" }'
when you could write JSON.stringify({ foo: "bar" })
and get a static guarantee of valid JSON? [1]: https://github.com/airbnb/javascript#14.1
[2]: http://es-discourse.com/t/why-typeof-is-no-longer-safe/15Your editor should immediately highlight this error with a squiggly line.
>> let a;
>> a;
undefined // good
const obj = {
id: 5,
name: 'San Francisco',
[getKey('enabled')]: true,
}; 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.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.
Unless you "use strict", it's better to put var in-front of every variable if you put them on separate lines.
var foo = 1,
bar = 2
baz = 3
vs var foo = 1;
var bar = 2;
var baz = 3;
Forgetting a comma or semicolon in the first example might lead to silent bugs that will take hours to find.Also there's an autofix feature for most of the whitespace rules (`jscs src --preset=airbnb --fix`) so you won't have to fix everything manually.
function Foo() {
var foo = this;
foo.bar = 1;
foo.az = 2;
}
var foo = new Foo();
foo.bar = foo.bar + 5;
Then it will be super easy to rename say foo.bar to something else. It's also self "documented". {
"preset": "airbnb"
}Our old code base doesn't follow any style guide. After adding a style guide it requires us to go back and fix all our old files which is time consuming + kinda messes up with the git history.
I like .js over .jsx because I can require/import without explicit extension.
import Foo from './Foo';
vs
import Foo from './Foo.jsx';But yes, I got your point.
// bad
var a = 1;
var b = 2;
// good
const a = 1;
const b = 2; const a = {foo: 5};
a.foo = 42; // This is perfectly valid.
a = 'nope'; // But this isn't. It raises a SyntaxError.It was to show how they want you to always use const with complex types.
"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.
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.
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.
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. 3.3 Use readable synonyms in place of reserved words.
// bad
const superman = {
class: 'alien',
};
// bad
const superman = {
klass: 'alien',
};
What is unreadable about "klass"? Rails, for example, uses "klass" and it's never been hard for me (or, I suspect, anyone) to understand."Make sure you set the class-with-a-k property to 'alien'."
"Make sure you set the type property to 'alien'."
It's confufing to use one name inside your code and different one elsewhere.
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? class Child extends Parent {
}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.
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.
5 or 20 engineers who work in the same code base should have some more or less formal standards for that code.
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.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.
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).
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.
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.
-explains why {} is better than new Object().
https://github.com/rwaldron/idiomatic.js#spacing
Much easier to skim/parse quickly, at least for me.
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.xmlI 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.
3.5 Use object method shorthand.
I disagree. With anonymous objects it breaks the syntactical uniformity of the expression. I think it is much clearer when each field is given a name(and a value) the same way.Many items in the guide are...reasonable, but the explanations are gibberish or don't match the code.
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).
> Don't use generators for now.
>> Why? They don't transpile well to ES5.
Same thing with Symbols?
// good const items = [];
They obviously spent a lot of time on this guide, lots of investor dollars, and it's of almost no use.
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.// good const item = {};
Literally useless differentiation.
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?
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.
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).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.
In my 15 years of programming javascript I've never once seen this matter.