title: How to dynamically extend ES5 and ES6 classes
body: <p>I'm trying to build a tool library to be used on every environment. I have a transpiler so my generated code is ES5.</p>
  
  <p>The thing is my tool hooks on a class methods and injects them back in the prototype:</p>
  
  <pre><code>klass.prototype = Object.create(
    Object.getPrototypeOf(klass.prototype),
    modifiedDescriptors
  );
  </code></pre>
  
  <p>But if a ES6 class is passed we can't modify it's <code>prototype</code> because it's descriptor is <code>{configurable: false, writable: false}</code>. So I decided to fully extend the class with ES5 code and not modify the original prototype:</p>
  
  <pre><code>function ProxyCtor() { return klass.apply(this, arguments) }
  ProxyCtor.prototype = Object.create(klass.prototype, modifiedDescriptors);
  </code></pre>
  
  <p>Again this is not possible because a ES6 class constructor can't be invoked without <code>new</code>: <code>Class constructor X cannot be invoked without 'new'</code></p>
  
  <p>Ok no problem I'll drop ES5 support and my code will extend the class using ES6 classes and then I will finally be able to hook the methods:</p>
  
  <pre><code>class ProxyCtor extends klass {}
  
  Object.defineProperty(ProxyCtor, 'prototype', Object.create(
    Object.getPrototypeOf(ProxyCtor.prototype),
    modifiedDescriptors
  );
  </code></pre>
  
  <p>And this again fails because <code>ProxyCtor.prototype</code> is readonly as <code>klass.prototype</code> was.</p>
  
  <p>I could use <code>Proxy</code> for this but a requirement is to support older browsers and for optimization reasons I need the calculations to be executed on script startup and not when the method is called.</p>
  
  <p>So the question is... how can I extend a class ES6 (meaning it should have the same behaviour and <code>new ProxyCtor() instanceof klass</code> should be true) but wrap it's methods with a function?</p>