General-Purpose Javascript Libraries
Total Page:16
File Type:pdf, Size:1020Kb
General-Purpose Javascript Libraries Steve Gardiner 16 April, 2013 A brief history of Javascript 1995 Brendan Eich hired by Netscape to implement "Mocha" ("Scheme in the Browser") in 10 days Upon reconsideration, they deliver the first version of LiveScript Renamed JavaScript by marketing to evoke Java (the cool language of the day) and Script-ing (i.e. amateurs could do it) 1996 Microsoft implements JScript, a copy of the Mozilla implementation which is completely faithful, down to the bugs 1998 ECMAscript 1.0 Characteristics of Javascript simple syntax, not unfamiliar to C/C++/java developers loose typing linguistically productive literal syntax (i.e. JSON) runs in the context of a response to an HTTP request Smalltalk Self Java Hypercard Scheme Prototypal First-class Functions; Syntax Events inheritance Closures Javascript Javascript as an Enduser language Web designers can and do write Javascript (often badly) and they copy it from one another So introducing libraries can improve the quality of code on the web but only if users adopt them ECMAScript is a standard, but anyone in the world can write and release a Javascript library Hypothesis The more used Javascript libraries will tend to exhibit qualities preferred by end users. Role of Javascript Libraries App Browser(s) Programming Javascript directly to the browser exposes many "low-level" concerns Cross-browser concerns Bandwidth concerns Lack of language features Role of Javascript Libraries App Browser(s) Lib Intermediary between code and the interpreter Akin to the role of the compiler in compiled languages (Some systems, e.g. Dart, do allow programmers to use a higher-level language and compile to JS) Large libraries must be downloaded before the application can use them High-Level Goals of Javascript Libraries Fix Javascript Fix the DOM including cross-browser issues with the DOM Fix HTML e.g. provide a richer set of widgets Fix HTTP i.e. support asynchronous loading of content Introduce best practices without re-training developers Some Examples of Javascript Libraries Class Poll WorldWide Usage 0 jQuery 0 MooTools 0 Prototype 0 YUI 0 None (wrote web-app w/o using a JS lib.) 0 Other Fix Javascript Problem: no support for classes (violates closeness of mapping heuristic for OO programmers) Solution in prototype // properties are directly passed to `create` method var Person = Class.create({ initialize: function(name) { this.name = name; }, say: function(message) { return this.name + ': ' + message; } }); // when subclassing, specify the class you want to inherit from var Pirate = Class.create(Person, { say: function($super, message) { return $super(message) + ', yarr!'; } }); var john = new Pirate('Long John'); john.say('ahoy matey'); // -> "Long John: ahoy matey, yarr!" Fix Javascript Problem: no include statement (forces programmers to address a hard mental operation, getting minimal dependency order right, and properly addressing bandwidth concerns) Instead, programmers reference script URLs in HTML, possibly impacting page performance Solution in YUI YUI().use('node', function(Y) { Y.one('#demo').setHTML("Whoa."); }); Fix the DOM Problem: browser DOM implementations are inconsistent (forces programmers to address a hard mental operation of writing cross-browser code) For example, in older versions of IE, event listeners are added with attachEvent rather than the ECMAscript standard addEventListener if (el.addEventListener) { el.addEventListener('click', modifyText, false); } else if (el.attachEvent) { el.attachEvent('onclick', modifyText); } Solution in jQuery -- new API that internally calls the appropriate native methods $(el).on("click", modifyText); Fix the DOM Problem: DOM provides rudimentary query operations (forces programmers to address a hard mental operation of decomposing a query into multiple steps) getElementById getElementsByTagName getElementsByClassName firstChild previousSibling nextSibling parentNode childNodes Solution in jQuery -- selectors follow CSS syntax (XPath also partially supported) $("#firstName"); $(".label"); $("#contents ul.people li"); Fix the DOM Problem: DOM provides rudimentary support for creating XML (e.g. for serialization) (forces programmers to address a hard mental operation of constructing documents in multiple steps) As with document querying, DOM supplies mehtods that create nodes of the tree one at a time Solution in prototype -- use JSON instead of XML var data = {name: 'Violet', occupation: 'character', age: 25 }; Object.toJSON(data); //-> '{"name": "Violet", "occupation": "character", "age": 25}' JSON support is native in JS 1.8.1+ modern browsers Fix the DOM Problem: DOM is not consistent with CSS CSS is declarative: the following rule applies to all li currently in the page, as well as any added subsequently li { color: red } Some naive JS developers expect that the following jQuery code works similarly $("li").on("click", function(event) { ... }); But in fact the jQuery code only (imperatively) adds event handlers to currently extant li elements. Initial jQuery solution: $("li").live("click", function(event) { ... }); jQuery 1.7+ solution: $(document).on("click", "li", function(event) { ... }); Fix HTML Problem: HTML provides only a small number of document- centric widgets (forces programmers to address a hard mental operation, getting the widgets right) Programmers must build richer widgets for themselves Solution in jQuery (UI) jQuery code Nunc tincidunt Proin dolor $(#tabs).tabs(); Fix HTTP Problem: We often want to update the page without re-loading all content through another HTTP request XMLHttpRequest is available in modern browsers, but it is difficult to use Solution from jQuery var jqxhr = $.get("example.php", function() { alert("success"); }); jqxhr.done(function() { alert("second success"); }); jqxhr.fail(function() { alert("error"); }); jqxhr.always(function() { alert("finished"); }); Try it Enforce Best Practices Problem: most (JS) programmers are bad programmers (forces programmers to address a hard mental operation, i.e. programming!) For example, the tabs on the previous slide are automatically enhanced with ARIA accessibility information, and thus work better with accessible browsers than a hand-coded variant <div id="tabs" class="ui-tabs ui-widget ui-widget-content ui-corner-all"> <ul class="ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" role="tablist"> <li class="ui-state-default ui-corner-top ui-tabs-active ui-state-active" role="tab" tabindex="0" aria-controls="tabs-0" aria-labelledby="ui-id-1" aria-selected="true"><a href="#tabs-0" class="ui-tabs-anchor" role="presentation" tabindex="-1" id="ui-id-1">jQuery code</a></li> ... How libraries describe themselves jQuery MooTools fast, small, feature-rich compact Simplifies HTML document traversal and modular manipulation Object-Oriented Simplifies event handling and animation for intermediate to advanced JS developer Simplifies AJAX enables powerful, flexible, cross-browser across a multitude of browsers code versatile and extensible Elegant, well documented, coherent API Source: http://jquery.com/ Source: http://mootools.net/ Prototype YUI Introducing classes and inheritance Fast (lightweight core with modular Adding functionality to the DOM architecture) Ajax Complete (intuitive and well-documented JSON API) Event delegation Industrial Strength, with a thriving Measuring elements' dimensions and offsets community Source: http://prototypejs.org/learn/ Free & Open Source: http://yuilibrary.com/ Conclusions 66 64 62 jQuery 60 58 Why would you choose a JS library? 56 54 52 50 48 46 0 Team Familiarity / Previous 44 42 40 38 Mar 12 May 12 Jul 12 Sep 12 Nov 12 Jan 13 Mar 13 Implementation 4.2 4 3.8 MooTools 3.6 3.4 3.2 3 0 Cross Browser Compatibility 2.8 2.6 2.4 2.2 2 1.8 1.6 Mar 12 May 12 Jul 12 Sep 12 Nov 12 Jan 13 Mar 13 0 Modularity 3.4 3.3 3.2 prototype 3.1 3 2.9 2.8 2.7 2.6 2.5 2.4 2.3 2.2 0 Extensibility / Presence of Extensions 2.1 Mar 12 May 12 Jul 12 Sep 12 Nov 12 Jan 13 Mar 13 4.8 4.6 4.4 YUI 4.2 Improved API / Architecture 4 0 3.8 3.6 3.4 3.2 3 2.8 2.6 2.4 2.2 Feb 12Mar 12Apr 12May 12Jun 12 Jul 12Aug 12Sep 12Oct 12Nov 12Dec 12Jan 13Feb 13Mar 13Apr 13 0 Richer / Prettier Widgets 0 Other Fix Javascript Problem: no support for private variables Solution in JS, prototype (not solved directly AFAIK) // properties are directly passed to `create` method var Person = Class.create((function() { var name; // bound in the closure return { initialize: function(name1) { name = name1; }, say: function(message) { return name + ': ' + message; } }}())); // when subclassing, specify the class you want to inherit from var Pirate = Class.create(Person, { say: function($super, message) { return $super(message) + ', yarr!'; } }); var john = new Pirate('Long John'); john.say('ahoy matey'); // -> "Long John: ahoy matey, yarr!" (violates closeness of mapping heuristic, also maybe hard mental operation).