Created
May 31, 2011 22:14
-
-
Save glenjamin/1001393 to your computer and use it in GitHub Desktop.
Demonstrating the JavaScript object model
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var assert = require('assert'); | |
var util = require('util'); | |
var inheritance = require('./inheritance'); | |
function Person(name) { | |
this.name = name; | |
} | |
Person.prototype.greet = function() { | |
return "Hello "+this.name; | |
} | |
util.inherits(Employee, Person); | |
function Employee(role, name) { | |
Person.call(this, name); | |
this.role = role; | |
} | |
Employee.prototype.greeting = "Welcome to work" | |
util.inherits(Retired, Employee); | |
function Retired(role, name, left) { | |
Employee.call(this, role, name); | |
this.left = left; | |
} | |
var john = new Retired("Boss", "John", new Date()); | |
console.log("john instance_of Employee"); | |
console.log(inheritance.instance_of(john, Employee)); | |
console.log(); | |
console.log("john instance_of Array"); | |
console.log(inheritance.instance_of(john, Array)); | |
console.log(); | |
console.log("new_instance(Person, 'john') instanceof Person"); | |
console.log(inheritance.new_instance(Person, 'john') instanceof Person); | |
console.log(); | |
console.log("new_instance(Employee, 'boss', 'john') instanceof Employee"); | |
console.log(inheritance.new_instance(Employee, 'boss', 'john') instanceof Employee); | |
console.log(); | |
console.log("get_attribute(john, 'role')") | |
console.log(inheritance.get_attribute(john, 'role')); | |
console.log(); | |
console.log("get_attribute(john, 'greeting')") | |
console.log(inheritance.get_attribute(john, 'greeting')); | |
console.log(); | |
console.log("call_method(john, 'greet')") | |
console.log(inheritance.call_method(john, 'greet')); | |
console.log(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
exports.extract_prototype_chain = extract_prototype_chain; | |
function extract_prototype_chain(obj) { | |
var chain = []; | |
var proto = Object.getPrototypeOf(obj); | |
while (proto) { | |
chain.push(proto); | |
proto = Object.getPrototypeOf(proto); | |
} | |
return chain; | |
} | |
// obj instanceof type <=> instance_of(obj, type) | |
exports.instance_of = instance_of; | |
function instance_of(obj, type) { | |
console.log("Trying to match %s.prototype", type.name); | |
var chain = extract_prototype_chain(obj); | |
for (var proto in chain) { | |
console.log("Comparing to %s.prototype", | |
chain[proto].constructor.name); | |
if (chain[proto] === type.prototype) { | |
return true; | |
} | |
} | |
return false; | |
} | |
// new Something(arg) <=> new_instance(Something, arg) | |
exports.new_instance = new_instance | |
function new_instance(obj /* , arguments ... */) { | |
if (typeof obj !== 'function') { | |
throw new TypeError(typeof obj +' is not a function'); | |
} | |
// This is the inverse of Object.getPrototypeOf(obj) | |
// Unlike douglas Crockford's version, it doesn't call the constructor | |
var instance = Object.create(obj.prototype); | |
// Call the constructor with this = instance | |
var args = Array.prototype.slice.call(arguments, 1); | |
obj.call(instance, args); | |
return instance; | |
} | |
// obj.property <=> obj['property'] <=> get_attribute(obj, 'property') | |
exports.get_attribute = get_attribute; | |
function get_attribute(obj, attr) { | |
console.log("Looking on object directly"); | |
if (obj.hasOwnProperty(attr)) { | |
return obj[attr]; | |
} | |
var chain = extract_prototype_chain(obj); | |
for (var proto in chain) { | |
console.log("Looking on %s.prototype", | |
chain[proto].constructor.name); | |
if (chain[proto].hasOwnProperty(attr)) { | |
return chain[proto][attr]; | |
} | |
} | |
return undefined; | |
} | |
// obj.method(arg) <=> call_method(obj, 'method', arg) | |
exports.call_method = call_method; | |
function call_method(obj, method/* , arguments ... */) { | |
var attr = get_attribute(obj, method); | |
if (!attr) { | |
throw new TypeError("Object " + Object.prototype.toString(obj) + | |
" has no method '" + method + "'"); | |
} | |
if (typeof attr !== 'function') { | |
throw new TypeError("Property '" + method + "' of object " + | |
Object.prototype.toString(obj) + | |
" is not a function"); | |
} | |
var args = Array.prototype.slice.call(arguments, 2); | |
return attr.call(obj, args); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment