Skip to content

Instantly share code, notes, and snippets.

@krisselden
Created January 4, 2019 03:14
Show Gist options
  • Save krisselden/0f497e3aacebc80ebbb9e8029e99f017 to your computer and use it in GitHub Desktop.
Save krisselden/0f497e3aacebc80ebbb9e8029e99f017 to your computer and use it in GitHub Desktop.
const bindingsMap = new WeakMap();
function bound() {
return (target, key, descriptor) => {
const { enumerable, configurable, value } = descriptor;
return {
enumerable,
configurable,
get() {
let bindings = bindingsMap.get(this);
if (bindings === undefined) {
bindings = {};
bindingsMap.set(this, bindings);
}
let fn = bindings[key];
if (fn === undefined) {
bindings[key] = fn = value.bind(this);
fn.orig = value;
}
return fn.orig === value ? fn : value;
}
}
}
}
function applyDecorator(target, key, decorator) {
let descriptor = Object.getOwnPropertyDescriptor(target, key);
Object.defineProperty(target, key, decorator()(target, key, descriptor));
}
class A {
perform(x) {
console.log(`A.perform(${x})`);
}
}
applyDecorator(A.prototype, 'perform', bound);
class B extends A {
perform(x) {
console.log(`B.perform(${x}) before`);
super.perform(x);
console.log(`B.perform(${x}) after`);
}
}
applyDecorator(B.prototype, 'perform', bound);
const a = new A();
const b = new B();
const { perform: aPerform } = a;
const { perform: bPerform } = b;
bPerform(23);
bPerform(10);
aPerform(19);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment