"writing maintainable javascript". jon bretman, badoo

138
WRITING MAINTAINABLE JAVASCRIPT Yet Another Conference 2013 @jonbretman jonbretman.co.uk Mobile Web Developer @ Badoo http://techblog.badoo.com @BadooTech 1

Upload: yandex

Post on 15-Jan-2015

2.134 views

Category:

Technology


0 download

DESCRIPTION

There are lot of tools (CoffeeScript, Typescript, Dart, JSLint / JSHint etc.) that we can use to help us write better JavaScript, and many frameworks (Backbone, Ember, Angular etc.) that can help us structure large applications. But... what if you already have a large code base and are not able to re-write your whole application in a new way? What if your organisation does not want to depend on some open source or third party tool or framework? I am going to talk about some of the key things that most of these tools and frameworks do and how you can apply them to your existing or new project. Topics covered will include type checking, data hiding (public, private, static), inheritance, asynchronous code and performance.

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