SlideShare uma empresa Scribd logo
1 de 108
Baixar para ler offline
Pragmatic JavaScript
John Hann / @unscriptable
JavaScript Barbarian at Pivotal / cujoJS Co-lead

© 2013 SpringOne 2GX. All rights reserved. Do not distribute without permission.
Friday, September 13, 13
Why are you here today?

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

Friday, September 13, 13
Why are you here today?

To learn more about JavaScript?

Friday, September 13, 13
did you get burned by JavaScript?

image: gifbin.com

Friday, September 13, 13
image: gifbin.com
Friday, September 13, 13

can't quite grok it?
Let's get one thing straight

JavaScript != Java

Friday, September 13, 13
JavaScript is very different

JavaScript != C
JavaScript != Java
JavaScript != Ruby
Friday, September 13, 13
image: http://www.legacyperformancehorses.net
Friday, September 13, 13

First I was like
image: http://www.flickr.com/photos/erniebm/
Friday, September 13, 13

...then I was like
image: slapix.com
Friday, September 13, 13

(this could be you)
JavaScript is functional

image: http://www.tyronestoddart.com
Friday, September 13, 13
Functions

1. an expression involving one or more variables… srsly, you
had to read this?
function statement: a traditional function declaration
function expression: an "inline" function with or without a name

12
Friday, September 13, 13
First-class functions
function transform (x) { return x * 2; }
// a function may be assigned to a variable
var func = transform;
// a function may have properties or be a property
func.inverse = function (x) { return x / 2; };
// a function may be used as a parameter
[1, 2, 3].map(func.inverse);

13
Friday, September 13, 13
First-class functions
// a function may be a return value
function 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; }

14
Friday, September 13, 13
Function scope
// JavaScript implements lexical (static) scoping
var a = 7;
function top () {
var b = 20;
return inner();
function inner () {
// both `a` and `b` are available here
return a + b;
}

}
top(); // returns 27

15
Friday, September 13, 13
Function scope
// JavaScript only has function scope, not block scope
function silly () {
var i = 20;
for (var i = 0; i < 10; i++) {
doSomething(i);
}
return i;
}
silly(); // returns 10, not 20!

16
Friday, September 13, 13
EcmaScript 6 has block scope!
// `let` is like `var`, but has block scope
function silly () {
var i = 20;
for (let i = 0; i < 10; i++) {
doSomething(i);
}
return i;
}
silly(); // returns 10, as you'd expect!

17
Friday, September 13, 13
Side note: function and var hoisting
// this is valid JavaScript
function 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;

18
Friday, September 13, 13
Functions as properties
var 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);

19
Friday, September 13, 13
Function context
function 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!

20
Friday, September 13, 13
Function context
function legacy () {
// `this` == `window` here
return this.document;
}
function strict () {
"use strict";
// `this` is undefined here
return this.document; // exception!
}

21
Friday, September 13, 13
Side note: "use strict";
// strict mode helps prevent many common mistakes,
// including inadvertent / implicit globals
function 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

22
Friday, September 13, 13
Function context
// call a function with context and arguments
myFunc.call(context /*, arg1, arg2, ... */);
// another way
myFunc.apply(context, arrayOfArgs);
// ES5*: create a function that is hard-bound to a context
myFunc.bind(context /*, arg1, arg2, ... */);

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

23
Friday, September 13, 13
Function context binding: a good use case
// pass an object's method as a callback to a node function
var 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);
});

24
Friday, September 13, 13
Immediately-Invoked Function Expression
// IIFE ("iffy"):
(function () { /* ... */ }());
// these also work, but plz don't:
!function () { /* ... */ }();
+function () { /* ... */ }();
// equivalent to this, but without a global
var globalName = function () { /* ... */ };
globalName();

25
Friday, September 13, 13
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));

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

27
Friday, September 13, 13
Example: Crockford-Cornford beget
// add "true prototypal" inheritance to JavaScript
var 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

28
Friday, September 13, 13
s!
ure
los
c

JavaScript loves boxes

image: http://toferet.wordpress.com
Friday, September 13, 13
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

30
Friday, September 13, 13
Closures
// every function creates a closure
var a = 42;
// `top` closes over `a`
function top () {
var b = 27;
// `inner` closes over `a` and `b`
return function inner () {
return a + b;
}
}
// (yawn)

31
Friday, September 13, 13
Closures: the interesting part
var 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);

32
Friday, September 13, 13
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?

