Between HTML5 and Node, JavaScript
is seeing a staggering level of adoption.
The patterns and tools and practices that will form
the foundation of Modern JavaScript are going to
have to come from outside implementations of the
language itself
- Rebecca Murphey
Everything is global
// lib1.js
var name = 'Barry';
function sayHi() {
alert("Hi, I'm " + name);
}
<script src="lib1.js"></script>
<script>
something();
console.log(name); // Barry
</script>
Which could make including multiple libraries challenging
// lib1.js
function something() {
console.log('foo');
}
// lib2.js
function something() {
console.log('bar');
}
<script src="lib1.js"></script>
<script src="lib2.js"></script>
<script>
something();
</script>
Using simple JavaScript constructs we can emulate many
traditional organization techniques
;(function(lib1) {
lib1.something = function() {
...
};
})(window.lib1 = window.lib1 || {});
lib1.something();
lib2.something();
I generally support the CommonJS idea, but let’s
be clear: it’s hardly a specification handed down by
the gods (like ES5); it’s just some people discussing
ideas on a mailing list. Most of these ideas are
without actual implementations.
- Ryan Dahl (creator of node.js)
Introduced a simple API for dealing with modules.
require for importing a module.
exports for exposing stuff from a module.
http://wiki.commonjs.org/wiki/Modules/1.1.1
// math.js
exports.add = function() {
var sum = 0, i = 0, args = arguments, l = args.length;
while (i < l) {
sum += args[i++];
}
return sum;
};
//increment.js
var add = require('math').add;
exports.increment = function(val) {
return add(val, 1);
};
// program.js
var inc = require('increment').increment;
var a = 1;
inc(a); // 2
var http = require('http');
var server = http.createServer(function(req, res) {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hi Lab!');
});
There are now a number of tools to bring
CommonJS modules to the browser.
https://github.com/substack/node-browserify
https://github.com/sstephenson/stitch
var stitch = require('stitch');
var express = require('express');
var package = stitch.createPackage({
paths: [__dirname + '/lib', __dirname + '/vendor']
});
var app = express.createServer();
app.get('/application.js', package.createServer());
app.listen(3000);
There are some problems with using this
module format in the browser.
It is not seldom that you see people messing with
Object.prototype.This is very bad because it breaks the
object-as-hash-tables feature in javascript.
Array.prototype.map = function() {...};
var arr = [1,2,3];
for (var p in arr) {
console.log(p);
}
// 1
// 2
// 3
// map - erm, what?
http://www.nczonline.net/blog/2010/03/02/maintainable-javascript-dont-modify-objects-you-down-own/
Deferred / Promises
var deferred = $.Deferred();
// or dojo.Deferred, new Deferred(), etc...
// Complete the deferred
deferred.resolve(...args);
// Fail the deferred
deferred.reject(...args);
// Return a read-only deferred
deferred.promise();
// Attach handlers for when resolve or rejected
deferred.then(function(...args) { ... }, function(...args) {...});
http://wiki.commonjs.org/wiki/Promises
function wait(duration) {
var deferred = $.Deferred();
window.setTimeout(function() {
deferred.resolve();
});
return deferred.promise();
}
wait(1000).then(function() {
alert('done');
});
function deferredWait(timeout) {
var d = $.Deferred();
window.setTimeout(function() {
d.resolve();
}, timeout);
return d;
}
function waitOnThings() {
alert('Starting');
await deferredWait(1000);
alert('Finished');
}
http://traceur-testbed.herokuapp.com/await