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