外部功能与类方法的内联绑定



假设我有一个函数返回这样的函数:

function createGreeter(logger) {
  return function greet(greeting) {
    logger.log(greeting + ', ' + this.name);
  }
}

和一个类

class Person {
  constructor(name) {this.name = name;}
}

如果我想为使用控制台作为记录器的Person类分配一个问候方法,我可以想到几种方法:

1.
class Person {
  constructor(name) {this.name = name;}
  greet(greeting) {
    return createGreeter(console).call(this, greeting);
  }
}
2.
class Person {
  constructor(name) {this.name = name;}
}
Person.prototype.greet = createGreeter(console);

但是,我认为这两个都有些丑陋。1)创建一个简单地绑定this并调用功能的不必要的包装器方法,以及2)在我看来会使类API较不清楚的班级主体外部修改原型。

是否没有更清晰/较短的语法来对外部功能与类方法的外部函数结合。我在想:

class Person {
  constructor(name) {this.name = name;}
  greet: createGreeter(console)
}

...类似于您如何在对象中分配一个函数。但这显然不起作用。有类似的东西(现在还是即将到来)?

另外,我想知道返回闭合的内存消耗和/或性能方面,如1)如果返回的功能很大。每当在Person对象上调用招呼方法时,即使我们始终希望将相同的参数(console)传递给它,也会创建一个新功能对象。因此,另一种方法可能是在类别定义之前声明const consoleGreeter = createGreeter(console)并将其实现为return consoleGreeter.call(this, greeting),但是值得吗?

class Person {
  constructor(name) {this.name = name;}
}
Person.prototype.greet = createGreeter(console);

是做到这一点的正确方法,除非还有其他问题(在打字稿中会出现问题)。

这也可以使用班级字段来完成,这是第三阶段提案,可能会降落在ES2018:

class Person {
  greet = createGreeter(console);
}

这是

的快捷方式
class Person {
  constructor() {
    this.greet = createGreeter(console);
  }
}

第一个摘要一次评估createGreeter(console),然后将方法分配给类原型。第二片片段每次实例化并将方法分配给类实例时都会对其进行评估。

好的,所以这是bind外部方法的替代品 class

class Person {
  constructor(name) {this.name = name;}
  get greet() { return createGreeter(console) }
}

刚刚检查,this也工作正常。

这将达到相同的效果#1,因为每次访问方法时都会调用包装器。如果您可以提高可读性...

function createGreeter(logger) {
  return function greet(greeting) {
    logger.log(`${greeting}, ${this.name}`);
  };
}
class Person {
  constructor(name) {
    this.name = name;
  }
  get greet() {
    return createGreeter(console);
  }
}
let person = new Person('Patrick');
person.greet('Hello');

最新更新