33
Friday, September 13, 13
Closures: the bad part
// one easy solution: make closures and loop data 1:1
function 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);
};
});
}

34
Friday, September 13, 13
Learn more about functional JavaScript
• "Must read" book:
–Effective JavaScript by David Herman

35
Friday, September 13, 13
JavaScript is prototypal

image: http://www.flickr.com/photos/doug88888
Friday, September 13, 13
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.

37
Friday, September 13, 13
Prototypal inheritance
• In "true" prototypal inheritance, objects inherit directly from
other objects:
–prototype chain: parent <-- child <-- grandchild

38
Friday, September 13, 13
Prototypal inheritance
# "true" prototypal inheritance (not javascript):
child <- beget(parent);
# child specialization
child.baz <- function () { /* ... */ }

39
Friday, September 13, 13
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 chain
child.baz = function () {
parent.baz.apply(this, arguments);
};
// *ES5 in legacy browsers? try cujoJS/poly @ cujojs.com

40
Friday, September 13, 13
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

41
Friday, September 13, 13
Not-quite-prototypal inheritance
// constructor-prototype pair
function 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?

42
Friday, September 13, 13
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

43
Friday, September 13, 13
Not-quite-prototypal inheritance
// create a parent constructor-prototype pair
function Parent () {} // constructor
Parent.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 prototype
Child.prototype.baz = function () {};

44
Friday, September 13, 13
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`

45
Friday, September 13, 13
Constructors: benefits
• Accept initialization parameters
• Execute initialization code
• Allow us to hide implementation details

46
Friday, September 13, 13
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

47
Friday, September 13, 13
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" things
Parent.prototype = { foo: 42, bar: 7 };
Parent.prototype.baz = function () {};

48
Friday, September 13, 13
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);
};

49
Friday, September 13, 13
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

50
Friday, September 13, 13
Constructors: pitfall
// parent constructor takes an argument
function 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!**

51
Friday, September 13, 13
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!

52
Friday, September 13, 13
ur inheritance horks hairballs

image: the internetz
Friday, September 13, 13

why not surprised?
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 = ... */

54
Friday, September 13, 13
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`

55
Friday, September 13, 13
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);
}

56
Friday, September 13, 13
Learn more about prototypal JavaScript
• "Must read" book:
–Effective JavaScript by David Herman
–(no, I don't receive a commission :) )

57
Friday, September 13, 13
image: http://www.puccimanuli.com
Friday, September 13, 13

JavaScript is async
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)

59
Friday, September 13, 13
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

60
Friday, September 13, 13
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

61
Friday, September 13, 13
Example: xhr
function 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'); }

62
Friday, September 13, 13
Continuation passing: cons
• Results are no longer returned from functions
• All functions involved in async operations must pass
callbacks
• Messy, messy, messy

63
Friday, September 13, 13
Example: xhr
function xhrGet (url, callback, errback) {
try { xhr('GET', url, callback, errback); }
catch (ex) { errback(ex); }
}
xhrGet('/result', success, failure);

64
Friday, September 13, 13
Example: xhr with fallback
function 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);

65
Friday, September 13, 13
Example: coordinate 2 xhr POSTs
function 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); }
}
}

66
Friday, September 13, 13
Example: coordinate 2 xhr POSTs w/ rollback

[code redacted]

67
Friday, September 13, 13
lookd at ur async java scripts

image: the internetz
Friday, September 13, 13

now i has puke in my mouth
Is JavaScript doomed?
Nah, we have a solution.
The solution was invented in the 70's like everything else.

Friday, September 13, 13
JavaScript + Promises

image: http://www.flickr.com/photos/aimlessbrooke/
Friday, September 13, 13
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

71
Friday, September 13, 13
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

72
Friday, September 13, 13
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!

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

74
Friday, September 13, 13
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();
}
}

75
Friday, September 13, 13

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

}

return lift(r.send)
.otherwise(logError)
.ensure(cleanup);
Example: xhr with fallback using promises
// async operation with fallback using promises
function 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));

76
Friday, September 13, 13
Learn more about Promises
• Awesome tutorials on async and promises:
–http://know.cujojs.com/tutorials

• Spec: http://promisesaplus.com

77
Friday, September 13, 13
JavaScript can be modular

image: http://wallpapersus.com
Friday, September 13, 13
Modules: benefits
• Code organization
–Small files, focused tests

