Optional Chaining 解決的問題是重復且無意義的判空,之所以說無意義,是對業務來說它不是必需的,但不判空,程序直接就掛了,比如:
let x = foo.bar.baz();
這里的訪問鏈路上 foo bar baz 任何一個為 undefined,程序就停止工作。
使用 Optional Chaining 修改后:
let x = foo?.bar.baz();
這里 ?. 的句法就是 Optional Chaining,在 TypeScript 3.7 中實現,目前 tc39 提案中處於 Stage 4 階段。
Optional Chaining 在這里表示,如果 foo 是 null 或 undefined,整個語句不繼續往后執行,直接返回 undefined。
作用范圍
需要注意的是,這里只對 foo 進行了保障,如果后續的 bar,baz 為空的話,代碼仍然報錯。?. 只作用於左邊的對象。
所以可以這樣來修正:
let x = foo?.bar?.baz();
這樣可以保障 foo bar 為空的情況下不報錯。這體現了 optional property accesses 的功能。
Opptoinal call
對於方法也同樣適用。
async function makeRequest(url: string, log?: (msg: string) => void) {
log?.(`Request started at ${new Date().toISOString()}`);
// roughly equivalent to
// if (log != null) {
// log(`Request started at ${new Date().toISOString()}`);
// }
const result = (await fetch(url)).json();
log?.(`Request finished at at ${new Date().toISOString()}`);
return result;
}
Optional element access
數組也是對象,只不是特殊的對象,通過數字索引作為屬性來訪問。所以 Optional Chaining 也可作用於數組元素的訪問,此時就體現了 optional element access 的功能,請看來自官方文檔中的示例:
/**
* Get the first element of the array if we have an array.
* Otherwise return undefined.
*/
function tryGetFirstElement<T>(arr?: T[]) {
return arr?.[0];
// equivalent to
// return (arr === null || arr === undefined) ?
// undefined :
// arr[0];
}
和 && 的差別
雖說 Optional Chaining 取代了如下通過 && 來實現的判空操作:
// Before
if (foo && foo.bar && foo.bar.baz) {
// ...
}
但 Optional Chaining 和 && 還是有區別,后者利用 JavaScript 中的短路機制,遇到假值時中斷執行。而前者只會在被判定對象為 null 或 undefined 時才會中斷執行。
請看如下示例:
const a: any = 0;
console.log(a?.blah);
console.log(a && a.blah);
const b: any = false;
console.log(b?.blah);
console.log(b && b.blah);
const c: any = "";
console.log(c?.blah);
console.log(c && c.blah);
輸出:
undefined
0
undefined
false
undefined
可以看到,通過 Optional Chaining 控制的部分全部輸出 undefined,因為這里被判定對象並不是 null 或 undefined,所以語句會往后執行,嘗試訪問 blah,拿到的值是 undefined,最后輸出。
而通過 && 進行判定的語句,因為被判定對象是假值,中斷執行並返回當前對象。
Nullish Coalescing
Nullish Coalescing 通過 ?? 操作符,為 null 或 undefined 的值提供默認值。
比如:
let x = foo ?? bar();
上面的表達式等價於如果 foo 是 null 或 undefined,則調用 bar()。
同樣地,他取代了之前通過 || 操作符達到的默認值效果,但后者同樣是通過判斷布爾真值達到的,而 Nullish Coalescing 只判斷 null 或 undefined。
比如:
function initializeAudio() {
let volume = localStorage.volume || 0.5;
// ...
}
這里如果 localStorage.volume 被設置成 0,則最后 volume 得到的是 0.5,也就是說設置在 localStorage.volume 永遠也不會生效。而 Nullish Coalescing 就可以避免這種問題。
相關資源
The text was updated successfully, but these errors were encountered:
