How to extend Function with ES6 classes?

2019-01-02 17:46发布

ES6 allows to extend special objects. So it's possible to inherit from the function. Such object can be called as a function, but how can I implement the logic for such call?

class Smth extends Function {
  constructor (x) {
    // What should be done here
    super();
  }
}

(new Smth(256))() // to get 256 at this call?

Any method of class gets reference to the class instance via this. But when it is called as a function, this refers to window. How can I get the reference to the class instance when it is called as a function?

PS: Same question in Russian.

8条回答
余生无你
2楼-- · 2019-01-02 18:20

You can wrap the Smth instance in a Proxy with an apply (and maybe construct) trap:

class Smth extends Function {
  constructor (x) {
    super();
    return new Proxy(this, {
      apply: function(target, thisArg, argumentsList) {
        return x;
      }
    });
  }
}
new Smth(256)(); // 256
查看更多
零度萤火
3楼-- · 2019-01-02 18:22

I took the advice from Bergi's answer and wrapped it into an NPM module.

var CallableInstance = require('callable-instance');

class ExampleClass extends CallableInstance {
  constructor() {
    // CallableInstance accepts the name of the property to use as the callable
    // method.
    super('instanceMethod');
  }

  instanceMethod() {
    console.log("instanceMethod called!");
  }
}

var test = new ExampleClass();
// Invoke the method normally
test.instanceMethod();
// Call the instance itself, redirects to instanceMethod
test();
// The instance is actually a closure bound to itself and can be used like a
// normal function.
test.apply(null, [ 1, 2, 3 ]);
查看更多
登录 后发表回答