Prototype Chaining Tests

JavaScript

function get_constructors(context, options) {
    context = context || {};
    options = options || {};

    var matches = {};
    var path = [];

    do {

        // We already know everything is an Object.
        if( context.constructor.name !== 'Object' ) {
            path.unshift( context.id || context.name || context.constructor.name );
        } 
        
        Object.defineProperty(matches, context.constructor.name, {
            enumerable: true,
            writable: true,
            value: {
                name: context.constructor.name,
                properties: {
                    constructor: {
                        type: typeof context.constructor,
                        properties: Object.getOwnPropertyNames(context.constructor)
                    },
                    prototype: {
                        type: typeof context.constructor.prototype,
                        properties: Object.keys(context.constructor.prototype)
                    }
                }
            }
        });

    } while (context = Object.getPrototypeOf(context));

    if (options.format === 'schema') {
        return matches || {};
    }

    if (options.delimiter) {
        return path.join( options.delimiter || '/' );;
    }

}

console.clear();

function User( name ) {

    
    // Instance Identity
    this.name = name || this.constructor.name || undefined; 
    this.model = this.constructor.name || arguments.callee.name; // The constructor has priority.

    this.settings = {};
    this.color = 'red';
    
    return this;
    
    return function() {
        console.log( 'user constructor' );
        return this;
    };
    
}

Object.defineProperties( User.prototype, {
    extend: {
        get: function() {
            console.log( 'extending', this.name );
            return function() { console.log( this ); return this; }.bind( this );
        }
    },
    channel: {
        get: function() { return get_constructors( Object.getPrototypeOf(...