在不需要返回时忽略JavaScript或TypeScript中的箭头函数内隐式返回是错误的

时间:2018-05-14 20:17:32

标签: javascript typescript

我经常遇到类似这样的代码:

ngOnDestroy() {
  this.subscriptions.forEach(subscription => subscription.unsubscribe());
}

我的问题是,如果这是,虽然在这个例子中是无害的,但这是一个不好的做法,因为这里的含义是返回值等于unsubscribe()方法返回的任何内容。

上面的代码没有任何需要从箭头函数返回任何东西,但是那里有隐式返回,即正文被翻译成return subscription.unsubscribe()

将该功能编码如下是一种更好的做法吗? (注意额外的花括号):

ngOnDestroy() {
  this.subscriptions.forEach(subscription => {
    subscription.unsubscribe();
  });
}

5 个答案:

答案 0 :(得分:8)

箭头函数减少了你编写的代码,因此隐式返回有助于保存一些击键:)但是,在你的第二个例子中,即使有一个undefined的返回。所以实践并不差,它更清洁,更短。

答案 1 :(得分:2)

这是一个风格问题,但我会把无意识的隐含回归称为坏事。如果阅读代码的开发人员并不熟悉,那么键入的内容会少一些,但会对使用的API产生错误的印象。对于像forEach这样的众所周知的API,这不是一个问题。但是,如果一个函数返回一个值但忽略了它,这可能会引起混淆。

如果返回值为undefined,则隐式返回不会导致运行时问题,但是如果定义了它,则值可能会影响以这种方式调用函数的代码。 / p>

一个例子是我在使用AngularJS测试时意外跌落的陷阱。测试模块接受与生产模块具有相同签名的模块配置功能(注释为不返回值的依赖注入的函数),但在生产模块中忽略该值:

// ok
app.config((foo) => foo.barThatReturnsAValue());

在测试中,它会导致模糊的错误:

// Error: [ng:areq] Argument 'fn' is not a function, got Object    
angular.mock.module((foo) => foo.barThatReturnsAValue())

TypeScript特有的问题是类型检查通常无法检测到这些问题:

let foo = () => 1;
let bar = (foo: () => void) => {};

bar(foo); // ok

答案 2 :(得分:2)

为获得更清晰的代码和更高的可读性,您还可以使用void关键字。

例如:(请注意void之后的=>关键字)

ngOnDestroy() {
  this.subscriptions.forEach(subscription => void subscription.unsubscribe());
}

此处没有隐式return:)

答案 3 :(得分:0)

理论上,对于具有返回值的函数,遵循第二个示例将是更好的做法。

然而,在实践中,回调函数是否具有返回值通常无关紧要,因此第一个示例的清晰语法值得模糊。

编辑:正如Randy在评论中指出的那样,如果函数返回undefined,则两种方法之间没有区别。我修改了我的答案以考虑到这一点。

答案 4 :(得分:0)

您的两个示例都会生成return个结果。如果你真的不需要任何返回值。您最好使用for循环

for(var i=0; i<this.subscriptions.length; i++)
{
  this.subscription[i].unsubscribe();
}

同样for循环比forEach here

更有效