Primitive Types Object Boolean Number
String Array Date RegExp Function Math Error EvalError RangeError ReferenceError SyntaxError TypeError URIError Mike Girouard — AJAXWorld 2009
Creating Custom Types Object constructors
are functions Defining a new type is as simple as defining a function Creating a new instance is simply invoking a function with the new prefix Mike Girouard — AJAXWorld 2009
Creating Custom Types // Define
the constructor var Timestamp = function () { this.value = new Date().getTime(); }; // Instantiate var ts = new Timestamp; // Read instance variable console.log(ts.value); Mike Girouard — AJAXWorld 2009
Instance Members Instance members are
defined in a constructor’s prototype object New instances will have access to prototype members Prototypes may be modified at runtime Mike Girouard — AJAXWorld 2009
Instance Members var Timestamp =
function () { this.value = new Date().getTime(); }; Timestamp.prototype.getValue = function () { return this.value; }; var ts = new Timestamp; console.log(ts.getValue()); Mike Girouard — AJAXWorld 2009
Instance Members var Timestamp =
function () { this.value = new Date().getTime(); }; var ts = new Timestamp; Timestamp.prototype.getValue = function () { return this.value; }; console.log(ts.getValue()); // Still works Mike Girouard — AJAXWorld 2009
Prototypal Inheritance Completely eliminates the
need for classes Objects inherit directly from other objects (prototypes) Incredibly efficient, ridiculously strange Mike Girouard — AJAXWorld 2009
Prototypal Inheritance var Foo =
function () {}; // Foo Constructor var Bar = function () {}; // Bar Constructor Bar.prototype = new Foo; // Bar extends Foo var f = new Foo(); // Foo instance var b = new Bar(); // Bar instance console.log(f instanceof Foo); // true console.log(f instanceof Bar); // false console.log(b instanceof Foo); // true console.log(b instanceof Bar); // true Mike Girouard — AJAXWorld 2009
Classical Inheritance JavaScript has no
native support for classical inheritance Many libraries support class-like structures Rolling your own is quite trivial Mike Girouard — AJAXWorld 2009
Classical Inheritance var Foo =
classFactory({ __construct: function () { this.identify(); }, identify: function () { console.log(‘Foo’); } }); Mike Girouard — AJAXWorld 2009
Classical Inheritance var Bar =
Foo.extend({ identify: function () { console.log(‘Bar’); } }); Mike Girouard — AJAXWorld 2009
Classical Inheritance var classFactory =
function (obj, extends) { if (extends) for (var i in extends) if (!obj[i]) obj[i] = extends[i]; if (obj.__construct) obj.__construct.call(obj); obj.extend = function (subclass) { return classFactory(subclass, obj); }; return obj; }; Mike Girouard — AJAXWorld 2009
Why bother? JavaScript has implied
global scope Global variables are only for selfish people Raise your hand if you use these variable names: id, element, name, value, target… Mike Girouard — AJAXWorld 2009
Implementing namespaces Use an object…
any object Remember: Objects can store any kind of value Everything is an object This means anything [mutable] can be a namespace Mike Girouard — AJAXWorld 2009
Namespace Objects var mikeg =
{ name : ‘Mike G’, location : ‘NYC’, getName : function () { return this.name; }, getLocation : function () { return location; } }; Mike Girouard — AJAXWorld 2009
Namespace Functions var getXHR =
function () { if (!getXHR.enabled) return null; var xhr = new XMLHttpRequest; getXHR.registry.push(xhr); return xhr; }; getXHR.registry = []; getXHR.enabled = true; Mike Girouard — AJAXWorld 2009
Data Hiding in JS There
is no concept of public, private, or protected in JavaScript Closures allow values to be remembered in a function, even after it terminates Mike Girouard — AJAXWorld 2009
Data Hiding in JS var
Person = function (name) { this.getName = function () { return name; }; this.setName = function (newName) { return name = newName; }; }; Mike Girouard — AJAXWorld 2009
Data Hiding in JS //
Assume: Person var mike = new Person(‘Mike G.’); var alex = new Person(‘Alex H.’); console.log(mike.name); // undefined console.log(alex.name); // undefined console.log(mike.getName()); // Mike G. console.log(alex.getName()); // Alex H. Mike Girouard — AJAXWorld 2009
Easier than you think… Because
JavaScript is a dynamic language, polymorphism is quite easy and very common. Two common types of polymorphism: 1. Runtime Replacement 2. Loadtime Branching Mike Girouard — AJAXWorld 2009
Loadtime Branching var getXHR =
function () { if (window.XMLHttpRequest) { return function () { // Return a standard XHR instance }; } else { return function () { // Return an Explorer XHR instance }; } }(); // Note: parens trigger self-invocation Mike Girouard — AJAXWorld 2009
Runtime Replacement var documentListFactory =
function () { var out = []; // Just a simple array // Override the default .push() method out.push = function (document) { Array.prototype.push.call(out, { document : document, timespamp : new Date().getTime() }); }; return out; }; Mike Girouard — AJAXWorld 2009
You Need Factories Forgetting the
new keyword will break your application. The issue comes down to the implied global scope Using new, context = the instance Forgetting new, context = window Mike Girouard — AJAXWorld 2009
Brittle Constructor var DocumentCreator =
function (document) { // What does ‘this’ refer to? this.document = document; }; new DocumentCreator(‘foo.txt’); // Instance DocumentCreator(‘foo.txt’); // window Mike Girouard — AJAXWorld 2009
A Simple Factory var DocumentCreator
= function (document) { // Yes, constructors can have return values :) return DocumentCreator.factory(document); }; DocumentCreator.factory = function (document) { return new DocumentCreator(document); }; new DocumentCreator(‘foo.txt’); // Instance DocumentCreator(‘foo.txt’); // Instance Mike Girouard — AJAXWorld 2009
Singletons are Easy Too Nothing
more than a simple object literal Objects are always passed by reference and values are static Very useful for grouping items together, even if they exist in other objects Mike Girouard — AJAXWorld 2009
Singletons var myHttpLibrary = {
newXHR : function (params) { ... }, parseQueryString : function (qs) { ... }, createQueryString : function (qs) { ... } }; Mike Girouard — AJAXWorld 2009
A Simple Module var config
= function () { var data = {}; return { get : function (name) { return data[name]; }, set : function (name, value) { data[name] = value; return this.get(name); } }; }(); Mike Girouard — AJAXWorld 2009
A Simple Module // Assume:
config config.set(‘name’, ‘Mike G.’); console.log(config.data.name); // undefined console.log(config.get(‘name’)); // Mike G. Mike Girouard — AJAXWorld 2009
A Better Module var config
= function () { var me, data = {}; return me = { get : function (name) { return data[name] }, set : function (name, value) { data[name] = value; return me.get(name); } }; }(); Mike Girouard — AJAXWorld 2009
Modules for Organization var module
= function () { var app, util, service; app = {}; util = {}; return service = {}; }(); Mike Girouard — AJAXWorld 2009
Modules for Organization var module
= function () { var app, util, service; app = { init : function () { ... } }; util = {}; return service = { init : app.init }; }(); Mike Girouard — AJAXWorld 2009
Miscellaneous… Everything in JavaScript is
an object All objects can be enumerated via for…in The for…in construct sees all the way up the prototype chain myObject.hasOwnProperty(‘foo’) is gross but necessary Mike Girouard — AJAXWorld 2009
Miscellaneous… Most primitives have literals
Primitive constructors aren’t called in literals (IE: no prototype features added) Please don’t go modifying primitive prototypes Mike Girouard — AJAXWorld 2009
Miscellaneous… Forgetting to use the
new keyword in some cases will break your app. The typeof operator is useful, but lies The instanceof operator is more accurate Mike Girouard — AJAXWorld 2009
Miscellaneous… The use of this
tempting, but introduces ambiguity into your program In most cases its not necessary and can be avoided Mike Girouard — AJAXWorld 2009
Miscellaneous… Most of JavaScript’s OO
features are clever functional programming patterns Studying functional programming languages will make you a better JavaScript programmer Mike Girouard — AJAXWorld 2009
Clipping is a handy way to collect and organize the most important slides from a presentation. You can keep your great finds in clipboards organized around topics.