function extensible(object) { // usable to extend a class function descriptors() {} // get rid of name, length, and the rest Reflect.ownKeys(descriptors).forEach(function (k) { delete descriptors[k]; }); // clean up the constructor too descriptors.prototype = {}; // per each property in object Reflect.ownKeys(object).forEach(function (k) { // grab the descriptor var d = Object.getOwnPropertyDescriptor(object, k); // if it's a Proxy trap, ignore it if (!d) return; // make it non enumerable, no matter what d.enumerable = false; // define it as prototype property Object.defineProperty(descriptors.prototype, k, d); // define it also as descriptor Object.defineProperty(descriptors, k, { enumerable: true, value: d }); }); // the exensible object is here return descriptors; } // example const greeter = extensible({ greetings() { console.log('Hello world from ' + this.name); } }); // usable to extend a class class Greeter extends greeter { constructor(name) { super(); this.name = name; } } const gClass = new Greeter('class'), // usable to enrich a created object gObject = Object.create({name: 'object'}, greeter) ; gClass.greetings(); gObject.greetings();