• End reliance on globals
–Reduces namespace conflicts
–Reduces dependency hell

• Dependency management
–IDE support
–Build support

79
Friday, September 13, 13
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 || {}));

80
Friday, September 13, 13
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

81
Friday, September 13, 13
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>

82
Friday, September 13, 13
tried ur modyule patturrrn

image: the internetz
Friday, September 13, 13

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

84
Friday, September 13, 13
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

85
Friday, September 13, 13
AMD
• Implementations
–RequireJS: http://requirejs.org/
–cujoJS/curl: http://cujojs.com/
–dojo
–LinkedIn's Inject.js
–dozens of others

86
Friday, September 13, 13
AMD modules
define(['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;
});

87
Friday, September 13, 13
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.
88
Friday, September 13, 13
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.

89
Friday, September 13, 13
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

90
Friday, September 13, 13
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

91
Friday, September 13, 13
CommonJS modules
var 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);
};

92
Friday, September 13, 13
CommonJS modules: node.js variant
var 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);
}
};

93
Friday, September 13, 13
CommonJS modules: pitfalls
// BAD: dynamic module lookup
var 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;
}
};

94
Friday, September 13, 13
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.

95
Friday, September 13, 13
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?....

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

97
Friday, September 13, 13
ES6 modules: cons
• Don't expect to use ES6 modules in production until…

2016
98
Friday, September 13, 13
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

99
Friday, September 13, 13
image: slapix.com
Friday, September 13, 13

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

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

102
Friday, September 13, 13
IOC in JavaScript?
• You bet!
• cujoJS/wire http://cujojs.com

103
Friday, September 13, 13
RESTful patterns?
• You know it!
• Backbone: http://backbonejs.org/
• cujoJS/rest: http://cujojs.com

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

105
Friday, September 13, 13
Data modeling and data binding?
• Uh huh.
• Check out the next JavaScript session with Scott Andrews,
Tim Branyen, and Matias Niemela

106
Friday, September 13, 13
image: http://www.flickr.com/photos/rooreynolds/
Friday, September 13, 13

Questions?
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/

108
Friday, September 13, 13

Mais conteúdo relacionado

Semelhante a Pragmatic JavaScript

Intro to Ember.js
Intro to Ember.jsIntro to Ember.js
Intro to Ember.jsJay Phelps
 
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...Richard McIntyre
 
Ember and containers
Ember and containersEmber and containers
Ember and containersMatthew Beale
 
Dinosaurs and Androids: The Listview Evolution
Dinosaurs and Androids: The Listview EvolutionDinosaurs and Androids: The Listview Evolution
Dinosaurs and Androids: The Listview EvolutionFernando Cejas
 
Zeno rocha - HTML5 APIs para Mobile
Zeno rocha - HTML5 APIs para MobileZeno rocha - HTML5 APIs para Mobile
Zeno rocha - HTML5 APIs para MobileiMasters
 
Securing Client Side Data
 Securing Client Side Data Securing Client Side Data
Securing Client Side DataGrgur Grisogono
 
Using Objects to Organize your jQuery Code
Using Objects to Organize your jQuery CodeUsing Objects to Organize your jQuery Code
Using Objects to Organize your jQuery CodeRebecca Murphey
 
Introduction to RabbitMQ | Meetup at Pivotal Labs
Introduction to RabbitMQ | Meetup at Pivotal LabsIntroduction to RabbitMQ | Meetup at Pivotal Labs
Introduction to RabbitMQ | Meetup at Pivotal LabsAlvaro Videla
 
Crafting Quality PHP Applications (PHP Joburg Oct 2019)
Crafting Quality PHP Applications (PHP Joburg Oct 2019)Crafting Quality PHP Applications (PHP Joburg Oct 2019)
Crafting Quality PHP Applications (PHP Joburg Oct 2019)James Titcumb
 
Javascript Everywhere
Javascript EverywhereJavascript Everywhere
Javascript Everywhereelliando dias
 
Keeping it small - Getting to know the Slim PHP micro framework
Keeping it small - Getting to know the Slim PHP micro frameworkKeeping it small - Getting to know the Slim PHP micro framework
Keeping it small - Getting to know the Slim PHP micro frameworkJeremy Kendall
 
JavaScript Closures for Dummies & JavaScript prototype, closures and OOP.
JavaScript Closures for Dummies & JavaScript prototype, closures and OOP.JavaScript Closures for Dummies & JavaScript prototype, closures and OOP.
JavaScript Closures for Dummies & JavaScript prototype, closures and OOP.Jin-Hwa Kim
 
