Object Oriented JavaScript
-
Upload
michael-girouard -
Category
Technology
-
view
4.727 -
download
2
description
Transcript of Object Oriented JavaScript
![Page 1: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/1.jpg)
Object Oriented JavaScriptMike Girouard — AJAXWorld 2009
![Page 2: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/2.jpg)
Mike Girouard — AJAXWorld 2009
Today’s Agenda
JavaScript Object ModelTypes, Constructors, Inheritance
“Missing” FeaturesNamespaces, Visibility, Polymorphism
Useful Design PatternsFactories, Singletons, Modules
![Page 3: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/3.jpg)
Mike Girouard — AJAXWorld 2009
The JavaScript Object Model
![Page 4: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/4.jpg)
Mike Girouard — AJAXWorld 2009
Boolean
Object
Number String Array Date
RegExp Function Math Error EvalError
RangeError ReferenceError SyntaxError TypeError URIError
Primitive Types
![Page 5: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/5.jpg)
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
![Page 6: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/6.jpg)
Mike Girouard — AJAXWorld 2009
// Define the constructorvar Timestamp = function () { this.value = new Date().getTime();};
// Instantiatevar ts = new Timestamp;
// Read instance variableconsole.log(ts.value);
Creating Custom Types
![Page 7: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/7.jpg)
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
![Page 8: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/8.jpg)
Mike Girouard — AJAXWorld 2009
var Timestamp = function () { this.value = new Date().getTime();};
Timestamp.prototype.getValue = function () { return this.value;};
var ts = new Timestamp;console.log(ts.getValue());
Instance Members
![Page 9: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/9.jpg)
Mike Girouard — AJAXWorld 2009
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
Instance Members
![Page 10: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/10.jpg)
Mike Girouard — AJAXWorld 2009
Inheritance
![Page 11: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/11.jpg)
Mike Girouard — AJAXWorld 2009
Prototypal Inheritance
Completely eliminates the need for classes
Objects inherit directly from other objects (prototypes)
Incredibly efficient, ridiculously strange
![Page 12: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/12.jpg)
Mike Girouard — AJAXWorld 2009
var Foo = function () {}; // Foo Constructorvar Bar = function () {}; // Bar ConstructorBar.prototype = new Foo; // Bar extends Foo
var f = new Foo(); // Foo instancevar b = new Bar(); // Bar instance
console.log(f instanceof Foo); // trueconsole.log(f instanceof Bar); // falseconsole.log(b instanceof Foo); // trueconsole.log(b instanceof Bar); // true
Prototypal Inheritance
![Page 13: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/13.jpg)
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
![Page 14: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/14.jpg)
Mike Girouard — AJAXWorld 2009
var Foo = classFactory({ __construct: function () { this.identify(); },
identify: function () { console.log(‘Foo’); }});
Classical Inheritance
![Page 15: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/15.jpg)
Mike Girouard — AJAXWorld 2009
var Bar = Foo.extend({ identify: function () { console.log(‘Bar’); }});
Classical Inheritance
![Page 16: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/16.jpg)
Mike Girouard — AJAXWorld 2009
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;};
Classical Inheritance
![Page 17: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/17.jpg)
Mike Girouard — AJAXWorld 2009
“Missing” Features
![Page 18: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/18.jpg)
Mike Girouard — AJAXWorld 2009
Namespaces
![Page 19: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/19.jpg)
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…
![Page 20: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/20.jpg)
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
![Page 21: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/21.jpg)
Mike Girouard — AJAXWorld 2009
var mikeg = { name : ‘Mike G’, location : ‘NYC’,
getName : function () { return this.name; }, getLocation : function () { return location; }};
Namespace Objects
![Page 22: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/22.jpg)
Mike Girouard — AJAXWorld 2009
var getXHR = function () { if (!getXHR.enabled) return null; var xhr = new XMLHttpRequest; getXHR.registry.push(xhr);
return xhr;};
getXHR.registry = [];getXHR.enabled = true;
Namespace Functions
![Page 23: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/23.jpg)
Mike Girouard — AJAXWorld 2009
Visibility
![Page 24: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/24.jpg)
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
![Page 25: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/25.jpg)
Mike Girouard — AJAXWorld 2009
var Person = function (name) { this.getName = function () { return name; };
this.setName = function (newName) { return name = newName; };};
Data Hiding in JS
![Page 26: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/26.jpg)
Mike Girouard — AJAXWorld 2009
// Assume: Person
var mike = new Person(‘Mike G.’);var alex = new Person(‘Alex H.’);
console.log(mike.name); // undefinedconsole.log(alex.name); // undefined
console.log(mike.getName()); // Mike G.console.log(alex.getName()); // Alex H.
Data Hiding in JS
![Page 27: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/27.jpg)
Mike Girouard — AJAXWorld 2009
Polymorphism
![Page 28: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/28.jpg)
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
![Page 29: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/29.jpg)
Mike Girouard — AJAXWorld 2009
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
Loadtime Branching
![Page 30: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/30.jpg)
Mike Girouard — AJAXWorld 2009
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;};
Runtime Replacement
![Page 31: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/31.jpg)
Mike Girouard — AJAXWorld 2009
Useful Design Patterns
![Page 32: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/32.jpg)
Mike Girouard — AJAXWorld 2009
Factories
![Page 33: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/33.jpg)
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
![Page 34: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/34.jpg)
Mike Girouard — AJAXWorld 2009
var DocumentCreator = function (document) { // What does ‘this’ refer to? this.document = document;};
new DocumentCreator(‘foo.txt’); // InstanceDocumentCreator(‘foo.txt’); // window
Brittle Constructor
![Page 35: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/35.jpg)
Mike Girouard — AJAXWorld 2009
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’); // InstanceDocumentCreator(‘foo.txt’); // Instance
A Simple Factory
![Page 36: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/36.jpg)
Mike Girouard — AJAXWorld 2009
Singletons
![Page 37: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/37.jpg)
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
![Page 38: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/38.jpg)
Mike Girouard — AJAXWorld 2009
var myHttpLibrary = { newXHR : function (params) { ... }, parseQueryString : function (qs) { ... }, createQueryString : function (qs) { ... }};
Singletons
![Page 39: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/39.jpg)
Mike Girouard — AJAXWorld 2009
The Module
![Page 40: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/40.jpg)
Mike Girouard — AJAXWorld 2009
A Visibility Pattern
Original pattern discovered by Douglas Crockford
Simplifies private data in JS
![Page 41: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/41.jpg)
Mike Girouard — AJAXWorld 2009
var config = function () { var data = {}; return { get : function (name) { return data[name]; }, set : function (name, value) { data[name] = value; return this.get(name); } };}();
A Simple Module
![Page 42: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/42.jpg)
Mike Girouard — AJAXWorld 2009
// Assume: config
config.set(‘name’, ‘Mike G.’);
console.log(config.data.name); // undefinedconsole.log(config.get(‘name’)); // Mike G.
A Simple Module
![Page 43: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/43.jpg)
Mike Girouard — AJAXWorld 2009
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); } };}();
A Better Module
![Page 44: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/44.jpg)
Mike Girouard — AJAXWorld 2009
var module = function () { var app, util, service;
app = {};
util = {};
return service = {};}();
Modules for Organization
![Page 45: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/45.jpg)
Mike Girouard — AJAXWorld 2009
var module = function () { var app, util, service;
app = { init : function () { ... } };
util = {};
return service = { init : app.init };}();
Modules for Organization
![Page 46: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/46.jpg)
Mike Girouard — AJAXWorld 2009
Any questions so far?
![Page 47: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/47.jpg)
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
![Page 48: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/48.jpg)
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
![Page 49: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/49.jpg)
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
![Page 50: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/50.jpg)
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
![Page 51: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/51.jpg)
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
![Page 52: Object Oriented JavaScript](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f985fb4c9057b298b45da/html5/thumbnails/52.jpg)
Thank [email protected]