The document discusses object oriented JavaScript. It covers JavaScript types and constructors, creating custom types, using prototypes for inheritance and instance members. It also discusses namespaces, visibility, and polymorphism in JavaScript. Useful design patterns like factories, singletons, and modules are presented. The presentation provides examples and explanations of these core JavaScript concepts.
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
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
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
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
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
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
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
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
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