# Ember.js JavaScript Style Guide ## Table Of Contents - [Objects](#objects) - [Array](#arrays) - [Strings](#strings) - [Variables](#variables) - [Whitespace](#whitespace) - [Commas](#commas) - [Semicolons](#semicolons) - [Block Statements](#block-statements) - [Conditional Statements](#conditional-statements) - [Properties](#properties) - [Functions](#functions) - [Arrow Functions](#arrow-functions) - [Function Arguments](#function-arguments) - [Rest Parameters](#rest-parameters) - [Destructuring](#destructuring) - [Comments](#comments) ## Objects - Use literal form for object creation. ```javascript var foo = {}; ``` - Pad single-line objects with white-space. ```javascript var bar = { color: 'orange' }; ``` ## Arrays - Use literal form for array creation (unless you know the exact length). ```javascript var foo = []; ``` - If you know the exact length and know that array is not going to grow, use `Array`. ```javascript var foo = new Array(16); ``` - Use `push` to add an item to an array. ```javascript var foo = []; foo.push('bar'); ``` ## Strings - Use `'single quotes'`. ## Variables - Put all non-assigning declarations on one line. ```javascript var a, b; ``` - Use a single `var` declaration for each assignment. ```javascript var a = 1; var b = 2; ``` - Declare variables at the top of their scope. ```javascript function foo() { var bar; console.log('foo bar!'); bar = getBar(); } ``` ## Whitespace - Use soft tabs set to 2 spaces. ```javascript function() { ∙∙var name; } ``` - Place 1 space before the leading brace. ```javascript obj.set('foo', { foo: 'bar', }); test('foo-bar', function () {}); ``` - No spaces before semicolons. ```javascript var foo = {}; ``` - Keep parenthesis adjacent to the function name when declared or called. ```javascript function foo() {} foo(); ``` - Spaces are required around binary operators. ```javascript // assignments var foo = bar + 'a'; // conditionals if (foo === 'bara') { } // parameters function(test, foo) { } ``` ## Commas - Skip trailing commas. ```javascript var foo = [1, 2, 3]; var bar = { a: 'a' }; ``` - Skip leading commas. ```javascript var foo = [1, 2, 3]; ``` ## Semicolons - Use semicolons. ## Block Statements - Use spaces. ```javascript // conditional if (notFound) { return 0; } else { return 1; } switch (condition) { case 'yes': // code break; } // loops for (var key in keys) { // code } for (var i = 0; i < keys.length; i++) { // code } while (true) { // code } try { // code that throws an error } catch (e) { // code that handles an error } ``` - Opening curly brace should be on the same line as the beginning of a statement or declaration. ```javascript function foo() { var obj = { val: 'test', }; return { data: obj, }; } if (foo === 1) { foo(); } for (var key in keys) { bar(e); } while (true) { foo(); } ``` - Keep `else` and its accompanying braces on the same line. ```javascript if (foo === 1) { bar = 2; } else { bar = '2'; } if (foo === 1) { bar = 2; } else if (foo === 2) { bar = 1; } else { bar = 3; } ``` ## Conditional Statements - Use `===` and `!==`. - Use curly braces. ```javascript if (notFound) { return; } ``` - Use explicit conditions. ```javascript if (arr.length > 0) { // code } if (foo !== '') { // code } ``` ## Properties - Use dot-notation when accessing properties. ```javascript var foo = { bar: 'bar', }; foo.bar; ``` - Use `[]` when accessing properties with a variable. ```javascript var propertyName = 'bar'; var foo = { bar: 'bar', }; foo[propertyName]; ``` ## Functions - Make sure to name functions when you define them. ```javascript function fooBar() {} ``` ## Arrow Functions - Make sure arrow functions are done on multiple lines. ```javascript var foo = [1, 2, 3, 4].map((item) => { return item * 2; }); ``` ## Function Arguments `arguments` object must not be passed or leaked anywhere. See the [reference](https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#3-managing-arguments). - Use a `for` loop with `arguments` (instead of `slice`). ```javascript function fooBar() { var args = new Array(arguments.length); for (var i = 0; i < args.length; ++i) { args[i] = arguments[i]; } return args; } ``` - Don't re-assign the arguments. ```javascript function fooBar() { arguments = 3; } function fooBar(opt) { opt = 3; } ``` - Use a new variable if you need to re-assign an argument. ```javascript function fooBar(opt) { var options = opt; options = 3; } ``` ## Rest Parameters Since [Babel implements]() Rest parameters in a non-leaking matter you should use them whenever applicable. ```javascript function foo(...args) { args.forEach((item) => { console.log(item); }); } ``` ## Destructuring When decomposing simple arrays or objects, prefer [destructuring](http://babeljs.io/docs/learn-es6/#destructuring). ```javascript // array destructuring var fullName = 'component:foo-bar'; var [first, last] = fullName.split(':'); ``` ```javascript // object destructuring var person = { firstName: 'Stefan', lastName: 'Penner', }; var { firstName, lastName } = person; ``` ## Comments - Use [YUIDoc](http://yui.github.io/yuidoc/syntax/index.html) comments for documenting functions. - Use `//` for single line comments. ```javascript function foo() { var bar = 5; // multiplies `bar` by 2. fooBar(bar); console.log(bar); } ```