How to write better code: in-depth best practices for writing readable, simpl...
How to write better code: in-depth best practices for writing readable, simpl...How to write better code: in-depth best practices for writing readable, simpl...
How to write better code: in-depth best practices for writing readable, simpl...Oursky
 
How to write better code: in-depth best practices for writing readable, simpl...
How to write better code: in-depth best practices for writing readable, simpl...How to write better code: in-depth best practices for writing readable, simpl...
How to write better code: in-depth best practices for writing readable, simpl...Jane Chung
 
Writing JavaScript that doesn't suck
Writing JavaScript that doesn't suckWriting JavaScript that doesn't suck
Writing JavaScript that doesn't suckRoss Bruniges
 

Semelhante a Pragmatic JavaScript (20)

Intro to Ember.js
Intro to Ember.jsIntro to Ember.js
Intro to Ember.js
 
Backbone
BackboneBackbone
Backbone
 
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
 
DrupalCon jQuery
DrupalCon jQueryDrupalCon jQuery
DrupalCon jQuery
 
Intro tobackbone
Intro tobackboneIntro tobackbone
Intro tobackbone
 
Ember and containers
Ember and containersEmber and containers
Ember and containers
 
Dinosaurs and Androids: The Listview Evolution
Dinosaurs and Androids: The Listview EvolutionDinosaurs and Androids: The Listview Evolution
Dinosaurs and Androids: The Listview Evolution
 
Zeno rocha - HTML5 APIs para Mobile
Zeno rocha - HTML5 APIs para MobileZeno rocha - HTML5 APIs para Mobile
Zeno rocha - HTML5 APIs para Mobile
 
Securing Client Side Data
 Securing Client Side Data Securing Client Side Data
Securing Client Side Data
 
Using Objects to Organize your jQuery Code
Using Objects to Organize your jQuery CodeUsing Objects to Organize your jQuery Code
Using Objects to Organize your jQuery Code
 
Introduction to RabbitMQ | Meetup at Pivotal Labs
Introduction to RabbitMQ | Meetup at Pivotal LabsIntroduction to RabbitMQ | Meetup at Pivotal Labs
Introduction to RabbitMQ | Meetup at Pivotal Labs
 
Crafting Quality PHP Applications (PHP Joburg Oct 2019)
Crafting Quality PHP Applications (PHP Joburg Oct 2019)Crafting Quality PHP Applications (PHP Joburg Oct 2019)
Crafting Quality PHP Applications (PHP Joburg Oct 2019)
 
Dig1108 Lesson 3
Dig1108 Lesson 3Dig1108 Lesson 3
Dig1108 Lesson 3
 
Javascript
JavascriptJavascript
Javascript
 
Javascript Everywhere
Javascript EverywhereJavascript Everywhere
Javascript Everywhere
 
Keeping it small - Getting to know the Slim PHP micro framework
Keeping it small - Getting to know the Slim PHP micro frameworkKeeping it small - Getting to know the Slim PHP micro framework
Keeping it small - Getting to know the Slim PHP micro framework
 
JavaScript Closures for Dummies & JavaScript prototype, closures and OOP.
JavaScript Closures for Dummies & JavaScript prototype, closures and OOP.JavaScript Closures for Dummies & JavaScript prototype, closures and OOP.
JavaScript Closures for Dummies & JavaScript prototype, closures and OOP.
 
How to write better code: in-depth best practices for writing readable, simpl...
How to write better code: in-depth best practices for writing readable, simpl...How to write better code: in-depth best practices for writing readable, simpl...
How to write better code: in-depth best practices for writing readable, simpl...
 
How to write better code: in-depth best practices for writing readable, simpl...
How to write better code: in-depth best practices for writing readable, simpl...How to write better code: in-depth best practices for writing readable, simpl...
How to write better code: in-depth best practices for writing readable, simpl...
 
Writing JavaScript that doesn't suck
Writing JavaScript that doesn't suckWriting JavaScript that doesn't suck
Writing JavaScript that doesn't suck
 

Último

Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESmohitsingh558521
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxBkGupta21
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demoHarshalMandlekar2
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...AliaaTarek5
 
What is Artificial Intelligence?????????
What is Artificial Intelligence?????????What is Artificial Intelligence?????????
What is Artificial Intelligence?????????blackmambaettijean
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 

