Skip to content
This repository was archived by the owner on Aug 8, 2023. It is now read-only.

Commit d9f4d56

Browse files
Daniel Brook-RobergeDaniel Brook-Roberge
authored andcommitted
Merge pull request #83 from mobify/method-chain-conventions-js
Add a method chain and callback standard for Javascript
2 parents b9b0a7e + 6449473 commit d9f4d56

1 file changed

Lines changed: 93 additions & 35 deletions

File tree

javascript/README.md

Lines changed: 93 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ Please comment code extensively. More comments are always better than fewer comm
77
// bad!
88
// Shows footer if shopping bag is absent
99
var showFooter = !$('.shopping-bag').length;
10-
10+
1111
// good
12-
// PROJ-12: As per client request, we hide the footer if
12+
// PROJ-12: As per client request, we hide the footer if
1313
// the shopping bag is not visible on the page.
1414
var showFooter = !$('.shopping-bag').length;
1515
````
@@ -37,14 +37,14 @@ In general, always favour comment placement that leads to less indenting.
3737
Don't commit commented out sections of code back into the repository. Just delete the code. That's what git's history is for!
3838

3939
If a piece of code is very temporarily being removed, and will be reinserted shortly, you might decide to do this anyway. Please leave a detailed comment explaining exactly why. Sorta like those post-its we leave on boxes in the fridge with our name and date so that we know when to chuck 'em out!
40-
40+
4141

4242
##Use single quotes
4343

4444
````javascript
4545
// good
4646
$('.footer')
47-
47+
4848
// bad
4949
$(".footer")
5050
````
@@ -54,14 +54,14 @@ $(".footer")
5454
````javascript
5555
// bad: what was 3 again? Text node? Comment?
5656
if (el.nodeType === 3) { ... }
57-
57+
5858
// bad: The reader doesn't know why we chose 7, and if we change 7 with 8, we'll have to carefully search and replace all occurrences
5959
if ($('.blah').length === 7) { ... }
60-
60+
6161
// good
62-
62+
6363
if (el.nodeType === Node.TEXT_NODE) { ... }
64-
64+
6565
// good
6666
if ($('.blah').length === defaultRoomCount) { ... }
6767
````
@@ -73,14 +73,14 @@ Separate declarations with a semicolon and a line break.
7373
````javascript
7474
// bad: these are all in the global scope and is hard to read
7575
items = {}, length = items.length, name = 'foo';
76-
76+
7777
// bad: if you comment out the first line, the subsequent declarations
7878
// become global variables
7979
// additionally, these do not beautify in DevTools nicely (semi-colons do)
8080
var items = {},
8181
length = items.length,
8282
name = 'foo';
83-
83+
8484
// good: easiest to read/edit, and because we run our code through uglify,
8585
// it will be optimized at compile-time anyways
8686
var items = {};
@@ -118,7 +118,7 @@ function foo () {
118118
...
119119
}
120120

