前言
新的特性,看過就忘記,有可能不經常用
你有沒有花一個下午的時間來閱讀Mozilla的文件?如果你有,你就會很清楚,網上有很多關於JavaScript的資訊。這使得人們很容易忽視一些比較生僻的JavaScript運算子。
然而,這些運算子不常見並不意味著它們不強大! 它們各自在語法上看起來很相似,但一定要讀懂每一個,因為它們的工作方式不同。
就讓我們一探究竟吧!
1. ?? 運算子在JavaScript中,??運算子被稱為nullish coalescing運算子(零合併運算子)。如果第一個引數不是null/undefined,這個運算子將返回第一個引數,否則,它將返回第二個引數。我們來看一個例子。
null?? 5// => 53?? 5// => 3
當為一個變數分配預設值時,JavaScript開發人員傳統上依賴邏輯OR運算子,比如這樣。
var prevMoney = 1var currMoney = 0var noAccount = nullvar futureMoney = -1function moneyAmount(money) {return money || `You currently do not own an account in the bank`}console.log(moneyAmount(prevMoney)) // => 1console.log(moneyAmount(currMoney)) // => `You currently do not own an account in the bank`console.log(moneyAmount(noAccount)) // => `You currently do not own an account in the bank`console.log(moneyAmount(futureMoney))// => -1
上面我們建立了一個函式moneyAmount,負責返回使用者的當前餘額。我們使用了||運算子來識別沒有賬戶的使用者。然而,當一個使用者沒有賬戶時是什麼意思呢?更準確的做法是將無賬戶視為null,而不是0,因為銀行賬戶可以存在無(或負)錢的情況。在上面的例子中,||運算子將0視為一個假 值,因此沒有登記我們的使用者有一個0美元的賬戶。讓我們透過使用nullish coalescing運算子來解決這個問題。
var currMoney = 0var noAccount = nullfunction moneyAmount(money) {return money ?? `You currently do not own an account in the bank`} moneyAmount(currMoney) // => 0 moneyAmount(noAccount) // => `You currently do not own an account in the bank`
概括地說,??運算子允許我們分配預設值,同時忽略0和空字串等錯誤值。
2. ??=運算子??=又被稱為邏輯空值賦值運算子,與我們之前學習的內容密切相關。我們來看看它們是如何聯絡在一起的。
var x = nullvar y = 5console.log(x ??= y) // => 5console.log(x = (x ?? y)) // => 5
這個賦值運算子只有在當前值為空或未定義的情況下才會賦一個新的值。上面的例子強調了這個運算子本質上是空值賦值的語法糖。接下來,讓我們看看這個運算子與預設引數有何不同。
function gameSettingsWithNullish(options) { options.gameSpeed ??= 1 options.gameDiff ??= 'easy' return options}function gameSettingsWithDefaultParams(gameSpeed=1, gameDiff='easy') {return{gameSpeed, gameDiff}}gameSettingsWithNullish({gameSpeed: null, gameDiff: null}) // => { gameSpeed: 1, gameDiff: 'easy' }gameSettingsWithDefaultParams(null, null) // => { gameSpeed: null, gameDiff: null }
上述函式在處理空值時有一個值得注意的區別。預設引數將覆蓋預設值與null引數,nullish賦值運算子不會。預設引數和nullish賦值都不會覆蓋未定義的值。在這裡閱讀更多內容。
3. ?. 運算子可選的鏈式運算子?. 允許開發人員讀取深嵌在物件鏈中的屬性值,而不必顯式驗證每個引用。當一個引用為空時,表示式停止計算並返回一個未定義的值。讓我們來看看一個例子。
var travelPlans = { destination: 'DC', monday: { location: 'National Mall', budget: 200}};const tuesdayPlans = travelPlans.tuesday?.location;console.log(tuesdayPlans) // => undefined
現在,讓我們把到目前為止學到的一切都納入到新的旅行計劃中去吧!
function addPlansWhenUndefined(plans, location, budget) {if(plans.tuesday?.location == undefined) {var newPlans = { plans, tuesday: { location: location ?? "Park", budget: budget ?? 200},};} else{ newPlans ??= plans; //will only override if newPlans is undefined console.log("Plans have already been added!");}return newPlans;}var newPlans = addPlansWhenUndefined(travelPlans, "Ford Theatre", null);console.log(newPlans) // => { plans://{ destination: 'DC',// monday: { location: 'National Mall', budget: 200 } },// tuesday: { location: 'Ford Theatre', budget: 200 } }newPlans = addPlansWhenUndefined(newPlans, null, null) // logs => Plans have already been added!// returns => newPlans object
我們現在建立了一個函式,將plans新增到一個當前沒有巢狀屬性 tuesday.location 的物件中。我們還使用了nullish運算子來提供預設值。這個函式將接受'0'這樣的虛值作為有效引數。這意味著我們的預算可以被設定為0,而不會出現任何錯誤。
4. ? 運算子三元運算子 ? : 需要三個運算元,一個條件為真時要執行的表示式,以及一個條件為假時要執行的表示式。讓我們來看看它的操作。
function checkCharge(charge) { return(charge > 0) ? 'Ready for use': 'Needs to charge' }console.log(checkCharge(20)) // => 'Ready for use'console.log(checkCharge(0)) // => 'Needs to charge'
如果你在JavaScript上花了一些時間,你可能已經看到了三元運算子。然而,你知道三元運算子可以用於變數賦值嗎?
var budget = 0var transportion = (budget > 0) ? 'Train': 'Walking' console.log(transportion) // => 'Walking'
我們甚至可以用它來複制nullish賦值的行為。
var x = 6var x = (x !== null|| x !== undefined) ? x : 3console.log(x) // => 6
現在讓我們透過建立一個函式來概括這種行為!
function nullishAssignment(x,y) {return(x == null|| x == undefined) ? y : x}var x = nullishAssignment(null, 8) // => 8var y = nullishAssignment(4,8) // => 4
在收尾之前,讓我們使用三元運算子重構前面例子中的函式。
譯者:@飄飄
原文: