/* jslint indent: 2 */ var MyObject = function() { }; MyObject.prototype = Object.create(Object.prototype); MyObject.prototype.noop = function() {}; MyObject.prototype.snoop = function() { return "hello patrick"; }; var Proxy = function(originalObjects) { 'use strict'; originalObjects = Array.prototype.slice(arguments); this.chain = originalObjects; }; Proxy.prototype = {}; Proxy.prototype.send = function(message, args) { 'use strict'; args = Array.prototype.slice.call(arguments).slice(1); var exectuted = false; var result; this.chain.forEach(function(object) { if (!executed && !_.isUndefined(object[message]) && _.isFunction(object[message])) { exectuted = true; result = object[message].apply(object, args); } }); return result; }; Proxy.prototype.pantomime = function(name, fn) { var self = this; Object.defineProperty(this, name, { get: fn }); }; var myObject = new MyObject(); myObject.firstName = 'Patrick'; myObject.lastName = 'Stapleton'; var proxyToProxy = new Proxy(myObject); proxyToProxy.pantomime('fullName', function() { return this.send('firstName') + this.send('lastName'); }); proxyToProxy.fullName //==> 'Patrick Stapleton'