121-
// good
121+
// good
122122
var foo = function() {
123123
...
124124
}
@@ -131,7 +131,7 @@ But no space before the opening argument parenthesis.
131131
````javascript
132132
// bad
133133
var foo = function(){...}
134-
134+
135135
// good: whitespace improves readability here
136136
var foo = function() {
137137
...
@@ -143,7 +143,7 @@ var foo = function() {
143143
````javascript
144144
// bad: we want to differentiate between operations (see below) and function calls
145145
doStuff ();
146-
146+
147147
// good
148148
doStuff();
149149
````
@@ -153,7 +153,7 @@ doStuff();
153153
````javascript
154154
// bad: we are recalculating items.length every time
155155
for (var i = 0; i < items.length; i++)
156-
156+
157157
// good
158158
for (var i = 0, length = items.length; i < length; i++)
159159
````
@@ -163,7 +163,7 @@ for (var i = 0, length = items.length; i < length; i++)
163163
````javascript
164164
// bad: we want to differentiate between function calls (see above) and conditions
165165
if(true)
166-
166+
167167
// good
168168
if (true)
169169
````
@@ -173,7 +173,7 @@ if (true)
173173
````javascript
174174
// bad
175175
var c=a+b;
176-
176+
177177
// good: yay whitespace!
178178
var c = a + b;
179179
````
@@ -188,7 +188,7 @@ if (true) {
188188
else {
189189
...
190190
}
191-
191+
192192
// good
193193
if (true) {
194194
...
@@ -203,7 +203,7 @@ if (true) {
203203
// bad
204204
'footer':{
205205
}
206-
206+
207207
// good
208208
'footer': {
209209
}
@@ -214,7 +214,7 @@ if (true) {
214214
````javascript
215215
// bad: it's more work to add a line to this block
216216
if (isVisible) return true;
217-
217+
218218
// good: this will get minified anyways
219219
if (isVisible) {
220220
return true;
@@ -237,11 +237,11 @@ Use a descriptive variable name instead.
237237
````javascript
238238
// bad: what is this supposed to be?
239239
var arr = [];
240-
240+
241241
// bad: why is the object type so important that it needs to be in the name?
242242
var itemsArray = [];
243243
var computerObj = {};
244-
244+
245245
// good
246246
var items = [];
247247
var computer = {};
@@ -252,10 +252,10 @@ var computer = {};
252252
````javascript
253253
// bad: underscores shouldn’t be used in identifiers
254254
function recalculate_item_height() { ... }
255-
255+
256256
// bad: this is our constructor name convention
257257
function RecalculateItemHeight() { ... }
258-
258+
259259
// good
260260
function recalculateItemHeight() { ... }
261261
````
@@ -265,7 +265,7 @@ function recalculateItemHeight() { ... }
265265
````javascript
266266
// bad
267267
var is_visible = true;
268-
268+
269269
// good
270270
var isVisible = true;
271271
````
@@ -288,14 +288,14 @@ var router = new Router();
288288
function awesomemovie(options) {
289289
this.title = options.title;
290290
}
291-
291+
292292
var titanic = new awesomemovie({ title: 'Titanic' });
293-
293+
294294
// good
295295
function AwesomeMovie(options) {
296296
this.title = options.title;
297297
}
298-
298+
299299
var fiftyShades = new AwesomeMovie({ title: '50 Shades Of Grey' });
300300
````
301301

@@ -324,23 +324,23 @@ var Utils = {
324324
function BadExample(name, value) {
325325
this.name = name;
326326
this.value = value;
327-
327+
328328
this.doSomeStuff = function() {
329329
// some stuff done
330330
}
331331
}
332-
332+
333333
// good
334334
// methods declared with the prototype will be shared across all instances, reducing memory footprint
335335
function GoodExample(name, value) {
336336
this.name = name;
337337
this.value = value;
338338
}
339-
339+
340340
GoodExample.prototype.doSomeStuff = function() {
341341
// some stuff done
342342
};
343-
````
343+
````
344344

345345
##Cache variables if you use them more than once
346346

@@ -350,7 +350,7 @@ $('.items').on('click', function() {
350350
$(this).addClass('active');
351351
$(this).find('h3').remove();
352352
});
353-
353+
354354
// good
355355
$('.items').on('click', function() {
356356
var $items = $(this);
@@ -364,7 +364,7 @@ $('.items').on('click', function() {
364364
````javascript
365365
// bad
366366
var title = $('h1');
367-
367+
368368
// good: later on in the code, people will know that they can use jQuery/Zepto on this object
369369
var $title = $('h1');
370370
````
@@ -385,14 +385,14 @@ if ("0" === false) {console.log('foo')}
385385

386386
##Calling array methods on array-like objects
387387

388-
You can use functions from `Array.prototype` on array-like objects. (eg. 'arguments' is not an array, but
388+
You can use functions from `Array.prototype` on array-like objects. (eg. 'arguments' is not an array, but
389389
is array-like).
390390

391391
###Prefer using methods from `[]` over `Array.prototype`
392392

393393
Prefer the short, more succinct version.
394394

395-
[Performance between the two styles is almost identical](http://jsperf.com/foreach-vs-array-prototype-foreach).
395+
[Performance between the two styles is almost identical](http://jsperf.com/foreach-vs-array-prototype-foreach).
396396

397397
```javascript
398398
// Good
@@ -402,3 +402,61 @@ Prefer the short, more succinct version.
402402
Array.prototype.forEach.call(arguments, function(arg) { console.log(arg); });
403403
```
404404

405+
##Method and promise chains
406+
407+
With method-chaining or promise APIs, we may have a long chain of
408+
method calls in a single statement. It is important to format these so
409+
that they are readable and flow as clearly as possible.
410+
411+
###Place each call on its own line, beginning with the period, and indented
412+
413+
The sequence of operations is clearer if each 'step' in the process
414+
begins at the start of the line. Indenting relative to the previous
415+
line makes the chain distinct.
416+
417+
```javascript
418+
// Good
419+
return functionThatReturnsAPromise()
420+
.then(preprocessTheResult)
421+
.catch(handleErrors)
422+
.then(logSomething);
423+
424+
// Bad
425+
return functionThatReturnsAPromise.then(preprocessTheResult)
426+
.catch(handleErrors).then(logSomething);
427+
```
428+
429+
###Avoid multiple function expressions in a single function call
430+
431+
The break between two function expressions passed as arguments can be
432+
quite awkward. It is clearer to use named functions, or to change your
433+
use of the API to split them up.
434+
435+
```javascript
436+
// Bad
437+
functionThatReturnsAPromise()
438+
.then(function() {
439+
// code here!
440+
}, function() {
441+
// other code here!
442+
});
443+
444+
// Good
445+
var resolveFunction = function() {
446+
// code here!
447+
};
448+
var rejectFunction = function() {
449+
// other code here!
450+
};
451+
452+
functionThatReturnsAPromise().then(resolveFunction, rejectFunction);
453+
454+
// Also Good
455+
functionThatReturnsAPromise()
456+
.then(function() {
457+
// code here!
458+
})
459+
.catch(function() {
460+
// other code here!
461+
});
462+
```

0 commit comments

Comments
 (0)