Advertisement
Advertisement

More Related Content

Advertisement
Advertisement

JavaScript Growing Up

  1. JavaScript Growing Up Modules, Platform Consistency and Harmony David Padbury
  2. Between HTML5 and Node, JavaScript is seeing a staggering level of adoption.
  3. 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
  4. Modules
  5. Java has import C# has using JavaScript has? Nothing.
  6. So JavaScript authors used what we had in the language to provide what we needed.
  7. But before we get to that, first some prerequisites.
  8. 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>
  9. 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>
  10. Using simple JavaScript constructs we can emulate many traditional organization techniques ;(function(lib1) { lib1.something = function() { ... }; })(window.lib1 = window.lib1 || {}); lib1.something(); lib2.something();
  11. function namespace(ns) { var obj = window; ns.split('.').forEach(function(component) { obj = typeof obj[component] !== 'undefined' ? obj[component] : obj[component] = {}; }); return obj; }
  12. (function(data) { data.something = function() { ... }; })(namespace('lab49.app.data'));
  13. (function(example) { function privateAdd(num1, num2) { return num1 + num2; } example.add = function(num1, num2) { return privateAdd(num1, num2); }; })(namespace('lab49.example')); console.log(typeof example.add); // function console.log(typeof example.privateAdd); // undefined console.log(typeof privateAdd); // undefined
  14. Server-side JavaScript authors started to talk about what a more robust module system would look like.
  15. 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)
  16. 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
  17. // 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
  18. CommonJS modules are now the de-facto for server based JavaScript.
  19. var http = require('http'); var server = http.createServer(function(req, res) { res.writeHead(200, { 'Content-Type': 'text/plain' }); res.end('Hi Lab!'); });
  20. 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
  21. 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);
  22. There are some problems with using this module format in the browser.
  23. Asynchronous Module Definition (Commonly known as AMD) https://github.com/amdjs/amdjs-api/wiki/AMD
  24. define for creating a module definition.
  25. define('personView', ['models/person'], function(person) { return { initialize: function() { ... } }; });
  26. AMD is now used by RequireJS, Dojo and even Node.
  27. RequireJS also supports text templates.
  28. Becoming the most common way to structure large JavaScript applications, both on the server and in the browser.
  29. JS.next will be introducing language level modules. These are similar to the modules we’ve been looking at.
  30. module Math { export function add(x, y) { return x + y; } } Math.add(2, 2); import Math.*; add(2,2);
  31. But not much implements that yet. Why do we care? I’ll get to that later.
  32. Platform Consistency
  33. Everyone knows that the biggest suckage in modern JavaScript is dealing with different platforms.
  34. Polyfill A shim that mimics a future API, providing fallback functionality to older browsers. http://stateofhtml5.appspot.com/
  35. You can fake a surprising amount now days.
  36. ;(function(geolocation){ if (geolocation) return; var cache; geolocation = window.navigator.geolocation = {}; geolocation.getCurrentPosition = function(callback){ if (cache) callback(cache); $.getScript('//www.google.com/jsapi',function(){ cache = { coords : { "latitude": google.loader.ClientLocation.latitude, "longitude": google.loader.ClientLocation.longitude } }; callback(cache); }); }; geolocation.watchPosition = geolocation.getCurrentPosition; })(navigator.geolocation);
  37. border-radius: 8px; box-shadow: #666 0px 2px 3px; background: linear-gradient(#eeff99, #66ee33); behavior: url(/PIE.htc); http://css3pie.com/
  38. But just because you can, it doesn’t mean that you should.
  39. But if we are in different environments, we can start with some polyfills that are much simpler.
  40. Array.prototype.forEach Array.prototype.map Array.prototype.filter Array.prototype.every Array.prototype.some Array.prototype.reduce Array.prototype.indexOf Object.keys Date.now Date.prototype.toISOString Function.prototype.bind String.prototype.trim
  41. ['one', 'two', 'three'].map(function(word) { return word.length }).filter(function(length) { return length > 3; });
  42. 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/
  43. Array.prototype.map = function() {...}; var arr = [1,2,3]; for (var p in arr) { if (arr.hasOwnProperty(p)) { console.log(p); } }
  44. So where we can polyfill basic language functionality, take advantage of it. https://github.com/kriskowal/es5-shim
  45. Harmony
  46. JavaScript is the x86 of the web - Brendan Eich (creator of JavaScript)
  47. Google Traceur - JavaScript to JavaScript Compiler http://code.google.com/p/traceur-compiler/
  48. Harmony Features Modules Iterators Iterators and For Each Generators Block Scoped Bindings Destructuring Assignment Default Parameters Rest Parameters Spread Operator Strawman Features Classes Traits Deferred Functions Object Initializer Shorthand http://code.google.com/p/traceur-compiler/wiki/LanguageFeatures
  49. Destructuring Assignment var [a, [b], c] = ['hello', [', ', 'junk'], 'world']; alert(a + b + c); // hello, world http://traceur-testbed.herokuapp.com/destructuringArrayAssignment var pt = { x: 23, y: 42 }; var {x, y} = pt; console.log(x); // 23 http://traceur-testbed.herokuapp.com/destructuringObjectAssignment
  50. function slice(list, start = 0, end = list.length) { ... } http://traceur-testbed.herokuapp.com/defaultParameters
  51. function print(...items) { items.forEach(function(item, index) { console.log(index, item); }); } print('foo', 'bar'); // 0, foo // 1, bar http://traceur-testbed.herokuapp.com/restParameters
  52. var a1 = [1,2,3], a2 = []; a2.push(...a1); // a1.push.apply(a1, a2) http://traceur-testbed.herokuapp.com/spreadOperator
  53. 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
  54. function wait(duration) { var deferred = $.Deferred(); window.setTimeout(function() { deferred.resolve(); }); return deferred.promise(); } wait(1000).then(function() { alert('done'); });
  55. 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
  56. Thanks for listening!

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
Advertisement