如何使用ES6类扩展函数?

ES6允许扩展特殊对象。所以可以从函数继承。这样的对象可以作为函数调用,但是如何实现这种调用的逻辑呢?


class Smth extends Function {

  constructor (x) {

    // What should be done here

    super();

  }

}


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

类的任何方法都可以通过引用类实例this。但是当它被称为函数时,this指的是window。当作为函数调用时,如何获取对类实例的引用?


慕婉清6462132
浏览 582回答 3
3回答

慕标琳琳

这是我创建可调用对象的方法,这些对象正确引用其对象成员,并保持正确的继承,而不会弄乱原型。只是:class ExFunc extends Function {  constructor() {    super('...args', 'return this.__call__(...args)');    return this.bind(this);  }  // Example `__call__` method.  __call__(a, b, c) {    return [a, b, c];  }}扩展此类并添加一个__call__方法,更多信息......代码和注释中的解释:// A Class that extends Function so we can create// objects that also behave like functions, i.e. callable objects.class ExFunc extends Function {  constructor() {    // Here we create a dynamic function with `super`,    // which calls the constructor of the parent class, `Function`.    // The dynamic function simply passes any calls onto    // an overridable object method which I named `__call__`.    // But there is a problem, the dynamic function created from    // the strings sent to `super` doesn't have any reference to `this`;    // our new object. There are in fact two `this` objects; the outer    // one being created by our class inside `constructor` and an inner    // one created by `super` for the dynamic function.    // So the reference to this in the text: `return this.__call__(...args)`    // does not refer to `this` inside `constructor`.    // So attempting:    // `obj = new ExFunc();`     // `obj();`    // Will throw an Error because __call__ doesn't exist to the dynamic function.    super('...args', 'return this.__call__(...args)');        // `bind` is the simple remedy to this reference problem.    // Because the outer `this` is also a function we can call `bind` on it    // and set a new inner `this` reference. So we bind the inner `this`    // of our dynamic function to point to the outer `this` of our object.    // Now our dynamic function can access all the members of our new object.    // So attempting:    // `obj = new Exfunc();`     // `obj();`    // Will work.    // We return the value returned by `bind`, which is our `this` callable object,    // wrapped in a transparent "exotic" function object with its `this` context    // bound to our new instance (outer `this`).    // The workings of `bind` are further explained elsewhere in this post.    return this.bind(this);  }    // An example property to demonstrate member access.  get venture() {    return 'Hank';  }    // Override this method in subclasses of ExFunc to take whatever arguments  // you want and perform whatever logic you like. It will be called whenever  // you use the obj as a function.  __call__(a, b, c) {    return [this.venture, a, b, c];  }}// A subclass of ExFunc with an overridden __call__ method.class DaFunc extends ExFunc {  get venture() {    return 'Dean';  }    __call__(ans) {    return [this.venture, ans];  }}// Create objects from ExFunc and its subclass.var callable1 = new ExFunc();var callable2 = new DaFunc();// Inheritance is correctly maintained.console.log('\nInheritance maintained:');console.log(callable2 instanceof Function);  // trueconsole.log(callable2 instanceof ExFunc);  // trueconsole.log(callable2 instanceof DaFunc);  // true// Test ExFunc and its subclass objects by calling them like functions.console.log('\nCallable objects:');console.log( callable1(1, 2, 3) );  // [ 'Hank', 1, 2, 3 ]console.log( callable2(42) );  // [ 'Dean', 42 ]进一步说明bind:function.bind()工作很像function.call(),他们共享一个类似的方法签名:fn.call(this, arg1, arg2, arg3, ...);更多关于mdnfn.bind(this, arg1, arg2, arg3, ...);更多关于mdn在第一个参数中重新定义this函数内的上下文。其他参数也可以绑定到值。但是,在call立即使用绑定值调用函数的情况下,bind返回一个“异国情调”的函数对象,该对象透明地包装原始函数,this并预设任何参数。所以当你定义一个函数时bind,它的一些参数:var foo = function(a, b) {  console.log(this);  return a * b;}foo = foo.bind(['hello'], 2);只使用其余参数调用绑定函数,其上下文是预设的,在本例中为['hello']。// We pass in arg `b` only because arg `a` is already set.foo(2);  // returns 4, logs `['hello']`

开满天机

您可以使用(也许)陷阱将Smth实例包装在Proxy中:applyconstructclass Smth extends Function {  constructor (x) {    super();    return new Proxy(this, {      apply: function(target, thisArg, argumentsList) {        return x;      }    });  }}new Smth(256)(); // 256
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript