vixalien
vixalien

Reputation: 390

Can a Proxy detect that a subclass is adding methods to a class?

Given a class like:

class A {}

Is it possible to modify in any way so that I can proxy when methods are subclassed like so:

// proxy the `A` object in some way
const handler = {
  get(target, property) {
    console.log("getting", arguments);
    return target[property];
  },
  set(target, property, value) {
    console.log("setting", arguments);
    return target[property] = value;
  },
};

const A_proxied = new Proxy(A, handler);

I want the message setting hello (or similar) to be logged in the following case.

class B extends A_proxied {
  hello() {
    return "world";
  }
}

The above code just logs getting prototype and nothing else. Any ideas?

Upvotes: 1

Views: 129

Answers (2)

Alexander Nenashev
Alexander Nenashev

Reputation: 23602

Use the construct trap in the Proxy's handler:

// proxy the `A` object in some way
const handler = {
  construct(_, args, constructor){
    Object.getOwnPropertyNames(constructor.prototype).forEach(name => name === 'constructor' || console.log('setting', name));
    return Reflect.construct(...arguments);
  }
};

class A{}

const A_proxied = new Proxy(A, handler);

class B extends A_proxied {
  hello() {
    return "world";
  }
}

const b = new B;

Upvotes: -1

Bergi
Bergi

Reputation: 665276

Don't use a class that should be subclassed for this. Inheritance is the wrong solution to your problem, and proxies won't help either.

If you want someone to execute code when defining a class, give them a function to call:

const B = A(class {
  hello() {
    return "world";
  }
});

You can declare it as

function A(cls) {
  for (const key of Object.getOwnPropertyNames(cls.prototype)) {
    if (key == 'constructor') continue;
    console.log(`setting ${key}`);
  }
  return cls;
}

Upvotes: -1

Related Questions