Object Oriented JavaScript

7,217 views
6,492 views

Published on

My talk for AJAXWorld 2009 in NYC.

Published in: Technology
3 Comments
27 Likes
Statistics
Notes
No Downloads
Views
Total views
7,217
On SlideShare
0
From Embeds
0
Number of Embeds
179
Actions
Shares
0
Downloads
292
Comments
3
Likes
27
Embeds 0
No embeds

No notes for slide

Object Oriented JavaScript

  1. Object Oriented JavaScript Mike Girouard — AJAXWorld 2009
  2. Today’s Agenda JavaScript Object Model Types, Constructors, Inheritance “Missing” Features Namespaces,Visibility, Polymorphism Useful Design Patterns Factories, Singletons, Modules Mike Girouard — AJAXWorld 2009
  3. The JavaScript Object Model Mike Girouard — AJAXWorld 2009
  4. Primitive Types Object Boolean Number String Array Date RegExp Function Math Error EvalError RangeError ReferenceError SyntaxError TypeError URIError Mike Girouard — AJAXWorld 2009
  5. 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
  6. 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
  7. 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
  8. 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
  9. 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
  10. Inheritance Mike Girouard — AJAXWorld 2009
  11. Prototypal Inheritance Completely eliminates the need for classes Objects inherit directly from other objects (prototypes) Incredibly efficient, ridiculously strange Mike Girouard — AJAXWorld 2009
  12. 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
  13. 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
  14. Classical Inheritance var Foo = classFactory({ __construct: function () { this.identify(); }, identify: function () { console.log(‘Foo’); } }); Mike Girouard — AJAXWorld 2009
  15. Classical Inheritance var Bar = Foo.extend({ identify: function () { console.log(‘Bar’); } }); Mike Girouard — AJAXWorld 2009
  16. 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
  17. “Missing” Features Mike Girouard — AJAXWorld 2009
  18. Namespaces Mike Girouard — AJAXWorld 2009
  19. 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
  20. 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
  21. Namespace Objects var mikeg = { name : ‘Mike G’, location : ‘NYC’, getName : function () { return this.name; }, getLocation : function () { return location; } }; Mike Girouard — AJAXWorld 2009
  22. 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
  23. Visibility Mike Girouard — AJAXWorld 2009
  24. 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
  25. Data Hiding in JS var Person = function (name) { this.getName = function () { return name; }; this.setName = function (newName) { return name = newName; }; }; Mike Girouard — AJAXWorld 2009
  26. 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
  27. Polymorphism Mike Girouard — AJAXWorld 2009
  28. 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
  29. 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
  30. 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
  31. Useful Design Patterns Mike Girouard — AJAXWorld 2009
  32. Factories Mike Girouard — AJAXWorld 2009
  33. 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
  34. 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
  35. 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
  36. Singletons Mike Girouard — AJAXWorld 2009
  37. 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
  38. Singletons var myHttpLibrary = { newXHR : function (params) { ... }, parseQueryString : function (qs) { ... }, createQueryString : function (qs) { ... } }; Mike Girouard — AJAXWorld 2009
  39. The Module Mike Girouard — AJAXWorld 2009
  40. A Visibility Pattern Original pattern discovered by Douglas Crockford Simplifies private data in JS Mike Girouard — AJAXWorld 2009
  41. 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
  42. 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
  43. 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
  44. Modules for Organization var module = function () { var app, util, service; app = {}; util = {}; return service = {}; }(); Mike Girouard — AJAXWorld 2009
  45. Modules for Organization var module = function () { var app, util, service; app = { init : function () { ... } }; util = {}; return service = { init : app.init }; }(); Mike Girouard — AJAXWorld 2009
  46. Any questions so far? Mike Girouard — AJAXWorld 2009
  47. 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
  48. 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
  49. 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
  50. 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
  51. 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
  52. Thank you. mikeg@lovemikeg.com

×