我经常遇到类似这样的代码:
ngOnDestroy() {
this.subscriptions.forEach(subscription => subscription.unsubscribe());
}
我的问题是,如果这是,虽然在这个例子中是无害的,但这是一个不好的做法,因为这里的含义是返回值等于unsubscribe()
方法返回的任何内容。
上面的代码没有任何需要从箭头函数返回任何东西,但是那里有隐式返回,即正文被翻译成return subscription.unsubscribe()
。
将该功能编码如下是一种更好的做法吗? (注意额外的花括号):
ngOnDestroy() {
this.subscriptions.forEach(subscription => {
subscription.unsubscribe();
});
}
答案 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