原文:fettblog.eu/void-in-jav…
译文:涂鸦码龙
如果写过强类型语言,会比较熟悉 void 的概念:调用函数和方法的时候,什么也不返回。
JavaScript 中的 void 是操作符,TypeScript 中的 void 是基本类型。void 在两个环境中的表现有所不同。
JavaScript 中的 void
JavaScript 中的 void 是操作符,可以执行表达式。不关心表达式执行结果,void 总是返回 undefined
let i = void 2; // i === undefined
那为什么需要它呢?首先,早期我们可以覆盖 undefined,给出确切的值。void 总是返回真正的 undefined。
其次,它是调用立即执行函数的好法子:
void function() {
console.log('What')
}()
不会污染全局命名空间:
void function aRecursion(i) {
if(i > 0) {
console.log(i--)
aRecursion(i)
}
}(3)
console.log(typeof aRecursion) // undefined
由于 void 总是返回 undefined,void 总会执行紧随其后的表达式,有一个很便利的方法可以做到,函数没有返回任何值,但是仍然调用了 callback:
// 返回其它值,app 会崩溃
function middleware(nextCallback) {
if(conditionApplies()) {
return void nextCallback();
}
}
对我而言,void 最重要的作用是 app 的保安闸。既然函数默认返回 undefined,我们也可以明确地定义它。
button.onclick = () => void doSomething();
TypeScript 中的 void
TypeScript 中的 void 是 undefined 的子类型。JavaScript 中的函数总会返回一个值,或者 undefined。
function iHaveNoReturnValue(i) {
console.log(i)
} // 返回 undefined
没有返回值的函数总是返回 undefined,JavaScript 中的 void 总是返回 undefined,TypeScript 中的 void 是个合适的类型,表明函数返回 undefined:
declare function iHaveNoReturnValue(i: number): void
void 可以用于参数或者其他的声明,只有 undefined 可以传:
declare function iTakeNoParameters(x: void): void
iTakeNoParameters() // 👍
iTakeNoParameters(undefined) // 👍
iTakeNoParameters(void 2) // 👍
所以 void 和 undefined 几乎一样。有一点点不同的是:void 作为返回类型,可以用不同的类型替代,允许高级回调模式:
function doSomething(callback: () => void) {
let c = callback() // 此处,callback 总是返回 undefined
// c 也是 undefiend 类型
}
// 函数返回 number 类型
function aNumberCallback(): number {
return 2;
}
// 👍 类型安全在 doSometing 中得到保证
doSomething(aNumberCallback)
这种期望的行为常用于 JavaScript 应用。可置换性的模式可以阅读我的其他文章。
如果想确保传入的函数只返回 undefined,需要修改 callback 的类型定义:
- function doSomething(callback: () => void) {
+ function doSomething(callback: () => undefined) { /* ... */ }
function aNumberCallback(): number { return 2; }
// 💥 类型不匹配
doSomething(aNumberCallback)