Slide 1

Slide 1 text

JavaScript coding tips Axel Rauschmayer rauschma.de ! Sud Web 2014

Slide 2

Slide 2 text

Coding styles on GitHub Source: sideeffect.kr/popularconvention/#javascript

Slide 3

Slide 3 text

Comma: first or last? var foo = 1 , bar = 2 , baz = 3; ! var obj = { foo: 1 , bar: 2 , baz: 3 };
 var foo = 1, bar = 2, baz = 3; ! var obj = { foo: 1, bar: 2, baz: 3 }; 7% comma first
 93% comma last 3

Slide 4

Slide 4 text

Indentation: spaces vs. tabs function foo() { ␣␣return 'bar'; }
 function foo() { ⇥ return 'bar'; } 81% spaces
 19% tabs 4

Slide 5

Slide 5 text

Space after function name? function foo () { return 'bar'; }
 function foo() { return 'bar'; } 33% space after function name
 67% no space after function name 5

Slide 6

Slide 6 text

Spaces inside parens? function fn( x, y ) { ... } ! if ( true ) { ... }
 function fn(x, y) { ... } ! if (true) { ... } 6% spaces inside parens
 94% no spaces inside parens 6

Slide 7

Slide 7 text

Object literals { foo:1, bar:2, baz:3 }
 { foo: 1, bar: 2, baz: 3 }
 { foo : 1, bar : 2, baz : 3 } 22% no space after colon
 64% space after colon
 14% space before & after 7

Slide 8

Slide 8 text

Conditional statements if (true) { ... } while (true) { ... } switch (v) { ... }
 if(true) { ... } while(true) { ... } switch(v) { ... } 79% space after keyword
 21% no space after keyword 8

Slide 9

Slide 9 text

String literals var foo = 'bar'; ! var obj = { 'foo': 'bar' };
 var foo = "bar"; ! var obj = { "foo": "bar" }; 57% single quotes
 43% double quotes 9

Slide 10

Slide 10 text

General tips

Slide 11

Slide 11 text

Be consistent New project:" • Come up with a style • Document it • Automatically check it (tools: JSLint, JSHint, ESLint) • Follow it consistently Existing project:" • Follow their style (even if you don’t like it) 11

Slide 12

Slide 12 text

Code should be easy to understand Code is written once, read many times. Treat it accordingly. Programs must be written for people to read, and only incidentally for machines to execute. —Abelson, Sussman 12

Slide 13

Slide 13 text

Code should be easy to understand • Shorter isn’t always better • Familiar + longer > unfamiliar + shorter • Humans read tokens, not characters: redBalloon > rdBlln • Write code like a textbook • A guide to your mental universe • Complemented by documentation • Don’t be clever • Avoid optimizing for speed or code size (esp. early on) 13

Slide 14

Slide 14 text

Commonly accepted best practices

Slide 15

Slide 15 text

Best practices • Use strict mode • Always use strict equality (===). No exceptions! • Avoid global variables • Always write semicolons • Single quotes for strings (common, but not a must) 15

Slide 16

Slide 16 text

Use: 1TBS (One True Brace Style) function foo(x, y, z) { if (x) { a(); } else { b(); c(); } } 16

Slide 17

Slide 17 text

Don’t use: Allman brace style function foo(x, y, z) { if (x) { a(); } else { b(); c(); } } 17

Slide 18

Slide 18 text

Literals are better than constructors var obj = {}; // yes var obj = new Object(); // no ! var arr = []; // yes var arr = new Array(); // no ! var regex = /abc/; // yes var regex = new RegExp('abc'); // avoid 18

Slide 19

Slide 19 text

Acceptable cleverness // Optional parameter x function f(x) { x = x || 0; ... } 19

Slide 20

Slide 20 text

Naming entities • Not capitalized: • Functions, variables: myFunction • Methods: obj.myMethod • Modules: my_module • Capitalized: • Constructors: MyConstructor • Constants: MY_CONSTANT

Slide 21

Slide 21 text

Less mainstream rules

Slide 22

Slide 22 text

Camel case Camel case: • JavaScript: decodeURIComponent, JSON • Shudder: XMLHttpRequest • I prefer: processHtmlFile

Slide 23

Slide 23 text

Four spaces for indentation // My preference: // 4 spaces function abs(x) { if (x >= 0) { return x; } else { return -x; } }
 // Often used: // 2 spaces function abs(x) { if (x >= 0) { return x; } else { return -x; } } 23

Slide 24

Slide 24 text

One variable declaration per line // no var foo = 3, bar = 2, baz; ! // yes var foo = 3; var bar = 2; var baz;
 Advantages: • Protects against some typos (forgetting a comma) • Easier: insert, delete, rearrange lines • Every line has context information • Automatically indented correctly 24

Slide 25

Slide 25 text

Coercing Use Boolean, Number, String (as functions) to coerce. ! var bool = Boolean(7); // yes var bool = !!7; // no ! var num = Number('123'); // yes var num = +'123'; // no ! var str = String(true); // yes var str = ''+true; // no 25

Slide 26

Slide 26 text

Keep declarations local Close to where they are used.

Slide 27

Slide 27 text

Keep declarations local // Often recommended: var elem; for (var i=0; i

Slide 28

Slide 28 text

Keep declarations local // Often recommended: var tmp; if (x < 0) { tmp = -x; ... } ! // I prefer: if (x < 0) { var tmp = -x; ... } 28

Slide 29

Slide 29 text

Keep declarations local Often recommended:" ! // Only used inside loop function helperFunc() { ... } arr.forEach(function (x) { ... });
 I prefer:" ! arr.forEach(function (x) { function helperFunc() { ... } ... }); 29

Slide 30

Slide 30 text

Keep declarations local Advantages: • Code fragments are easier to • understand • move and reuse • delete • Often engines optimize automatically
 㱺 no performance penalty 30

Slide 31

Slide 31 text

Thanks! More info (chapter 26): speakingjs.com/es5/

Slide 32

Slide 32 text

Bonus slides

Slide 33

Slide 33 text

Object-orientation • Prefer constructors over other instance creation patterns • Mainstream • Optimized • Forward-looking (ECMAScript 6 classes are constructors) • Avoid closures for private data • Less elegant code • But: only way to keep data completely private • Use parens for constructor calls without arguments: var foo = new Foo; // no var foo = new Foo(); // yes 33

Slide 34

Slide 34 text

Avoid this as implicit parameter // Avoid $('ul.tabs li').on('click', function () { var tab = $(this); highlightTab(tab); ... }); ! // Prefer $('ul.tabs li').on('click', function (event) { var tab = $(event.target); highlightTab(tab); ... }); 34

Slide 35

Slide 35 text

Avoid this as implicit parameter // Avoid beforeEach(function () { this.addMatchers({ toBeInRange: function (start, end) { ... } }); }); ! // Prefer beforeEach(function (api) { api.addMatchers({ toBeInRange(start, end) { ... } }); }); 35