Último (20)

Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptx
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demo
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
 
What is Artificial Intelligence?????????
What is Artificial Intelligence?????????What is Artificial Intelligence?????????
What is Artificial Intelligence?????????
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 

Pragmatic JavaScript

  • 1. Pragmatic JavaScript John Hann / @unscriptable JavaScript Barbarian at Pivotal / cujoJS Co-lead © 2013 SpringOne 2GX. All rights reserved. Do not distribute without permission. Friday, September 13, 13
  • 2. Why are you here today? 1.dealing with things sensibly and realistically in a way that is based on practical rather than theoretical considerations Friday, September 13, 13
  • 3. Why are you here today? To learn more about JavaScript? Friday, September 13, 13
  • 4. did you get burned by JavaScript? image: gifbin.com Friday, September 13, 13
  • 5. image: gifbin.com Friday, September 13, 13 can't quite grok it?
  • 6. Let's get one thing straight JavaScript != Java Friday, September 13, 13
  • 7. JavaScript is very different JavaScript != C JavaScript != Java JavaScript != Ruby Friday, September 13, 13
  • 10. image: slapix.com Friday, September 13, 13 (this could be you)
  • 11. JavaScript is functional image: http://www.tyronestoddart.com Friday, September 13, 13
  • 12. Functions 1. an expression involving one or more variables… srsly, you had to read this? function statement: a traditional function declaration function expression: an "inline" function with or without a name 12 Friday, September 13, 13
  • 13. First-class functions function transform (x) { return x * 2; } // a function may be assigned to a variable var func = transform; // a function may have properties or be a property func.inverse = function (x) { return x / 2; }; // a function may be used as a parameter [1, 2, 3].map(func.inverse); 13 Friday, September 13, 13
  • 14. First-class functions // a function may be a return value function 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; } 14 Friday, September 13, 13
  • 15. Function scope // JavaScript implements lexical (static) scoping var a = 7; function top () { var b = 20; return inner(); function inner () { // both `a` and `b` are available here return a + b; } } top(); // returns 27 15 Friday, September 13, 13
  • 16. Function scope // JavaScript only has function scope, not block scope function silly () { var i = 20; for (var i = 0; i < 10; i++) { doSomething(i); } return i; } silly(); // returns 10, not 20! 16 Friday, September 13, 13
  • 17. EcmaScript 6 has block scope! // `let` is like `var`, but has block scope function silly () { var i = 20; for (let i = 0; i < 10; i++) { doSomething(i); } return i; } silly(); // returns 10, as you'd expect! 17 Friday, September 13, 13
  • 18. Side note: function and var hoisting // this is valid JavaScript function 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; 18 Friday, September 13, 13
  • 19. Functions as properties var 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); 19 Friday, September 13, 13
  • 20. Function context function 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! 20 Friday, September 13, 13
  • 21. Function context function legacy () { // `this` == `window` here return this.document; } function strict () { "use strict"; // `this` is undefined here return this.document; // exception! } 21 Friday, September 13, 13
  • 22. Side note: "use strict"; // strict mode helps prevent many common mistakes, // including inadvertent / implicit globals function 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 22 Friday, September 13, 13
  • 23. Function context // call a function with context and arguments myFunc.call(context /*, arg1, arg2, ... */); // another way myFunc.apply(context, arrayOfArgs); // ES5*: create a function that is hard-bound to a context myFunc.bind(context /*, arg1, arg2, ... */); // *ES5 in legacy browsers? try cujoJS/poly @ cujojs.com 23 Friday, September 13, 13
  • 24. Function context binding: a good use case // pass an object's method as a callback to a node function var 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); }); 24 Friday, September 13, 13
  • 25. Immediately-Invoked Function Expression // IIFE ("iffy"): (function () { /* ... */ }()); // these also work, but plz don't: !function () { /* ... */ }(); +function () { /* ... */ }(); // equivalent to this, but without a global var globalName = function () { /* ... */ }; globalName(); 25 Friday, September 13, 13
  • 26. 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)); 26 Friday, September 13, 13
  • 27. Example: debounce function debounce (func, msec) { var handle; return function () { var context = this, args = arguments; clearTimeout(handle); handle = setTimeout(function () { func.apply(context, args); }, msec); }; } 27 Friday, September 13, 13
  • 28. Example: Crockford-Cornford beget // add "true prototypal" inheritance to JavaScript var 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 28 Friday, September 13, 13
  • 29. s! ure los c JavaScript loves boxes image: http://toferet.wordpress.com Friday, September 13, 13
  • 30. 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 30 Friday, September 13, 13
  • 31. Closures // every function creates a closure var a = 42; // `top` closes over `a` function top () { var b = 27; // `inner` closes over `a` and `b` return function inner () { return a + b; } } // (yawn) 31 Friday, September 13, 13
  • 32. Closures: the interesting part var 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); 32 Friday, September 13, 13
  • 33. 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? 33 Friday, September 13, 13
  • 34. Closures: the bad part // one easy solution: make closures and loop data 1:1 function 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); }; }); } 34 Friday, September 13, 13
  • 35. Learn more about functional JavaScript • "Must read" book: –Effective JavaScript by David Herman 35 Friday, September 13, 13
  • 36. JavaScript is prototypal image: http://www.flickr.com/photos/doug88888 Friday, September 13, 13
  • 37. 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. 37 Friday, September 13, 13
  • 38. Prototypal inheritance • In "true" prototypal inheritance, objects inherit directly from other objects: –prototype chain: parent <-- child <-- grandchild 38 Friday, September 13, 13
  • 39. Prototypal inheritance # "true" prototypal inheritance (not javascript): child <- beget(parent); # child specialization child.baz <- function () { /* ... */ } 39 Friday, September 13, 13
  • 40. 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 chain child.baz = function () { parent.baz.apply(this, arguments); }; // *ES5 in legacy browsers? try cujoJS/poly @ cujojs.com 40 Friday, September 13, 13
  • 41. 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 41 Friday, September 13, 13
  • 42. Not-quite-prototypal inheritance // constructor-prototype pair function 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? 42 Friday, September 13, 13
  • 43. 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 43 Friday, September 13, 13
  • 44. Not-quite-prototypal inheritance // create a parent constructor-prototype pair function Parent () {} // constructor Parent.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 prototype Child.prototype.baz = function () {}; 44 Friday, September 13, 13
  • 45. 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` 45 Friday, September 13, 13
  • 46. Constructors: benefits • Accept initialization parameters • Execute initialization code • Allow us to hide implementation details 46 Friday, September 13, 13
  • 47. 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 47 Friday, September 13, 13
  • 48. 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" things Parent.prototype = { foo: 42, bar: 7 }; Parent.prototype.baz = function () {}; 48 Friday, September 13, 13
  • 49. 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); }; 49 Friday, September 13, 13
  • 50. 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 50 Friday, September 13, 13
  • 51. Constructors: pitfall // parent constructor takes an argument function 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!** 51 Friday, September 13, 13
  • 52. 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! 52 Friday, September 13, 13
  • 53. ur inheritance horks hairballs image: the internetz Friday, September 13, 13 why not surprised?
  • 54. 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 = ... */ 54 Friday, September 13, 13
  • 55. 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` 55 Friday, September 13, 13
  • 56. 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); } 56 Friday, September 13, 13
  • 57. Learn more about prototypal JavaScript • "Must read" book: –Effective JavaScript by David Herman –(no, I don't receive a commission :) ) 57 Friday, September 13, 13
  • 59. 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) 59 Friday, September 13, 13
  • 60. 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 60 Friday, September 13, 13
  • 61. 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 61 Friday, September 13, 13
  • 62. Example: xhr function 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'); } 62 Friday, September 13, 13
  • 63. Continuation passing: cons • Results are no longer returned from functions • All functions involved in async operations must pass callbacks • Messy, messy, messy 63 Friday, September 13, 13
  • 64. Example: xhr function xhrGet (url, callback, errback) { try { xhr('GET', url, callback, errback); } catch (ex) { errback(ex); } } xhrGet('/result', success, failure); 64 Friday, September 13, 13
  • 65. Example: xhr with fallback function 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); 65 Friday, September 13, 13
  • 66. Example: coordinate 2 xhr POSTs function 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); } } } 66 Friday, September 13, 13
  • 67. Example: coordinate 2 xhr POSTs w/ rollback [code redacted] 67 Friday, September 13, 13
  • 68. lookd at ur async java scripts image: the internetz Friday, September 13, 13 now i has puke in my mouth
  • 69. Is JavaScript doomed? Nah, we have a solution. The solution was invented in the 70's like everything else. Friday, September 13, 13
  • 70. JavaScript + Promises image: http://www.flickr.com/photos/aimlessbrooke/ Friday, September 13, 13
  • 71. 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 71 Friday, September 13, 13
  • 72. 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 72 Friday, September 13, 13
  • 73. 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! 73 Friday, September 13, 13
  • 74. Example: distract user while loading UI // load the specified UI package function loadAppFeature(package) { // a promise "pipeline": return showBusyIndicator() .then(curl([package])) // fetch .then(showMainView) // display .then(hideBusyIndicator); } // Notice how the value `main` is propagated function showMainView (main) { return wire(main); // returns a promise! } 74 Friday, September 13, 13
  • 75. 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(); } } 75 Friday, September 13, 13 // how it would look using // cujoJS/when: function foo (url) { var r = xhr(url); } return lift(r.send) .otherwise(logError) .ensure(cleanup);
  • 76. Example: xhr with fallback using promises // async operation with fallback using promises function 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)); 76 Friday, September 13, 13
  • 77. Learn more about Promises • Awesome tutorials on async and promises: –http://know.cujojs.com/tutorials • Spec: http://promisesaplus.com 77 Friday, September 13, 13
  • 78. JavaScript can be modular image: http://wallpapersus.com Friday, September 13, 13
  • 79. Modules: benefits • Code organization –Small files, focused tests • End reliance on globals –Reduces namespace conflicts –Reduces dependency hell • Dependency management –IDE support –Build support 79 Friday, September 13, 13
  • 80. 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 || {})); 80 Friday, September 13, 13
  • 81. 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 81 Friday, September 13, 13
  • 82. 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> 82 Friday, September 13, 13
  • 83. tried ur modyule patturrrn image: the internetz Friday, September 13, 13 it was awwful
  • 84. Formal modules for JavaScript • Asynchronous Module Definition • CommonJS Modules/1.1 • ES6 Modules 84 Friday, September 13, 13
  • 85. 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 85 Friday, September 13, 13
  • 86. AMD • Implementations –RequireJS: http://requirejs.org/ –cujoJS/curl: http://cujojs.com/ –dojo –LinkedIn's Inject.js –dozens of others 86 Friday, September 13, 13
  • 87. AMD modules define(['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; }); 87 Friday, September 13, 13
  • 88. 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. 88 Friday, September 13, 13
  • 89. 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. 89 Friday, September 13, 13
  • 90. 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 90 Friday, September 13, 13
  • 91. 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 91 Friday, September 13, 13
  • 92. CommonJS modules var 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); }; 92 Friday, September 13, 13
  • 93. CommonJS modules: node.js variant var 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); } }; 93 Friday, September 13, 13
  • 94. CommonJS modules: pitfalls // BAD: dynamic module lookup var 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; } }; 94 Friday, September 13, 13
  • 95. 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. 95 Friday, September 13, 13
  • 96. 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?.... 96 Friday, September 13, 13
  • 97. ES6 modules • Finally!!!! An official standard for JavaScript modules! • Part of EcmaScript 6 • Enforces static dependency analysis • Provides hooks for consuming AMD and CommonJS 97 Friday, September 13, 13
  • 98. ES6 modules: cons • Don't expect to use ES6 modules in production until… 2016 98 Friday, September 13, 13
  • 99. 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 99 Friday, September 13, 13
  • 100. image: slapix.com Friday, September 13, 13 Ready to go for it?
  • 101. Code docs in JavaScript? • Yep! It's called JSDoc • jsdoc-toolkit: https://code.google.com/p/jsdoc-toolkit/ • @use JSDoc: http://usejsdoc.org/ 101 Friday, September 13, 13
  • 102. AOP in JavaScript? • YES! • Possible because function context is dynamic! • See Brian Cavalier's talk this afternoon 102 Friday, September 13, 13
  • 103. IOC in JavaScript? • You bet! • cujoJS/wire http://cujojs.com 103 Friday, September 13, 13
  • 104. RESTful patterns? • You know it! • Backbone: http://backbonejs.org/ • cujoJS/rest: http://cujojs.com 104 Friday, September 13, 13
  • 105. Enterprise Messaging? • Yes, even that. • cujoJS/msgs: http://cujojs.com 105 Friday, September 13, 13
  • 106. Data modeling and data binding? • Uh huh. • Check out the next JavaScript session with Scott Andrews, Tim Branyen, and Matias Niemela 106 Friday, September 13, 13
  • 108. 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/ 108 Friday, September 13, 13