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...