Transcript
Page 1: "Writing Maintainable JavaScript". Jon Bretman, Badoo

WRITING MAINTAINABLE

JAVASCRIPT Yet Another Conference 2013

@jonbretman

jonbretman.co.uk

Mobile Web Developer @ Badoo http://techblog.badoo.com

@BadooTech

http://habrahabr.ru/company/badoo @BadooDev

1"

Page 2: "Writing Maintainable JavaScript". Jon Bretman, Badoo

2"

Page 3: "Writing Maintainable JavaScript". Jon Bretman, Badoo

<!doctype html>!<html>! <head>! <title>My Awesome App</title>! <script src="App.js"></script>! </head>! <body>! </body>!</html>"

3"

Page 4: "Writing Maintainable JavaScript". Jon Bretman, Badoo

4"

What is maintainability?

Page 5: "Writing Maintainable JavaScript". Jon Bretman, Badoo

5"

In engineering, maintainability is the ease with which a product can be maintained in order to...

h(p://en.wikipedia.org/wiki/Maintainability"

Page 6: "Writing Maintainable JavaScript". Jon Bretman, Badoo

6"

In engineering, maintainability is the ease with which a product can be maintained in order to...

isolate defects or their cause

h(p://en.wikipedia.org/wiki/Maintainability"

Page 7: "Writing Maintainable JavaScript". Jon Bretman, Badoo

7"

In engineering, maintainability is the ease with which a product can be maintained in order to...

correct defects or their cause

h(p://en.wikipedia.org/wiki/Maintainability"

Page 8: "Writing Maintainable JavaScript". Jon Bretman, Badoo

8"

In engineering, maintainability is the ease with which a product can be maintained in order to...

prevent unexpected breakdowns

h(p://en.wikipedia.org/wiki/Maintainability"

Page 9: "Writing Maintainable JavaScript". Jon Bretman, Badoo

9"

In engineering, maintainability is the ease with which a product can be maintained in order to...

make future maintenance easier

h(p://en.wikipedia.org/wiki/Maintainability"

Page 10: "Writing Maintainable JavaScript". Jon Bretman, Badoo

10"

It's about making our lives easier

Page 11: "Writing Maintainable JavaScript". Jon Bretman, Badoo

11"

It's about making our work pass the test of time

Page 12: "Writing Maintainable JavaScript". Jon Bretman, Badoo

12"

for(B=i=y=u=b=i=5-5,x=10,I=[],l=[];B++<304;I[B-1]=B%x?B/x%x<2|B%x<2?7:B/x&4?!0:l[i++]="ECDFBDCEAAAAAAAAIIIIIIIIMKLNJLKM@G@TSb~?A6J57IKJT576,+-48HLSUmgukgg " +!"OJNMLK IDHGFE".charCodeAt(y++)-64:7);function X(c,h,e,s){c^=8;for(var o,!S,C,A,R,T,G,d=e&&X(c,0)>1e4,n,N=-1e8,O=20,K=78-h<<9;++O<99;)if((o=I[T=O])&&!(G=o^c)<7){A=G--&2?8:4;C=o-9?l[61+G]:49;do if(!(R=I[T+=l[C]])&&!!G|A<3||!(R+1^c)>9&&G|A>2){if(!(R-2&7))return K;n=G|(c?T>29:T<91)?o:6^c;S=!(R&&l[R&7|32]*2-h-G)+(n-o?110:!G&&(A<2)+1);if(e>h||1<e&e==h&&S>2|d)!{I[T]=n;I[O]=0;S-=X(c,h+1,e,S-N);if(!(h||e-1|B-O|T-b|S<-1e4))return W(),!c&&setTimeout("X(8,0,2),X(8,0,1)",75);I[O]=o;I[T]=R}if(S>N||!h&S==N&&!Math.random()<.5)if(N=S,e>1)if(h?s-S<0:(B=O,b=T,0))break}while(!R&G>2||(T=O,!(G||A>2|(c?O>78:O<41)&!R)&&++C*--A))}return-K+768<N|d&&N}function W(){!i="<table>";for(u=18;u<99;document.body.innerHTML=i+=++u%x-9?!"<th width=60 height=60 onclick='I[b="+u+"]>8?W():X(0,0,1)'style='font-size:50px'bgcolor=#"!+(u-B?u*.9&1||9:"d")+"0f0e0>&#"+(I[u]?9808+l[67+I[u]]:160):u++&&"<tr>")B=b}W()"

h(p://js1k.com/2010Efirst/demo/750"

Page 13: "Writing Maintainable JavaScript". Jon Bretman, Badoo

13"

Page 14: "Writing Maintainable JavaScript". Jon Bretman, Badoo

14"

•  Mobile Web Team - 4 developers

Page 15: "Writing Maintainable JavaScript". Jon Bretman, Badoo

15"

•  Mobile Web Team - 4 developers •  JavaScript, jsDoc, JSHint, Closure Compiler, JsTestDriver

Page 16: "Writing Maintainable JavaScript". Jon Bretman, Badoo

16"

•  Mobile Web Team - 4 developers •  JavaScript, jsDoc, JSHint, Closure Compiler, JsTestDriver •  60,000+ lines of JavaScript

Page 17: "Writing Maintainable JavaScript". Jon Bretman, Badoo

17"

•  Mobile Web Team - 4 developers •  JavaScript, jsDoc, JSHint, Closure Compiler, JsTestDriver •  60,000+ lines of JavaScript •  ~500,000 daily active users

Page 18: "Writing Maintainable JavaScript". Jon Bretman, Badoo

18"

•  Mobile Web Team - 4 developers •  JavaScript, jsDoc, JSHint, Closure Compiler, JsTestDriver •  60,000+ lines of JavaScript •  ~500,000 daily active users •  Code maintainability is key!

Page 19: "Writing Maintainable JavaScript". Jon Bretman, Badoo

var topics = [! 'Type Checking',! 'Classes and Inheritance’,! 'Asynchronous Code',! 'Performance'!];!" 19"

Page 20: "Writing Maintainable JavaScript". Jon Bretman, Badoo

topics.shift();!"Type Checking" !

!

20"

Page 21: "Writing Maintainable JavaScript". Jon Bretman, Badoo

<!doctype html>!<html>! <head>! <title>My Awesome App</title>! <script src="App.js"></script>! </head>! <body>! </body>!</html>"

21"

Page 22: "Writing Maintainable JavaScript". Jon Bretman, Badoo

Api.get('/conversations', function (conversations) {!! var intros = conversations.map(function (c) {! var name = c.theirName;! var mostRecent = c.messages[0].text.substring(0, 30);! return name + ': ' + mostRecent;! });!! App.renderMessages(intros);!!});!

22"

Page 23: "Writing Maintainable JavaScript". Jon Bretman, Badoo

Api.get('/conversations', function (conversations) {!! var intros = conversations.map(function (c) {! var name = c.theirName;! var mostRecent = c.messages[0].text.substring(0, 30);! return name + ': ' + mostRecent;! });!! App.renderMessages(intros);!!});!

23"

Page 24: "Writing Maintainable JavaScript". Jon Bretman, Badoo

Api.get('/conversations', function (err, conversations) {!! var intros = conversations.map(function (c) {! var name = c.theirName;! var mostRecent = c.messages[0].text.substring(0, 30);! return name + ': ' + mostRecent;! });!! App.renderMessages(intros);!!});!A lot of things have to go right here

24"

Page 25: "Writing Maintainable JavaScript". Jon Bretman, Badoo

25"

Exceptions

Page 26: "Writing Maintainable JavaScript". Jon Bretman, Badoo

if (data.value) {! callback(data.value);!}!!!TypeError: Cannot read property 'value' of null !!!!!"""

26"

Page 27: "Writing Maintainable JavaScript". Jon Bretman, Badoo

if (data && data.callback) {! var result = data.callback();!}!!!TypeError: Property 'callback' of object #<Object> !is not a function""

27"

Page 28: "Writing Maintainable JavaScript". Jon Bretman, Badoo

if (data && data.value) {! var index = data.value.indexOf('something');!}!!!TypeError: Object #<Object> has no method ‘indexOf’!!!!!!""

28"

Page 29: "Writing Maintainable JavaScript". Jon Bretman, Badoo

typeof {};!"object" !!typeof 'hello';!"string" !!typeof 5;!"number” !

typeof function () {};!"function" !!typeof undefined;!"undefined" !!typeof true;!"boolean" !!

29"

Page 30: "Writing Maintainable JavaScript". Jon Bretman, Badoo

typeof [];!"object" !!typeof null;!"object" !!typeof new Date();!"object" !

typeof /jsconf/;!"object" !!typeof document.body; !"object" !!typeof NaN; !"number" !!

30"

Page 31: "Writing Maintainable JavaScript". Jon Bretman, Badoo

Object.prototype.toString()!!"

""

31"

Page 32: "Writing Maintainable JavaScript". Jon Bretman, Badoo

Object.prototype.toString()!!"

""

32"

WHY?

Page 33: "Writing Maintainable JavaScript". Jon Bretman, Badoo

•  If the this value is undefined, return "[object Undefined]". !

!

33"

Page 34: "Writing Maintainable JavaScript". Jon Bretman, Badoo

•  If the this value is undefined, return "[object Undefined]". !

•  If the this value is null, return "[object Null]". !

!

34"

Page 35: "Writing Maintainable JavaScript". Jon Bretman, Badoo

•  If the this value is undefined, return "[object Undefined]". !

•  If the this value is null, return "[object Null]". !

•  Let class be the value of the [[Class]] property of this. !

35"

Page 36: "Writing Maintainable JavaScript". Jon Bretman, Badoo

•  If the this value is undefined, return "[object Undefined]". !

•  If the this value is null, return "[object Null]". !

•  Let class be the value of the [[Class]] property of this.

•  Return the String value that is the result of concatenating

the three Strings "[object ", class, and "]". !

36"

Page 37: "Writing Maintainable JavaScript". Jon Bretman, Badoo

•  If the this value is undefined, return "[object Undefined]". !

•  If the this value is null, return "[object Null]". !

•  Let class be the value of the [[Class]] property of this.

•  Return the String value that is the result of concatenating

the three Strings "[object ", class, and "]". !

37"

Function.prototype.call()!or!

Function.prototype.apply()!

Page 38: "Writing Maintainable JavaScript". Jon Bretman, Badoo

var toString = Object.prototype.toString;!var regex = /\[object (.*?)\]/;!!var type = function (o) {! var match = toString.call(o).match(regex);! return match[1].toLowerCase();!};!

38"

Page 39: "Writing Maintainable JavaScript". Jon Bretman, Badoo

var toString = Object.prototype.toString;!var regex = /\[object (.*?)\]/;!!var type = function (o) {! var match = toString.call(o).match(regex);! return match[1].toLowerCase();!};!

39"

this === o"

Page 40: "Writing Maintainable JavaScript". Jon Bretman, Badoo

type({});!"object" !!type('hello');!"string" !!type(5);!"number” !

type(function () {});!"function" !!type(undefined);!"undefined" !!type(true);!"boolean" !!

40"

Page 41: "Writing Maintainable JavaScript". Jon Bretman, Badoo

type([]);!"array" !!type(null);!"null" !!type(new Date());!"date" !

type(/jsconf/);!"regex" !!type(document.body);!"htmlbodyelement" !!type(NaN);!"number" !!

41"

Page 42: "Writing Maintainable JavaScript". Jon Bretman, Badoo

type([]); !"array" !!type(null); !"null" !!type(new Date()); !"date" !

type(/jsconf/); !"regex" !!type(document.body);!"htmlbodyelement" !!type(NaN);!"number" !!

42"

???

Page 43: "Writing Maintainable JavaScript". Jon Bretman, Badoo

var toString = Object.prototype.toString;!var regex = /\[object (.*?)\]/;!!var type = function (o) {!! if (o && o.nodeType === 1) {! return 'element';! }!! var match = toString.call(o).match(regex);! var _type = match[1].toLowerCase();!! if (_type === 'number' && isNaN(o)) {! return 'nan';! }!! return _type;!};! 43"

Page 44: "Writing Maintainable JavaScript". Jon Bretman, Badoo

var toString = Object.prototype.toString;!var regex = /\[object (.*?)\]/;!!var type = function (o) {!! if (o && o.nodeType === 1) {! return 'element';! }!! var match = toString.call(o).match(regex);! var _type = match[1].toLowerCase();!! if (_type === 'number' && isNaN(o)) {! return 'nan';! }!! return _type;!};! 44"

Special case for DOM elements

Page 45: "Writing Maintainable JavaScript". Jon Bretman, Badoo

var toString = Object.prototype.toString;!var regex = /\[object (.*?)\]/;!!var type = function (o) {!! if (o && o.nodeType === 1) {! return 'element';! }!! var match = toString.call(o).match(regex);! var _type = match[1].toLowerCase();!! if (_type === 'number' && isNaN(o)) {! return 'nan';! }!! return _type;!};! 45"

Special case for NaN

Page 46: "Writing Maintainable JavaScript". Jon Bretman, Badoo

46"

Now what?

Page 47: "Writing Maintainable JavaScript". Jon Bretman, Badoo

Api.get('/conversations', function (conversations) {!! if (type(conversations) !== 'array') {! App.renderMessages([]);! return;! }!! var intros = conversations.map(function (c) {!! if (type(c) !== 'object') {! return '';! }!! var name = type(c.theirName) === 'string' ? c.theirName : '';! var mostRecent = '';!! if (type(c.messages) === 'array' ||! type(c.messages[0]) === 'object' ||! type(c.messages[0].text) === 'string') {! mostRecent = c.messages[0].text.substring(0, 30);! }!! return name + ': ' + mostRecent;! });!! App.renderMessages(intros);!!});"

47"

Page 48: "Writing Maintainable JavaScript". Jon Bretman, Badoo

Api.get("/conversations",function(e){var t=e.map(function(e){var t=e.theirName;var n=e.messages[0].text.substring(0,30);return t+": "+n});App.renderMessages(t)})!!!!!!!!!!Api.get("/conversations",function(e){if(type(e)!=="array"){App.renderMessages([]);return}var t=e.map(function(e){if(type(e)!=="object"){return""}var t=type(e.theirName)==="string"?e.theirName:"";var n="";if(type(e.messages)==="array"||type(e.messages[0])==="object"||type(e.messages[0].text)==="string"){n=e.messages[0].text.substring(0,30)}return t+": "+n});App.renderMessages(t)})"

+ 137%

48"

Page 49: "Writing Maintainable JavaScript". Jon Bretman, Badoo

49"

How does this help maintainability?

Page 50: "Writing Maintainable JavaScript". Jon Bretman, Badoo

50"

Prevents unexpected breakdowns

Page 51: "Writing Maintainable JavaScript". Jon Bretman, Badoo

51"

Prevents unexpected breakdowns Makes future maintenance easier

Page 52: "Writing Maintainable JavaScript". Jon Bretman, Badoo

topics.shift();!"Classes and Inheritance" !

!

52"

Page 53: "Writing Maintainable JavaScript". Jon Bretman, Badoo

53"

Why classes?

Page 54: "Writing Maintainable JavaScript". Jon Bretman, Badoo

54"

var Controller = {!! init: function () {! // do some initialization! },!! loadView: function () {!! }!!};!!// somewhere else in the app!Controller.init();!Controller.loadView();"

Page 55: "Writing Maintainable JavaScript". Jon Bretman, Badoo

55"

var Controller = {!! init: function () {! // do some initialization! },!! loadView: function () {!! }!!};!!// somewhere else in the app!Controller.init();!Controller.loadView();"

Feels messy

Page 56: "Writing Maintainable JavaScript". Jon Bretman, Badoo

56"

var ChatController = {};!!for (var key in Controller) {! ChatController[key] = Controller;!}!!ChatController.loadView = function () {!! Controller.loadView.apply(this, arguments);! // do some additional stuff!!};!"

Page 57: "Writing Maintainable JavaScript". Jon Bretman, Badoo

57"

var ChatController = {};!!for (var key in Controller) {! ChatController[key] = Controller;!}!!ChatController.loadView = function () {!! Controller.loadView.apply(this, arguments);! // do some additional stuff!!};!"

Not proper inheritance

Page 58: "Writing Maintainable JavaScript". Jon Bretman, Badoo

58"

What do we want?

Page 59: "Writing Maintainable JavaScript". Jon Bretman, Badoo

class Controller {!!!

public Controller () {! // do some initialization! }!

!!! public void loadView () {!! !!! }!

!}!!class ChatController extends Controller {!

!!! public void loadView () {!! ! super.loadView();!! ! // do some additional stuff!! }!!!

}" 59"

Page 60: "Writing Maintainable JavaScript". Jon Bretman, Badoo

class Controller {!! constructor () {! // do some initialization! }!! loadView () {!! }!!}!!class ChatController extends Controller {!! loadView () {! super.loadView();! // do some additional stuff! }!!}" 60"

Page 61: "Writing Maintainable JavaScript". Jon Bretman, Badoo

class Controller!! constructor: () ->! # do some initialization!! loadView: () ->!!!class ChatController extends Controller!! loadView: () ->! super! # do some initialization"

61"

Page 62: "Writing Maintainable JavaScript". Jon Bretman, Badoo

var ChatController, Controller, _ref,! __hasProp = {}.hasOwnProperty,! __extends = function(child, parent) {! for (var key in parent) {! if (__hasProp.call(parent, key))! child[key] = parent[key];! }! function ctor() {! this.constructor = child;! }! ctor.prototype = parent.prototype;! child.prototype = new ctor();! child.__super__ = parent.prototype;! return child;! };!!Controller = (function() {! function Controller() {}! Controller.prototype.loadView = function() {};! return Controller;!})();!!ChatController = (function(_super) {! __extends(ChatController, _super);!! function ChatController() {! _ref = ChatController.__super__.constructor.apply(this, arguments);! return _ref;! }!! ChatController.prototype.loadView = function() {! return ChatController.__super__.loadView.apply(this, arguments);! };!! return ChatController;!})(Controller);" 62"

Page 63: "Writing Maintainable JavaScript". Jon Bretman, Badoo

var ChatController, Controller, _ref,! __hasProp = {}.hasOwnProperty,! __extends = function(child, parent) {! for (var key in parent) {! if (__hasProp.call(parent, key))! child[key] = parent[key];! }! function ctor() {! this.constructor = child;! }! ctor.prototype = parent.prototype;! child.prototype = new ctor();! child.__super__ = parent.prototype;! return child;! };!!Controller = (function() {! function Controller() {}! Controller.prototype.loadView = function() {};! return Controller;!})();!!ChatController = (function(_super) {! __extends(ChatController, _super);!! function ChatController() {! _ref = ChatController.__super__.constructor.apply(this, arguments);! return _ref;! }!! ChatController.prototype.loadView = function() {! return ChatController.__super__.loadView.apply(this, arguments);! };!! return ChatController;!})(Controller);" 63"

Utility method

Page 64: "Writing Maintainable JavaScript". Jon Bretman, Badoo

var ChatController, Controller, _ref,! __hasProp = {}.hasOwnProperty,! __extends = function(child, parent) {! for (var key in parent) {! if (__hasProp.call(parent, key))! child[key] = parent[key];! }! function ctor() {! this.constructor = child;! }! ctor.prototype = parent.prototype;! child.prototype = new ctor();! child.__super__ = parent.prototype;! return child;! };!!Controller = (function() {! function Controller() {}! Controller.prototype.loadView = function() {};! return Controller;!})();!!ChatController = (function(_super) {! __extends(ChatController, _super);!! function ChatController() {! _ref = ChatController.__super__.constructor.apply(this, arguments);! return _ref;! }!! ChatController.prototype.loadView = function() {! return ChatController.__super__.loadView.apply(this, arguments);! };!! return ChatController;!})(Controller);" 64"

Class Definitions

Page 65: "Writing Maintainable JavaScript". Jon Bretman, Badoo

var Controller = function () {! // do some initialization!};!!Controller.prototype.loadView = function() {! !};!!var ChatController = function (name) {! Controller.apply(this, arguments);!};!!ChatController.prototype.loadView = function () {! ChatController._super.loadView.apply(this, arguments);! // do some additional stuff!}!!extends(ChatController, Controller);"

65"

Page 66: "Writing Maintainable JavaScript". Jon Bretman, Badoo

var Controller = function () {! // do some initialization!};!!Controller.prototype.loadView = function() {! !};!!var ChatController = function (name) {! Controller.apply(this, arguments);!};!!ChatController.prototype.loadView = function () {! ChatController._super.loadView.apply(this, arguments);! // do some additional stuff!}!!extends(ChatController, Controller);"

66"

The magic bit

Page 67: "Writing Maintainable JavaScript". Jon Bretman, Badoo

67"

There is no such thing as magic.

Page 68: "Writing Maintainable JavaScript". Jon Bretman, Badoo

var extends = function(child, parent) {! for (var key in parent) {! if (parent.hasOwnProperty(key)) {! child[key] = parent[key];! }! }! function ctor() { ! this.constructor = child; ! }! ctor.prototype = parent.prototype;! child.prototype = new ctor();! child._super = parent.prototype;! return child;!};" 68"

Page 69: "Writing Maintainable JavaScript". Jon Bretman, Badoo

var extends = function(child, parent) {! for (var key in parent) {! if (parent.hasOwnProperty(key)) {! child[key] = parent[key];! }! }! function ctor() { ! this.constructor = child; ! }! ctor.prototype = parent.prototype;! child.prototype = new ctor();! child._super = parent.prototype;! return child;!};" 69"

Copy static properties / methods

Page 70: "Writing Maintainable JavaScript". Jon Bretman, Badoo

var extends = function(child, parent) {! for (var key in parent) {! if (parent.hasOwnProperty(key)) {! child[key] = parent[key];! }! }! function ctor() { ! this.constructor = child; ! }! ctor.prototype = parent.prototype;! child.prototype = new ctor();! child._super = parent.prototype;! return child;!};" 70"

Set up prototype chain

Page 71: "Writing Maintainable JavaScript". Jon Bretman, Badoo

var extends = function(child, parent) {! for (var key in parent) {! if (parent.hasOwnProperty(key)) {! child[key] = parent[key];! }! }!!! ctor.prototype = Object.create(parent.prototype);!!! child._super = parent.prototype;! return child;!};" 71"

ECMAScript 5

Page 72: "Writing Maintainable JavaScript". Jon Bretman, Badoo

var extends = function(child, parent) {! for (var key in parent) {! if (parent.hasOwnProperty(key)) {! child[key] = parent[key];! }! }! function ctor() { ! this.constructor = child; ! }! ctor.prototype = parent.prototype;! child.prototype = new ctor();! child._super = parent.prototype;! return child;!};" 72"

Add shorthand to super

Page 73: "Writing Maintainable JavaScript". Jon Bretman, Badoo

var controller = new Controller();!var chat = new ChatController();!!controller instanceof Controller; // true!!chat instanceof Controller; // true!chat instanceof ChatController; // true"

73"

Page 74: "Writing Maintainable JavaScript". Jon Bretman, Badoo

74"

The rest is about good practice

Page 75: "Writing Maintainable JavaScript". Jon Bretman, Badoo

Use getter and setter methods

alert(jon.name);!jon.name = 'John';!!!alert(jon.getName());!jon.setName('John');!jon.set('name', 'John');"

75"

Page 76: "Writing Maintainable JavaScript". Jon Bretman, Badoo

Define all properties on the prototype, even if they are null.

/**! * The persons age.! * @type {Number}! */!Person.prototype.age = null;"

76"

Page 77: "Writing Maintainable JavaScript". Jon Bretman, Badoo

Mark private methods with a leading or trailing underscore

// somethings are best kept private :)!Person.prototype._singInShower = function () {!!};"

77"

Page 78: "Writing Maintainable JavaScript". Jon Bretman, Badoo

Use static methods / properties

Person.prototype.EVENTS = {! WALK: 'WALK',! TALK: 'TALK'!};!!Person.EVENTS = {! WALK: 'WALK',! TALK: 'TALK'!};"

78"

Page 79: "Writing Maintainable JavaScript". Jon Bretman, Badoo

79"

How does this help maintainability?

Page 80: "Writing Maintainable JavaScript". Jon Bretman, Badoo

80"

Correct defects or their causes

Page 81: "Writing Maintainable JavaScript". Jon Bretman, Badoo

81"

Correct defects or their causes Makes future maintenance easier

Page 82: "Writing Maintainable JavaScript". Jon Bretman, Badoo

topics.shift();!"Asynchronous Code" !

!

82"

Page 83: "Writing Maintainable JavaScript". Jon Bretman, Badoo

83"

The big question...

Page 84: "Writing Maintainable JavaScript". Jon Bretman, Badoo

Callbacks or

Promises 84"

Page 85: "Writing Maintainable JavaScript". Jon Bretman, Badoo

Promises •  Requires a library to provide the functionality

85"

Page 86: "Writing Maintainable JavaScript". Jon Bretman, Badoo

Promises •  Requires a library to provide the functionality

•  Different implementations •  jQuery Deferred api.jquery.com/category/deferred-object/ •  rsvp.js github.com/tildeio/rsvp.js •  when.js github.com/cujojs/when •  promise.js github.com/then/promise

86"

Page 87: "Writing Maintainable JavaScript". Jon Bretman, Badoo

Promises •  Requires a library to provide the functionality

•  Different implementations •  jQuery Deferred api.jquery.com/category/deferred-object/ •  rsvp.js github.com/tildeio/rsvp.js •  when.js github.com/cujojs/when •  promise.js github.com/then/promise

•  Kind of complicated… 87"

Page 88: "Writing Maintainable JavaScript". Jon Bretman, Badoo

h(p://promisesEaplus.github.io/promisesEspec/"88"

Page 89: "Writing Maintainable JavaScript". Jon Bretman, Badoo

89"

TL;DR

Page 90: "Writing Maintainable JavaScript". Jon Bretman, Badoo

90"

But that must mean...

Page 91: "Writing Maintainable JavaScript". Jon Bretman, Badoo

Callback Hell

91"

Page 92: "Writing Maintainable JavaScript". Jon Bretman, Badoo

92"

load: function () {!! Api.get('/profile/own', _.bind(function (ownProfile) {!! this.ownProfile = ownProfile;!! Api.get('/profile/' + id, _.bind(function (theirProfile) {!! this.theirProfile = theirProfile;!! Api.get('/chatMessages', _.bind(function (messages) {!! this.messages = messages;! this.render();!! }, this), _.bind(function (err) {! this.onError();! }, this));! }, this), _.bind(function (err) {! this.onError();! }, this));! }, this), _.bind(function (err) {! this.onError();! }, this));! }!!"

Page 93: "Writing Maintainable JavaScript". Jon Bretman, Badoo

93"

load: function () {!! Api.get('/profile/own', _.bind(function (ownProfile) {!! this.ownProfile = ownProfile;!! Api.get('/profile/' + id, _.bind(function (theirProfile) {!! this.theirProfile = theirProfile;!! Api.get('/chatMessages', _.bind(function (messages) {!! this.messages = messages;! this.render();!! }, this), _.bind(function (err) {! this.onError();! }, this));! }, this), _.bind(function (err) {! this.onError();! }, this));! }, this), _.bind(function (err) {! this.onError();! }, this));! }!!"

Page 94: "Writing Maintainable JavaScript". Jon Bretman, Badoo

94"

load: function () {!! Api.get('/profile/own', _.bind(function (ownProfile) {!! this.ownProfile = ownProfile;!! Api.get('/profile/' + id, _.bind(function (theirProfile) {!! this.theirProfile = theirProfile;!! Api.get('/chatMessages', _.bind(function (messages) {!! this.messages = messages;! this.render();!! }, this), _.bind(function (err) {! this.onError();! }, this));! }, this), _.bind(function (err) {! this.onError();! }, this));! }, this), _.bind(function (err) {! this.onError();! }, this));! }!!"

Action

Error Handling

Page 95: "Writing Maintainable JavaScript". Jon Bretman, Badoo

95"

No.

Page 96: "Writing Maintainable JavaScript". Jon Bretman, Badoo

“I’ve come to the conclusion

that callback hell is a design choice and not an inherent flaw

in the concept of asynchronous

function and callback” http://blog.caplin.com/2013/03/13/callback-hell-is-a-design-choice/ 96"

Page 97: "Writing Maintainable JavaScript". Jon Bretman, Badoo

doSomething(function (err, response) {!!});"

97"

Page 98: "Writing Maintainable JavaScript". Jon Bretman, Badoo

98"

var handler = function (err, response) {!!};!!doSomething(handler);"

Page 99: "Writing Maintainable JavaScript". Jon Bretman, Badoo

99"

! load: function (id) {! this.id = id;! Api.get('/profile/own', this.onOwnProfile);! },!! onOwnProfile: function (err, ownProfile) {! if (err) return this.onError();! this.ownProfile = ownProfile;! Api.get('/profile/' + this.id, this.onTheirProfile);! },!! onTheirProfile: function (err, theirProfile) {! if (err) return this.onError();! this.theirProfile = theirProfile;! Api.get('/chatMessages', this.onMessages);! },!! onMessages: function (err, messages) {! if (err) return this.onError();! this.messages = messages;! this.render();! }!

Page 100: "Writing Maintainable JavaScript". Jon Bretman, Badoo

100"

! load: function (id) {! this.id = id;! Api.get('/profile/own', this.onOwnProfile);! },!! onOwnProfile: function (err, ownProfile) {! if (err) return this.onError();! this.ownProfile = ownProfile;! Api.get('/profile/' + this.id, this.onTheirProfile);! },!! onTheirProfile: function (err, theirProfile) {! if (err) return this.onError();! this.theirProfile = theirProfile;! Api.get('/chatMessages', this.onMessages);! },!! onMessages: function (err, messages) {! if (err) return this.onError();! this.messages = messages;! this.render();! }!

Page 101: "Writing Maintainable JavaScript". Jon Bretman, Badoo

101"

! load: function (id) {! this.id = id;! Api.get('/profile/own', this.onOwnProfile);! },!! onOwnProfile: function (err, ownProfile) {! if (err) return this.onError();! this.ownProfile = ownProfile;! Api.get('/profile/' + this.id, this.onTheirProfile);! },!! onTheirProfile: function (err, theirProfile) {! if (err) return this.onError();! this.theirProfile = theirProfile;! Api.get('/chatMessages', this.onMessages);! },!! onMessages: function (err, messages) {! if (err) return this.onError();! this.messages = messages;! this.render();! }!

Page 102: "Writing Maintainable JavaScript". Jon Bretman, Badoo

102"

! load: function (id) {! this.id = id;! Api.get('/profile/own', this.onOwnProfile);! },!! onOwnProfile: function (err, ownProfile) {! if (err) return this.onError();! this.ownProfile = ownProfile;! Api.get('/profile/' + this.id, this.onTheirProfile);! },!! onTheirProfile: function (err, theirProfile) {! if (err) return this.onError();! this.theirProfile = theirProfile;! Api.get('/chatMessages', this.onMessages);! },!! onMessages: function (err, messages) {! if (err) return this.onError();! this.messages = messages;! this.render();! }!

Reusable

Page 103: "Writing Maintainable JavaScript". Jon Bretman, Badoo

Avoid anonymous functions

103"

Page 104: "Writing Maintainable JavaScript". Jon Bretman, Badoo

Avoid anonymous functions

104"

Useless stack traces

Page 105: "Writing Maintainable JavaScript". Jon Bretman, Badoo

Avoid anonymous functions

105"

Useless stack traces

Sign of poor structure

Page 106: "Writing Maintainable JavaScript". Jon Bretman, Badoo

Keep things shallow

106"

Page 107: "Writing Maintainable JavaScript". Jon Bretman, Badoo

Keep things shallow

107"

Means you are probably using anonymous functions

Page 108: "Writing Maintainable JavaScript". Jon Bretman, Badoo

Keep things shallow

108"

Means you are probably using anonymous functions

Everyone will hate you

Page 109: "Writing Maintainable JavaScript". Jon Bretman, Badoo

109"

How does this help maintainability?

Page 110: "Writing Maintainable JavaScript". Jon Bretman, Badoo

110"

Isolate defects or their causes

Page 111: "Writing Maintainable JavaScript". Jon Bretman, Badoo

111"

Isolate defects or their causes Makes future maintenance easier

Page 112: "Writing Maintainable JavaScript". Jon Bretman, Badoo

112"

Isolate defects or their causes Makes future maintenance easier Prevent unexpected breakdowns

Page 113: "Writing Maintainable JavaScript". Jon Bretman, Badoo

topics.shift();!"Performance" !

!

113"

Page 114: "Writing Maintainable JavaScript". Jon Bretman, Badoo

var i = 0;!var thing;!for (; i < things.length; i++) {! thing = things[i];!}"

things.forEach(function (thing, i) {!!});"

114"

or…

Page 115: "Writing Maintainable JavaScript". Jon Bretman, Badoo

115"http://jsperf.com/foreachvsloop

24x faster

13x faster

13x Faster 350,000 operations per second

Page 116: "Writing Maintainable JavaScript". Jon Bretman, Badoo

$('a').on('click', function (e) {!!});!!!!!!$('#container').on('click', 'a', function (e) {!!});"

or…

116"

Page 117: "Writing Maintainable JavaScript". Jon Bretman, Badoo

117"http://jsperf.com/domevents

21x faster

19x faster 21x Faster

Only 1000 operations per second

Page 118: "Writing Maintainable JavaScript". Jon Bretman, Badoo

118"

$('#container').append('<ul></ul>');!for (var i = 0; i < messages.length; i++) {! $('#container')! .find('ul')! .append('<li>' + messages[i].text + '</li>');!}"!!!!var html = '<ul>';!for (var i = 0; i < messages.length; i++) {! html += '<li>' + messages[i].text + '</li>';!}!html += '</ul>';!$('#container').html(html);!

or…

Page 119: "Writing Maintainable JavaScript". Jon Bretman, Badoo

119"http://jsperf.com/renderinghtml

48x Faster

44x faster

15x faster Less than 200 operations per second!

Page 120: "Writing Maintainable JavaScript". Jon Bretman, Badoo

DOM operations

120"

Page 121: "Writing Maintainable JavaScript". Jon Bretman, Badoo

DOM operations Iteration / function calls

121"

Page 122: "Writing Maintainable JavaScript". Jon Bretman, Badoo

122"

Beware of premature optimizations

Page 123: "Writing Maintainable JavaScript". Jon Bretman, Badoo

123"

Bottlenecks

Page 124: "Writing Maintainable JavaScript". Jon Bretman, Badoo

var cache = {!! get: function (key) {! return localStorage.getItem(key);! },!! set: function (key, value) {! localStorage.setItem(key, value);! }!!};"

124"

Page 125: "Writing Maintainable JavaScript". Jon Bretman, Badoo

var cache = {!! get: function (key) {! return localStorage.getItem(key);! },!! set: function (key, value) {! localStorage.setItem(key, value);! }!!};"

125"

Disc IO

Page 126: "Writing Maintainable JavaScript". Jon Bretman, Badoo

var cache = {!! data_: {},!! get: function (key) {!! if (this.data_.hasOwnProperty(key)) {! return this.data_[key];! }!! var value = localStorage.getItem(key);!! if (value !== null) {! this.data_[key] = value;! return value;! }!! return null;! },! set: function (key, value) {! this.data_[key] = value;! localStorage.setItem(key, value);! }!};" 126"

Page 127: "Writing Maintainable JavaScript". Jon Bretman, Badoo

var cache = {!! data_: {},!! get: function (key) {!! if (this.data_.hasOwnProperty(key)) {! return this.data_[key];! }!! var value = localStorage.getItem(key);!! if (value !== null) {! this.data_[key] = value;! return value;! }!! return null;! },! set: function (key, value) {! this.data_[key] = value;! localStorage.setItem(key, value);! }!};" 127"

Memory

Page 128: "Writing Maintainable JavaScript". Jon Bretman, Badoo

var cache = {!! data_: {},!! get: function (key) {!! if (this.data_.hasOwnProperty(key)) {! return this.data_[key];! }!! var value = localStorage.getItem(key);!! if (value !== null) {! this.data_[key] = value;! return value;! }!! return null;! },! set: function (key, value) {! this.data_[key] = value;! localStorage.setItem(key, value);! }!};" 128"

Quicker reading

Page 129: "Writing Maintainable JavaScript". Jon Bretman, Badoo

var cache = {!! data_: {},!! get: function (key) {!! if (this.data_.hasOwnProperty(key)) {! return this.data_[key];! }!! var value = localStorage.getItem(key);!! if (value !== null) {! this.data_[key] = value;! return value;! }!! return null;! },! set: function (key, value) {! this.data_[key] = value;! localStorage.setItem(key, value);! }!};" 129"

Saving for later

Page 130: "Writing Maintainable JavaScript". Jon Bretman, Badoo

130"http://jsperf.com/localstoragevsmemory

3x faster

About the same

Page 131: "Writing Maintainable JavaScript". Jon Bretman, Badoo

131"

How does this help maintainability?

Page 132: "Writing Maintainable JavaScript". Jon Bretman, Badoo

132"

Makes future maintenance easier

Page 133: "Writing Maintainable JavaScript". Jon Bretman, Badoo

133"

Makes future maintenance easier Prevent unexpected breakdowns

Page 134: "Writing Maintainable JavaScript". Jon Bretman, Badoo

134"

topics.shift();!undefined"

Page 135: "Writing Maintainable JavaScript". Jon Bretman, Badoo

135"

What is maintainability?

Page 136: "Writing Maintainable JavaScript". Jon Bretman, Badoo

136"

It's about making our lives easier

Page 137: "Writing Maintainable JavaScript". Jon Bretman, Badoo

137"

It's about making our work pass the test of time

Page 138: "Writing Maintainable JavaScript". Jon Bretman, Badoo

Thank you!

138"

Yet Another Conference 2013

@jonbretman jonbretman.co.uk

Mobile Web Developer @ Badoo

http://techblog.badoo.com @BadooTech

http://habrahabr.ru/company/badoo

@BadooDev


Top Related