TypeScript中变量调用时后缀感叹号和问号的区别
typescript编译时,当我们开启严格模式时,下面的代码就会报错:
function doSomething(x: string | null) {
console.log("Hello, " + x.toUpperCase());
}
编译错误:
hello.ts:56:29 - error TS2531: Object is possibly 'null'.
56 console.log("Hello, " + x.toUpperCase());
~
当我们在调用变量x的方法时,增加后缀!和?时,这个编译错误都会消失:
x!.toUpperCase()
x?.toUpperCase()
那这两者到底有什么区别呢?
那我们运行分别运行下代码就可以看出端倪:
-
后缀是?
function doSomething(x: string | null) { console.log("Hello, " + x?.toUpperCase()); } doSomething(null);
输出是:
Hello, undefined
-
后缀是!
function doSomething(x: string | null) { console.log("Hello, " + x!.toUpperCase()); } doSomething(null);
输出是:
Uncaught TypeError TypeError: Cannot read properties of null (reading 'toUpperCase')
结论:
- 后缀是!,只是告诉typescript编译器对于
null
和undefined
不做显示的检查,生成的js文件中还是x.toUpperCase()
,如果此时x为null,那么就会出现运行时异常 - 后缀是?,代表是一个空判断,只有非空是,才会执行
x.toUpperCase()
,生成的js文件中是增加了null或者undefined判断的,生成的js是(x === null || x === void 0 ? void 0 : x.toUpperCase())