Demonstrating the JavaScript object model
JavaScript
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)
function instance_of(obj, type) {
console.log("Trying to match "+type.name+".prototype");
var chain = extract_prototype_chain(obj);
for (var proto in chain) {
console.log("Comparing to "+chain[proto].constructor.name+".prototype");
if (chain[proto] === type.prototype) {
return true;
}
}
return false;
}
// new Something(arg) <=> new_instance(Something, arg)
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')
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 "+chain[proto].constructor.name+".prototype");
if (chain[proto].hasOwnProperty(attr)) {
return chain[proto][attr];
}
}
return undefined;
}
// obj.method(arg) <=> call_method(obj, 'method', arg)
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...