Hi, StormyTalent again. And today we are going through best usages of "Control statements, comments, whitespace"
1. Control statements
In case your control statement (if, while etc.) gets too long or exceeds the maximum line length, each (grouped) condition could be put into a new line. The logical operator should begin the line.
// bad if ((foo === 123 || bar === 'abc') && doesItLookGoodWhenItBecomesThatLong() && isThisReallyHappening()) { thing1(); } // bad if (foo === 123 && bar === 'abc') { thing1(); } // bad if (foo === 123 && bar === 'abc') { thing1(); } // bad if ( foo === 123 && bar === 'abc' ) { thing1(); } // good if ( foo === 123 && bar === 'abc' ) { thing1(); } // good if ( (foo === 123 || bar === 'abc') && doesItLookGoodWhenItBecomesThatLong() && isThisReallyHappening() ) { thing1(); } // good if (foo === 123 && bar === 'abc') { thing1(); }
Don't use selection operators in place of control statements.
// bad !isRunning && startRunning(); // good if (!isRunning) { startRunning(); }
2. Comments
Use /** ... */ for multiline comments.
// bad // make() returns a new element // based on the passed in tag name // // @param {String} tag // @return {Element} element function make(tag) { // ... return element; } // good /** * make() returns a new element * based on the passed-in tag name */ function make(tag) { // ... return element; }
Use // for single line comments. Place single line comments on a newline above the subject of the comment. Put an empty line before the comment unless it’s on the first line of a block.
// bad const active = true; // is current tab // good // is current tab const active = true; // bad function getType() { console.log('fetching type...'); // set the default type to 'no type' const type = this.type || 'no type'; return type; } // good function getType() { console.log('fetching type...'); // set the default type to 'no type' const type = this.type || 'no type'; return type; } // also good function getType() { // set the default type to 'no type' const type = this.type || 'no type'; return type; }
Start all comments with a space to make it easier to read.
// bad //is current tab const active = true; // good // is current tab const active = true; // bad /** *make() returns a new element *based on the passed-in tag name */ function make(tag) { // ... return element; } // good /** * make() returns a new element * based on the passed-in tag name */ function make(tag) { // ... return element; }
Use // FIXME: to annotate problems.
class Calculator extends Abacus { constructor() { super(); // FIXME: shouldn’t use a global here total = 0; } }
Use // TODO: to annotate solutions to problems.
class Calculator extends Abacus { constructor() { super(); // TODO: total should be configurable by an options param this.total = 0; } }
3. Whitespace
Use soft tabs (space character) set to 2 spaces.
// bad function foo() { ∙∙∙∙let name; } // bad function bar() { ∙let name; } // good function baz() { ∙∙let name; }
Place 1 space before the leading brace.
// bad function test(){ console.log('test'); } // good function test() { console.log('test'); } // bad dog.set('attr',{ age: '1 year', breed: 'Bernese Mountain Dog', }); // good dog.set('attr', { age: '1 year', breed: 'Bernese Mountain Dog', });
Place 1 space before the opening parenthesis in control statements (if, while etc.). Place no space between the argument list and the function name in function calls and declarations.
// bad if(isJedi) { fight (); } // good if (isJedi) { fight(); } // bad function fight () { console.log ('Swooosh!'); } // good function fight() { console.log('Swooosh!'); }
Set off operators with spaces.
// bad const x=y+5; // good const x = y + 5;
End files with a single newline character.
// bad import { es6 } from './AirbnbStyleGuide'; // ... export default es6; // bad import { es6 } from './AirbnbStyleGuide'; // ... export default es6;↵ // good import { es6 } from './AirbnbStyleGuide'; // ... export default es6;↵
Use indentation when making long method chains (more than 2 method chains). Use a leading dot, which emphasizes that the line is a method call, not a new statement.
// bad $('#items').find('.selected').highlight().end().find('.open').updateCount(); // bad $('#items'). find('.selected'). highlight(). end(). find('.open'). updateCount(); // good $('#items') .find('.selected') .highlight() .end() .find('.open') .updateCount(); // bad const leds = stage.selectAll('.led').data(data).enter().append('svg:svg').classed('led', true) .attr('width', (radius + margin) * 2).append('svg:g') .attr('transform', `translate(${radius + margin},${radius + margin})`) .call(tron.led); // good const leds = stage.selectAll('.led') .data(data) .enter().append('svg:svg') .classed('led', true) .attr('width', (radius + margin) * 2) .append('svg:g') .attr('transform', `translate(${radius + margin},${radius + margin})`) .call(tron.led); // good const leds = stage.selectAll('.led').data(data); const svg = leds.enter().append('svg:svg'); svg.classed('led', true).attr('width', (radius + margin) * 2); const g = svg.append('svg:g'); g.attr('transform', `translate(${radius + margin},${radius + margin})`).call(tron.led);
Leave a blank line after blocks and before the next statement.
// bad if (foo) { return bar; } return baz; // good if (foo) { return bar; } return baz; // bad const obj = { foo() { }, bar() { }, }; return obj; // good const obj = { foo() { }, bar() { }, }; return obj; // bad const arr = [ function foo() { }, function bar() { }, ]; return arr; // good const arr = [ function foo() { }, function bar() { }, ]; return arr;
Do not pad your blocks with blank lines.
// bad function bar() { console.log(foo); } // bad if (baz) { console.log(qux); } else { console.log(foo); } // bad class Foo { constructor(bar) { this.bar = bar; } } // good function bar() { console.log(foo); } // good if (baz) { console.log(qux); } else { console.log(foo); }
Do not use multiple blank lines to pad your code.
// bad class Person { constructor(fullName, email, birthday) { this.fullName = fullName; this.email = email; this.setAge(birthday); } setAge(birthday) { const today = new Date(); const age = this.getAge(today, birthday); this.age = age; } getAge(today, birthday) { // .. } } // good class Person { constructor(fullName, email, birthday) { this.fullName = fullName; this.email = email; this.setAge(birthday); } setAge(birthday) { const today = new Date(); const age = getAge(today, birthday); this.age = age; } getAge(today, birthday) { // .. } }
Do not add spaces inside parentheses.
// bad function bar( foo ) { return foo; } // good function bar(foo) { return foo; } // bad if ( foo ) { console.log(foo); } // good if (foo) { console.log(foo); }
Do not add spaces inside brackets.
// bad const foo = [ 1, 2, 3 ]; console.log(foo[ 0 ]); // good const foo = [1, 2, 3]; console.log(foo[0]);
Add spaces inside curly braces.
// bad const foo = {clark: 'kent'}; // good const foo = { clark: 'kent' };
Avoid having lines of code that are longer than 100 characters (including whitespace). Note: per above, long strings are exempt from this rule, and should not be broken up.
// bad const foo = jsonData && jsonData.foo && jsonData.foo.bar && jsonData.foo.bar.baz && jsonData.foo.bar.baz.quux && jsonData.foo.bar.baz.quux.xyzzy; // bad $.ajax({ method: 'POST', url: 'https://airbnb.com/', data: { name: 'John' } }).done(() => console.log('Congratulations!')).fail(() => console.log('You have failed this city.')); // good const foo = jsonData && jsonData.foo && jsonData.foo.bar && jsonData.foo.bar.baz && jsonData.foo.bar.baz.quux && jsonData.foo.bar.baz.quux.xyzzy; // good $.ajax({ method: 'POST', url: 'https://airbnb.com/', data: { name: 'John' }, }) .done(() => console.log('Congratulations!')) .fail(() => console.log('You have failed this city.'));
Require consistent spacing inside an open block token and the next token on the same line. This rule also enforces consistent spacing inside a close block token and previous token on the same line.
// bad var foo = 1,bar = 2; var arr = [1 , 2]; // good var foo = 1, bar = 2; var arr = [1, 2];
Top comments (1)
This is purely opinion and totally subjective