简体   繁体   中英

How to dynamically extend ES5 and ES6 classes

I'm trying to build a tool library to be used on every environment. I have a transpiler so my generated code is ES5.

The thing is my tool hooks on a class methods and injects them back in the prototype:

klass.prototype = Object.create(
  Object.getPrototypeOf(klass.prototype),
  modifiedDescriptors
);

But if a ES6 class is passed we can't modify it's prototype because it's descriptor is {configurable: false, writable: false} . So I decided to fully extend the class with ES5 code and not modify the original prototype:

function ProxyCtor() { return klass.apply(this, arguments) }
ProxyCtor.prototype = Object.create(klass.prototype, modifiedDescriptors);

Again this is not possible because a ES6 class constructor can't be invoked without new : Class constructor X cannot be invoked without 'new'

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:

class ProxyCtor extends klass {}

Object.defineProperty(ProxyCtor, 'prototype', Object.create(
  Object.getPrototypeOf(ProxyCtor.prototype),
  modifiedDescriptors
);

And this again fails because ProxyCtor.prototype is readonly as klass.prototype was.

I could use Proxy 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.

So the question is... how can I extend a class ES6 (meaning it should have the same behaviour and new ProxyCtor() instanceof klass should be true) but wrap it's methods with a function?

Your usage of Object.create to overwrite the .prototype with a new object could as easily be

Object.defineProperties(klass.prototype, modifiedDescriptors)

that keeps the object the same but changes its properties.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM