Skip to content

Instantly share code, notes, and snippets.

@glenjamin
Created May 31, 2011 22:14
Show Gist options
  • Save glenjamin/1001393 to your computer and use it in GitHub Desktop.
Save glenjamin/1001393 to your computer and use it in GitHub Desktop.
Demonstrating the JavaScript object model
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();
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