pragmatic javascript

108
© 2013 SpringOne 2GX. All rights reserved. Do not distribute without permission. Pragmatic JavaScript John Hann / @unscriptable JavaScript Barbarian at Pivotal / cujoJS Co-lead Friday, September 13, 13

Upload: spring-io

Post on 06-May-2015

2.605 views

Category:

Technology


1 download

DESCRIPTION

Speaker: John Hamm So you've been toying around with JavaScript. You have a basic feel for the language but don't quiet feel productive, yet. If so, this talk is for you. We'll peel away the abstractions, libraries, and frameworks to uncover the more interesting fundamentals of JavaScript. Specifically, we'll delve into the following: Prototypal inheritance (and alternatives to classical inheritance) Closures Scope versus context and this Public vs privileged vs private variables Modules Promises / Futures Recent improvements from EcmaScript 5 and 6 Functional programming strategies Documentation using JSDoc Testing strategies and more!

TRANSCRIPT

Page 1: Pragmatic JavaScript

© 2013 SpringOne 2GX. All rights reserved. Do not distribute without permission.

Pragmatic JavaScriptJohn Hann / @unscriptable

JavaScript Barbarian at Pivotal / cujoJS Co-lead

Friday, September 13, 13

Page 2: Pragmatic JavaScript

1.dealing with things sensibly and realistically in a way that is based on practical rather than theoretical considerations

Why are you here today?

Friday, September 13, 13

Page 3: Pragmatic JavaScript

To learn more about JavaScript?

Why are you here today?

Friday, September 13, 13

Page 4: Pragmatic JavaScript

did you get burned by JavaScript?image: gifbin.com

Friday, September 13, 13

Page 5: Pragmatic JavaScript

can't quite grok it?image: gifbin.com

Friday, September 13, 13

Page 6: Pragmatic JavaScript

Let's get one thing straight

JavaScript != Java

Friday, September 13, 13

Page 7: Pragmatic JavaScript

JavaScript is very different

JavaScript != CJavaScript != JavaJavaScript != Ruby

Friday, September 13, 13

Page 8: Pragmatic JavaScript

First I was likeimage: http://www.legacyperformancehorses.net

Friday, September 13, 13

Page 9: Pragmatic JavaScript

...then I was likeimage: http://www.flickr.com/photos/erniebm/

Friday, September 13, 13

Page 10: Pragmatic JavaScript

(this could be you)image: slapix.com

Friday, September 13, 13

Page 11: Pragmatic JavaScript

image: http://www.tyronestoddart.com

JavaScript is functionalFriday, September 13, 13

Page 12: Pragmatic JavaScript

Functions

1. an expression involving one or more variables… srsly, you had to read this?

function statement: a traditional function declarationfunction expression: an "inline" function with or without a name

12Friday, September 13, 13

Page 13: Pragmatic JavaScript

First-class functionsfunction transform (x) { return x * 2; }

// a function may be assigned to a variablevar func = transform;

// a function may have properties or be a propertyfunc.inverse = function (x) { return x / 2; };

// a function may be used as a parameter[1, 2, 3].map(func.inverse);

13Friday, September 13, 13

Page 14: Pragmatic JavaScript

First-class functions// a function may be a return valuefunction configure (options) { // choose a function based on ref data return options.flag ? addFoo : identity;}

function addFoo (x) { x.foo = 27; return x; }function identity (x) { return x; }

14Friday, September 13, 13

Page 15: Pragmatic JavaScript

Function scope// JavaScript implements lexical (static) scopingvar a = 7;function top () { var b = 20; return inner();

function inner () { // both `a` and `b` are available here return a + b; }}top(); // returns 27

15Friday, September 13, 13

Page 16: Pragmatic JavaScript

Function scope// JavaScript only has function scope, not block scopefunction silly () { var i = 20; for (var i = 0; i < 10; i++) { doSomething(i); } return i;}

silly(); // returns 10, not 20!

16Friday, September 13, 13

Page 17: Pragmatic JavaScript

EcmaScript 6 has block scope!// `let` is like `var`, but has block scopefunction silly () { var i = 20; for (let i = 0; i < 10; i++) { doSomething(i); } return i;}

silly(); // returns 10, as you'd expect!

17Friday, September 13, 13

Page 18: Pragmatic JavaScript

Side note: function and var hoisting// this is valid JavaScriptfunction foo () { a = 7; b = add(a, 13);

// inner functions are auto-hoisted to outer scope function add (x, y) { return x + y; }

// so are vars, but plz don't do this! // the statements above look like implicit globals var a, b;}

18Friday, September 13, 13

Page 19: Pragmatic JavaScript

Functions as propertiesvar obj = { val: 7 };

obj.method = function (x) { return x > 0 ? this.val : 0;};

// what happens when we do this?var m = obj.method;[1, 2, 3].map(m);

19Friday, September 13, 13

Page 20: Pragmatic JavaScript

Function contextfunction useful () { // what is `this` here? return this.foo;}

var myObj = { foo: 13, doSomething: useful };

// what about now?myObj.doSomething();

// function context is dynamic// and is applied by the dot operator!

20Friday, September 13, 13

Page 21: Pragmatic JavaScript

Function contextfunction legacy () { // `this` == `window` here return this.document;}

function strict () {"use strict"; // `this` is undefined here return this.document; // exception!}

21Friday, September 13, 13

Page 22: Pragmatic JavaScript

Side note: "use strict";// strict mode helps prevent many common mistakes,// including inadvertent / implicit globalsfunction lorem () { // put "use strict" at the very top of a function 'use strict'; a = 7; // throws a ReferenceError}

// never put "use strict" outside of a function!

// more about strict mode: bit.ly/strictMode

22Friday, September 13, 13

Page 23: Pragmatic JavaScript

Function context// call a function with context and argumentsmyFunc.call(context /*, arg1, arg2, ... */);

// another waymyFunc.apply(context, arrayOfArgs);

// ES5*: create a function that is hard-bound to a contextmyFunc.bind(context /*, arg1, arg2, ... */);

// *ES5 in legacy browsers? try cujoJS/poly @ cujojs.com

23Friday, September 13, 13

Page 24: Pragmatic JavaScript

Function context binding: a good use case// pass an object's method as a callback to a node functionvar fs = require('fs');var myHandler = new StatHandler();fs.stat('foo.txt', myHandler.handle.bind(myHandler));

// two other ways without `bind()`fs.stat('foo.txt', function () { return myHandler.handle.apply(myHandler, arguments);});fs.stat('foo.txt', function (err, stats) { return myHandler.handle(err, stats);});

24Friday, September 13, 13

Page 25: Pragmatic JavaScript

Immediately-Invoked Function Expression// IIFE ("iffy"):(function () { /* ... */ }());

// these also work, but plz don't:!function () { /* ... */ }();+function () { /* ... */ }();

// equivalent to this, but without a globalvar globalName = function () { /* ... */ };globalName();

25Friday, September 13, 13

Page 26: Pragmatic JavaScript

Example: IIFE to boot an app// look ma, no globals!(function (doc, global) { var el;

el = doc.createElement('script'); el.src = 'app/boot.js'; el.async = true; /* ... add error handling here ... */ doc.body.appendChild(el);

}(document, this));

26Friday, September 13, 13

Page 27: Pragmatic JavaScript

Example: debouncefunction debounce (func, msec) { var handle; return function () { var context = this, args = arguments; clearTimeout(handle); handle = setTimeout(function () { func.apply(context, args); }, msec); };}

27Friday, September 13, 13

Page 28: Pragmatic JavaScript

Example: Crockford-Cornford beget// add "true prototypal" inheritance to JavaScriptvar create = Object.create /* ES5* */ || (function (Base) { return function (parent) { Base.prototype = parent; var child = new Base(); Base.prototype = null; return child; }; }(function () {}));

// *ES5 in legacy browsers? try cujoJS/poly @ cujojs.com

28Friday, September 13, 13

Page 29: Pragmatic JavaScript

image: http://toferet.wordpress.comJavaScript loves boxes

closures!

Friday, September 13, 13

Page 30: Pragmatic JavaScript

Closures

1. a function that refers to variables in its lexical scope keeps a reference to the scope. This pair -- the function invocation and its entire scope -- is called a closure.

This MDN Article has great examples, even if it doesn't quite define closures correctly: bit.ly/MDN-closures

30Friday, September 13, 13

Page 31: Pragmatic JavaScript

Closures// every function creates a closurevar a = 42;// `top` closes over `a`function top () { var b = 27; // `inner` closes over `a` and `b` return function inner () { return a + b; }}

// (yawn)

31Friday, September 13, 13

Page 32: Pragmatic JavaScript

Closures: the interesting partvar a = 42;function top () { var b = 27; return function inner () { return a + b; }}// closures only become interesting when we force them to// exist beyond function invocation. `a` and `b` continue// to exist until `func` goes out of scope.var func = top();setTimeout(func, 500);

32Friday, September 13, 13

Page 33: Pragmatic JavaScript

Closures: the bad part// loop + non-local vars + closures --> FAIL!function createCombo (createOne, notify, data) { var notifiers = []; for (var i = 0; i < data.length; i++) { var thing = createOne(data[i]); notifiers.push(function () { notify(thing); }); } return notifiers;}// hint: what is the scope of `thing`?// later, what value does `thing` have?

33Friday, September 13, 13

Page 34: Pragmatic JavaScript

Closures: the bad part// one easy solution: make closures and loop data 1:1function createCombo (createOne, notify, data) { // create a closure for each `thing` via ES5's map()* return data.map(function (item) { var thing = createOne(item); return function () { notify(thing); }; });}

34Friday, September 13, 13

Page 35: Pragmatic JavaScript

Learn more about functional JavaScript• "Must read" book:

–Effective JavaScript by David Herman

35Friday, September 13, 13

Page 36: Pragmatic JavaScript

JavaScript is prototypalimage: http://www.flickr.com/photos/doug88888

Friday, September 13, 13

Page 37: Pragmatic JavaScript

Prototypal inheritance

1. denoting the original of which something else is a copy or derivative.

prototypal inheritance: a descendent is a derivative of an ancestor and, therefore, inherits the traits of the ancestor.

37Friday, September 13, 13

Page 38: Pragmatic JavaScript

Prototypal inheritance• In "true" prototypal inheritance, objects inherit directly from

other objects:–prototype chain: parent <-- child <-- grandchild

38Friday, September 13, 13

Page 39: Pragmatic JavaScript

Prototypal inheritance# "true" prototypal inheritance (not javascript):child <- beget(parent);

# child specializationchild.baz <- function () { /* ... */ }

39Friday, September 13, 13

Page 40: Pragmatic JavaScript

Prototypal inheritance in JavaScript// ES5's `Object.create()`* for true prototypal inheritance:var parent = { foo: 42, bar: 7, baz: function () {}};

var child = Object.create(parent); // prototype chainchild.baz = function () { parent.baz.apply(this, arguments); };

// *ES5 in legacy browsers? try cujoJS/poly @ cujojs.com

40Friday, September 13, 13

Page 41: Pragmatic JavaScript

Not-quite-prototypal inheritance• In JavaScript, a "type" or a "class" is the pairing of a

prototype object with a constructor.• Instances of "types" are created by using the `new` operator

on a constructor-prototype pair.• The instance object has its own properties, but also "inherits"

properties from its constructor's prototype.–prototype chain: prototype <-- instance

41Friday, September 13, 13

Page 42: Pragmatic JavaScript

Not-quite-prototypal inheritance// constructor-prototype pairfunction Thing () {}Thing.prototype = { /* ... */ };

// JavaScript uses the `new` operator.var thing = new Thing();

// #truefact: the `new` operator was meant to make // JavaScript feel more like Java. did it work?

42Friday, September 13, 13

Page 43: Pragmatic JavaScript

Not-quite-prototypal inheritance• Inheritance of "types" occurs through this same mechanism.• To create child "type", pair the child's constructor with an

instance of the parent:–parent.prototype <-- parent instance/child prototype <-- child

43Friday, September 13, 13

Page 44: Pragmatic JavaScript

Not-quite-prototypal inheritance// create a parent constructor-prototype pairfunction Parent () {} // constructorParent.prototype = { foo: 42, bar: 7 };

// create a child constructor-prototype pair// that chains the parent's prototype via `new`function Child () {}Child.prototype = new Parent(); // prototype chaining

// specialize child prototypeChild.prototype.baz = function () {};

44Friday, September 13, 13

Page 45: Pragmatic JavaScript

Prototype chain: `new Child();`Object.prototype ^ - has several built-in methods |Parent.prototype ^ - has `foo`, `bar` |Child.prototype = new Parent() // instance of Parent ^ | child - has `baz` which overrides Parent.prototype `baz`

45Friday, September 13, 13

Page 46: Pragmatic JavaScript

Constructors: benefits• Accept initialization parameters• Execute initialization code• Allow us to hide implementation details

46Friday, September 13, 13

Page 47: Pragmatic JavaScript

Constructors• Public properties: anything on the prototype

–Protected-by-convention: denoted by a leading or trailing "_"• Privileged: instance methods created in the constructor

–Have access to local vars• Private: local variables and functions in the constructor

–Variables, actually, not properties

47Friday, September 13, 13

Page 48: Pragmatic JavaScript

Private and privileged// constructors can add properties, too.// added bonus! we have "private" vars!function Parent (val) { // "private" things var secret = 7 + val; // "privileged" things (instance properties) this.get = function () { return secret; };} // "public" thingsParent.prototype = { foo: 42, bar: 7 };Parent.prototype.baz = function () {};

48Friday, September 13, 13

Page 49: Pragmatic JavaScript

Super// how do we inherit private and privileged properties?// you don't directly, but here's how we call "super":function Child (val) { // calling the "super" constructor in our context: Parent.apply(this, arguments);}

Child.prototype = new Parent();Child.prototype.baz = function () { // calling a "super" method return Parent.prototype.baz.apply(this, arguments);};

49Friday, September 13, 13

Page 50: Pragmatic JavaScript

Prototype chain: `new Child(val);`Object.prototype ^ - has several built-in methods |Parent.prototype ^ - has `foo`, `bar`, `baz` |Child.prototype = new Parent() // instance of Parent ^ - has `get`, `baz` that overrides Parent.prototype | child - has `get` which overrides Child.prototype `get` on the prototype

50Friday, September 13, 13

Page 51: Pragmatic JavaScript

Constructors: pitfall// parent constructor takes an argumentfunction Parent (val) { var secret = 7 + val; this.get = function () { return secret; };} /* Parent.prototype = ... */

// prototype chaining doesn't provide an argument!function Child (val) { /* ... */ }Child.prototype = new Parent(); // <-- **ouch!**

51Friday, September 13, 13

Page 52: Pragmatic JavaScript

Prototype chain: `new Child(val);`Object.prototype ^ - has several built-in methods |Parent.prototype ^ - has `foo`, `bar`, `baz` |Child.prototype = new Parent() // instance of Parent ^ - has `get`, `baz` that overrides Parent.prototype | child - has `get` which overrides Child.prototype `get` on the prototype because we call Parent.apply!

52Friday, September 13, 13

Page 53: Pragmatic JavaScript

why not surprised?

ur inheritance horks hairballs

image: the internetzFriday, September 13, 13

Page 54: Pragmatic JavaScript

True prototypal inheritance// `Object.create()` also fixes prototype chaining issues:function Child (val) { Parent.apply(this, arguments);}

// no `new Parent()`! yay! Child.prototype = Object.create(Parent.prototype); /* Child.prototype.baz = ... */

54Friday, September 13, 13

Page 55: Pragmatic JavaScript

Prototype chain: `new Child(val);`Object.prototype ^ - has several built-in methods |Parent.prototype ^ - has `foo`, `bar`, `baz` |Child.prototype = Object.create(Parent.prototype) ^ - no longer calls `new Parent()` | - has `baz` that overrides Parent.prototype child - has `get`

55Friday, September 13, 13

Page 56: Pragmatic JavaScript

Example: configuration options// inherit from a user-supplied "options" object so we// don't pollute it when we fill-in default values.function createBindableView (node, options) { var viewOptions, view; viewOptions = Object.create(options); if (!('render' in viewOptions) { viewOptions.render = defaultRender; } view = createView(node, viewOptions); return bindableView(options, view);}

56Friday, September 13, 13

Page 57: Pragmatic JavaScript

Learn more about prototypal JavaScript• "Must read" book:

–Effective JavaScript by David Herman–(no, I don't receive a commission :) )

57Friday, September 13, 13

Page 58: Pragmatic JavaScript

JavaScript is asyncimage: http://www.puccimanuli.com

Friday, September 13, 13

Page 59: Pragmatic JavaScript

No concurrency• Things happen in parallel:

–XHR, iframes–Loading of scripts, stylesheets–"DOM ready"–CSS animations

• But code executes in a single thread!• Also: no formal language constructs (yet)

59Friday, September 13, 13

Page 60: Pragmatic JavaScript

No concurrency: how can this work?• De facto Javascript environment:

–A global event queue–Event handlers for each event run to completion before next

event is handled• Continuation passing via first-class functions

60Friday, September 13, 13

Page 61: Pragmatic JavaScript

Continuation passing• The simplest "functional" solution is to pass callback functions• Typical: one callback per type of continuation:

–success, fail, progress, etc.• Sensible implementations never call callback functions

immediately

61Friday, September 13, 13

Page 62: Pragmatic JavaScript

Example: xhrfunction xhr (type, url, callback, errback) { // go do something long-running // eventually, when some event occurs, // call either `callback` or `errback`}

xhrGet('GET', '/result', success, failure);console.log('getting');

function success () { console.log('got it'); }function failure () { console.log('i has a sad'); }

62Friday, September 13, 13

Page 63: Pragmatic JavaScript

Continuation passing: cons• Results are no longer returned from functions• All functions involved in async operations must pass

callbacks• Messy, messy, messy

63Friday, September 13, 13

Page 64: Pragmatic JavaScript

Example: xhrfunction xhrGet (url, callback, errback) { try { xhr('GET', url, callback, errback); } catch (ex) { errback(ex); }}

xhrGet('/result', success, failure);

64Friday, September 13, 13

Page 65: Pragmatic JavaScript

Example: xhr with fallbackfunction getTheResult (callback, errback) { xhrGet('/result', callback, function (ex) { if (test404(ex)) { xhrGet('/result2', callback, errback); } else { errback(ex); } });}

function xhrGet (url, callback, errback) { try { xhr('GET', url, callback, errback); } catch (ex) { errback(ex); }}

function test404 (ex) { return /not found/i.test(ex.message)); }

getTheResult(success, failure);

65Friday, September 13, 13

Page 66: Pragmatic JavaScript

Example: coordinate 2 xhr POSTsfunction postBoth (success, failure) { var count = 2, results = [], failed; xhrPost('/one', yay.bind(null, 0), nay); xhrPost('/two', yay.bind(null, 1), nay); function yay (i, result) { results[i] = result; if (--count == 0 && !failed) success(results); } function nay (ex) { if (!failed) { failed = true; failure(ex); } }}

66Friday, September 13, 13

Page 67: Pragmatic JavaScript

Example: coordinate 2 xhr POSTs w/ rollback

[code redacted]

67Friday, September 13, 13

Page 68: Pragmatic JavaScript

now i has puke in my mouth

lookd at ur async java scripts

image: the internetzFriday, September 13, 13

Page 69: Pragmatic JavaScript

Is JavaScript doomed?

Nah, we have a solution.The solution was invented in the 70's like everything else.

Friday, September 13, 13

Page 70: Pragmatic JavaScript

JavaScript + Promisesimage: http://www.flickr.com/photos/aimlessbrooke/

Friday, September 13, 13

Page 71: Pragmatic JavaScript

Promises• Eliminate continuation passing• Allow us to reason about async code similarly to sequential,

procedural code–List async tasks in sequence–Mimic try-catch-finally semantics

• Restore composability to async code–Functions can return values or promises (functional composition) –Promises are composable

71Friday, September 13, 13

Page 72: Pragmatic JavaScript

Promises de facto standards• 2009: Evolved from dojo (Kris Zyp)

–Defined "thenables" with a very simple API: • obj.then(callback, errback [, progress]) -> thenable

–Simple, but underspecified: compatibility languished–Broken implementations (e.g. $.Defer)

• 2012: Brain Cavalier and Domenic Denicola revived efforts!–Promises/A+

• Step 1: tighten up `then` (done!)• Next: standardize advanced concepts

72Friday, September 13, 13

Page 73: Pragmatic JavaScript

Promises/A+• Spec: http://promisesaplus.com/ • Wide adoption

–cujoJS/when http://cujojs.com –Q: https://github.com/kriskowal/q–Complete list: http://bit.ly/promises-aplus-impls

• Likely to be incorporated into ES6 and HTML5!

73Friday, September 13, 13

Page 74: Pragmatic JavaScript

Example: distract user while loading UI// load the specified UI packagefunction loadAppFeature(package) { // a promise "pipeline": return showBusyIndicator() .then(curl([package])) // fetch .then(showMainView) // display .then(hideBusyIndicator);}// Notice how the value `main` is propagatedfunction showMainView (main) { return wire(main); // returns a promise!}

74Friday, September 13, 13

Page 75: Pragmatic JavaScript

Example: try-catch-finally semantics// sync semantics we'd like// to mimic:function foo (url) { var r = xhr(url); try { r.send(); // sync! } catch (ex) { logError(ex); } finally { cleanup(); }}

// how it would look using// cujoJS/when:function foo (url) { var r = xhr(url);

return lift(r.send) .otherwise(logError) .ensure(cleanup);}

75Friday, September 13, 13

Page 76: Pragmatic JavaScript

Example: xhr with fallback using promises// async operation with fallback using promisesfunction getTheResult () { return xhr('/result') .then(null, function (ex) { if (!test404(ex)) throw ex; return xhr('/result2') });}

function xhr (url) { return lift(xhrGet.bind(null, url));}

function test404 (ex) { return /not found/i.test(ex.message); }

getTheResult.then(doSomething, console.error.bind(console));

76Friday, September 13, 13

Page 77: Pragmatic JavaScript

Learn more about Promises• Awesome tutorials on async and promises:

–http://know.cujojs.com/tutorials• Spec: http://promisesaplus.com

77Friday, September 13, 13

Page 78: Pragmatic JavaScript

JavaScript can be modularimage: http://wallpapersus.com

Friday, September 13, 13

Page 79: Pragmatic JavaScript

Modules: benefits• Code organization

–Small files, focused tests• End reliance on globals

–Reduces namespace conflicts –Reduces dependency hell

• Dependency management–IDE support–Build support

79Friday, September 13, 13

Page 80: Pragmatic JavaScript

Example: a "Module pattern" module// create an IIFE and pass our "namespace" to it(function (ns) {

// declare module var myModule = { foo: 7, bar: 42 }; myModule.doSomething = function (val) { return ns.util.dom.foo(val); };

// "export" our module; ns.myModule = myModule;}(window.namespace = window.namespace || {}));

80Friday, September 13, 13

Page 81: Pragmatic JavaScript

Module pattern: dependency hell• Too easy to reach into arbitrarily deep namespaces

****from anywhere in code****• Can't remap or alias namespaces

–Multiple versions of code bases–"Primitive" DI support

81Friday, September 13, 13

Page 82: Pragmatic JavaScript

Module pattern: "dependency management"<script src="client/util/dom.js"><script><!-- Note: widgets.js contains ns.util.dom.popup due to a circular dependency --><script src="client/app/widgets.js"><script><script src="client/app/myModule.js"><script><!-- Note: always put myChildModule after app/cust.js since it uses ns.flag! --><script src="client/app/cust.js"><script><script src="client/app/myChildModule.js"><script><script src="client/start.js"><script>

82Friday, September 13, 13

Page 83: Pragmatic JavaScript

it was awwful

tried ur modyule patturrrn

image: the internetzFriday, September 13, 13

Page 84: Pragmatic JavaScript

Formal modules for JavaScript• Asynchronous Module Definition• CommonJS Modules/1.1• ES6 Modules

84Friday, September 13, 13

Page 85: Pragmatic JavaScript

AMD• Started by James Burke ~2009• Improvement / replacement to dojo's module system• Later, would coordinate with CommonJS efforts• Supports all major browsers • And node.js

–cujoJS/curl, r.js

85Friday, September 13, 13

Page 86: Pragmatic JavaScript

AMD• Implementations

–RequireJS: http://requirejs.org/–cujoJS/curl: http://cujojs.com/–dojo–LinkedIn's Inject.js–dozens of others

86Friday, September 13, 13

Page 87: Pragmatic JavaScript

AMD modulesdefine(['util/dom', 'util/cust'], function (dom, cust) { var myModule = { foo: 7, bar: 42, baz: function(){ return cust.flag?this.foo:this.bar; } }; myModule.doSomething = function (val) { return dom.foo(val); }; return myModule;});

87Friday, September 13, 13

Page 88: Pragmatic JavaScript

AMD modules: benefits• Dependencies are easy to discover since they are

****specified at the interface of the module****• Many options and syntax variations • Build tools are readily available

–cujoJS/cram http://cujojs.com –r.js https://github.com/jrburke/r.js/–dojo, etc.

• IDE support–Scripted, IntelliJ, etc.

88Friday, September 13, 13

Page 89: Pragmatic JavaScript

AMD modules: cons• Many find the boilerplate to be verbose and ugly• Adds some overhead to file size and load time• Many options and syntax variations

-- confusing to newbs and parsers!• Doesn't handle dependency cycles

–A syntax variant does, however.

89Friday, September 13, 13

Page 90: Pragmatic JavaScript

CommonJS modules• Spearheaded by Kris Kowal ~2009• Ignored the needs of browsers in favor of a "clean slate"• Influenced by other dynamic languages• Current version 1.1.1

90Friday, September 13, 13

Page 91: Pragmatic JavaScript

CommonJS modules• Implementations

–Server• node.js, vert.x, RingoJS

• And browser environments–Browsers (build step required)

• browserify, RequireJS–Browsers (build step optional during dev)

• cujoJS/curl

91Friday, September 13, 13

Page 92: Pragmatic JavaScript

CommonJS modulesvar dom = require('util/dom');var cust = require('util/cust');

exports.foo = 7;exports.bar = 42;exports.baz = function () { return cust.flag ? this.foo : this.bar;};exports.doSomething = function (val) { return dom.foo(val);};

92Friday, September 13, 13

Page 93: Pragmatic JavaScript

CommonJS modules: node.js variantvar dom = require('util/dom');var cust = require('util/cust');

module.exports = { foo: 7, bar: 42, baz: function () { return cust.flag?this.foo:this.bar; }, doSomething: function (val) { return dom.foo(val); }};

93Friday, September 13, 13

Page 94: Pragmatic JavaScript

CommonJS modules: pitfalls// BAD: dynamic module lookupvar isBrowser = typeof window != 'undefined';var dom = require(isBrowser ? 'util/dom' : 'util/node-dom');

module.exports = { foo: 7, bar: 42, baz: function () { // BAD: deep dependency return require('cust').flag ? this.foo : this.bar; }};

94Friday, September 13, 13

Page 95: Pragmatic JavaScript

CommonJS modules: benefits• Cleaner syntax than AMD• Wide support on server side, some browser support• Supports dependency cycles (but just don't, plz!)• IDE support

–Scripted, IntelliJ, etc.

95Friday, September 13, 13

Page 96: Pragmatic JavaScript

CommonJS modules: cons• No direct browser support

–Requires a build step or on-the-fly conversion to AMD• Discourages, but does not eliminate, deep dependencies• Reliance on sync require(id) limits portability• Soon to be replaced by an official standard?....

96Friday, September 13, 13

Page 97: Pragmatic JavaScript

ES6 modules• Finally!!!! An official standard for JavaScript modules!• Part of EcmaScript 6• Enforces static dependency analysis• Provides hooks for consuming AMD and CommonJS

97Friday, September 13, 13

Page 98: Pragmatic JavaScript

ES6 modules: cons• Don't expect to use ES6 modules in production until…

201698

Friday, September 13, 13

Page 99: Pragmatic JavaScript

Learn more about: modules• Simple tutorials: http://know.cujojs.com/tutorials

–"Best JavaScript modules tutorials on the web" -- Brian Arnold, SitePen trainer

• Great overview: http://addyosmani.com/writing-modular-js/ • AMD wiki: https://github.com/amdjs/amdjs-api/wiki

99Friday, September 13, 13

Page 100: Pragmatic JavaScript

Ready to go for it?image: slapix.com

Friday, September 13, 13

Page 101: Pragmatic JavaScript

Code docs in JavaScript?• Yep! It's called JSDoc• jsdoc-toolkit: https://code.google.com/p/jsdoc-toolkit/• @use JSDoc: http://usejsdoc.org/

101Friday, September 13, 13

Page 102: Pragmatic JavaScript

AOP in JavaScript?• YES!• Possible because function context is dynamic!• See Brian Cavalier's talk this afternoon

102Friday, September 13, 13

Page 103: Pragmatic JavaScript

IOC in JavaScript?• You bet!• cujoJS/wire http://cujojs.com

103Friday, September 13, 13

Page 104: Pragmatic JavaScript

RESTful patterns?• You know it!• Backbone: http://backbonejs.org/• cujoJS/rest: http://cujojs.com

104Friday, September 13, 13

Page 105: Pragmatic JavaScript

Enterprise Messaging?• Yes, even that.• cujoJS/msgs: http://cujojs.com

105Friday, September 13, 13

Page 106: Pragmatic JavaScript

Data modeling and data binding?• Uh huh.• Check out the next JavaScript session with Scott Andrews,

Tim Branyen, and Matias Niemela

106Friday, September 13, 13

Page 107: Pragmatic JavaScript

Questions?image: http://www.flickr.com/photos/rooreynolds/

Friday, September 13, 13

Page 108: Pragmatic JavaScript

Links• Tutorials: http://know.cujojs.com/tutorials• cujoJS: cujojs.com• strict mode: bit.ly/strictMode • MDN Closures: bit.ly/MDN-closures • Effective JavaScript: amzn.to/19HrldV • Promises/A+: promisesaplus.com/

– Implementations: bit.ly/promises-aplus-impls • Modules: github.com/amdjs/amdjs-api/wiki• AMD wiki: github.com/amdjs/amdjs-api/wiki• jsdoc-toolkit: code.google.com/p/jsdoc-toolkit/

108Friday, September 13, 13