4個強大JavaScript運算符

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"今天我們學習新的 JS 運算符!"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"你有沒有花一個下午的時間閱讀 Mozilla 文檔?如果有,你會發現網上有很多 JS 資料,這使我們很容易忽略那些更爲基礎的 JS 運算符。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這些運算符不常見但很強大!在語法上看起來很相似,作用卻不一樣,一定要仔細閱讀。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"1. ?? 非空運算符"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在 JS 中,?? 運算符被稱爲非空運算符。如果第一個參數不是 null\/undefined(譯者注:這裏只有兩個假值,但是 JS 中假值包含:未定義 undefined、空對象 null、數值 0、空數字 NaN、布爾 false,空字符串’’,不要搞混了),將返回第一個參數,否則返回第二個參數。比如,"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"null"},"content":[{"type":"text","text":"null ?? 5 \/\/ => 53 ?? 5 \/\/ => 3\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"給變量設置默認值時,以前常用 ||邏輯或運算符,例如,"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"null"},"content":[{"type":"text","text":"var prevMoney = 1var currMoney = 0var noAccount = nullvar futureMoney = -1function moneyAmount(money) {return money || `賬戶未開通`}console.log(moneyAmount(prevMoney)) \/\/ => 1console.log(moneyAmount(currMoney)) \/\/ => 賬戶未開通console.log(moneyAmount(noAccount)) \/\/ => 賬戶未開通console.log(moneyAmount(futureMoney)) \/\/ => -1\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"上面我們創建了函數 moneyAmount,它返回當前用戶餘額。我們使用 || 運算符來識別沒有帳戶的用戶。然而,當用戶沒有帳戶時,這意味着什麼?將無賬戶視爲空而不是 0 更爲準確,因爲銀行賬戶可能沒有(或負)貨幣。在上面的例子中,|| 運算符將 0 視爲一個虛假值,不應該包括用戶有 0 美元的帳戶。讓我們使用?? 非空運算符來解決這個問題:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"null"},"content":[{"type":"text","text":"var currMoney = 0var noAccount = nullfunction moneyAmount(money) { return money ?? `賬戶未開通`}moneyAmount(currMoney) \/\/ => 0moneyAmount(noAccount) \/\/ => `賬戶未開通`\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"概括地說 ?? 運算符允許我們在忽略錯誤值(如 0 和空字符串)的同時指定默認值。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"2. ??= 空賦值運算符"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"??= 也被稱爲空賦值運算符,與上面的非空運算符相關。看看它們之間的聯繫:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"null"}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"僅當值爲 null 或 undefined 時,此賦值運算符纔會賦值。上面的例子強調了這個運算符本質上是空賦值的語法糖(譯者注,類似的語法糖:a = a + b 可寫成 a += b )。接下來,讓我們看看這個運算符與默認參數(譯者注,默認參數是 ES6 引入的新語法,僅當函數參數爲 undefined 時,給它設置一個默認值)的區別:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"null"},"content":[{"type":"text","text":"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(undefined, null) \/\/ => {gameSpeed: null, gameDiff: null}\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"上述函數處理空值的方式有一個值得注意的區別。默認參數將用空參數(譯者注,這裏的空參數,只能是 undefined)覆蓋默認值,空賦值運算符將不會。默認參數和空賦值都不會覆蓋未定義的值。更多信息請點擊"},{"type":"link","attrs":{"href":"https:\/\/developer.mozilla.org\/zh-CN\/docs\/Web\/JavaScript\/Reference\/Operators\/Logical_nullish_assignment","title":"xxx","type":null},"content":[{"type":"text","text":"這裏"}]},{"type":"text","text":"。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"3. ?. 鏈判斷運算符"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"鏈判斷運算符?. 允許開發人員讀取深度嵌套在對象鏈中的屬性值,而不必驗證每個引用。當引用爲空時,表達式停止計算並返回 undefined。比如:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"null"},"content":[{"type":"text","text":"var travelPlans = { destination: 'DC', monday: { location: 'National Mall', budget: 200 }}console.log(travelPlans.tuesday?.location) \/\/ => undefined\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"現在,把我們剛剛學到的結合起來,把 tuesday 加入旅行計劃中!"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"null"},"content":[{"type":"text","text":"function addPlansWhenUndefined(plans, location, budget) { if (plans.tuesday?.location == undefined) { var newPlans = { plans, tuesday: { location: location ?? \"公園\", budget: budget ?? 200 }, } } else { newPlans ??= plans; \/\/ 只有 newPlans 是 undefined 時,才覆蓋 console.log(\"已安排計劃\") } return newPlans}\/\/ 譯者注,對象 travelPlans 的初始值,來自上面一個例子var newPlans = addPlansWhenUndefined(travelPlans, \"Ford 劇院\", null)console.log(newPlans)\/\/ => { plans: \/\/ { destination: 'DC',\/\/ monday: { location: '國家購物中心', budget: 200 } },\/\/ tuesday: { location: 'Ford 劇院', budget: 200 } }newPlans = addPlansWhenUndefined(newPlans, null, null)\/\/ logs => 已安排計劃\/\/ returns => newPlans object\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"上面的例子包含了我們到目前爲止所學的所有運算符。現在我們已經創建了一個函數,該函數將計劃添加到當前沒有嵌套屬性的對象 tuesday.location 中。我們還使用了非空運算符來提供默認值。此函數將錯誤地接受像“0”這樣的值作爲有效參數。這意味着 budget 可以設置爲零,沒有任何錯誤。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"4. ?: 三元運算符"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"?: 又叫條件運算符,接受三個運算數:條件 ?  條件爲真時要執行的表達式 : 條件爲假時要執行的表達式。實際效果:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"null"},"content":[{"type":"text","text":"function checkCharge(charge) { return (charge > 0) ? '可用' : '需充值' }console.log(checkCharge(20)) \/\/ => 可用console.log(checkCharge(0)) \/\/ => 需充值\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果你寫過 JS,可能見過三元運算符。但是,你知道三元運算符可以用於變量賦值嗎?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"null"},"content":[{"type":"text","text":"var budget = 0var transportion = (budget > 0) ? '火車' : '步行' console.log(transportion) \/\/ => '步行'\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們甚至可以用它來實現空賦值的行爲:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"null"},"content":[{"type":"text","text":"var x = 6var x = (x !== null || x !== undefined) ? x : 3console.log(x) \/\/ => 6\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"讓我們通過創建一個函數來概括這個運算:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"null"},"content":[{"type":"text","text":"function nullishAssignment(x,y) { return (x == null || x == undefined) ? y : x }nullishAssignment(null, 8) \/\/ => 8nullishAssignment(4, 8) \/\/ => 4\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在結束之前,讓我們使用三元運算符重構前面示例中的函數:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"null"},"content":[{"type":"text","text":"function addPlansWhenUndefined(plans, location, budget) { var newPlans = plans.tuesday?.location === undefined ? { plans, tuesday: { location: location ?? \"公園\", budget: budget ?? 200 }, } : console.log(\"已安排計劃\"); newPlans ??= plans; return newPlans;}\n"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"結論"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們現在已經學習了這些運算符的使用方法,在這裏有更多關於這些運算符的"},{"type":"link","attrs":{"href":"https:\/\/developer.mozilla.org\/zh-CN\/docs\/Web\/JavaScript\/Reference\/Operators","title":"xxx","type":null},"content":[{"type":"text","text":"知識"}]},{"type":"text","text":"。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"(譯者注:文中前三個運算符是 ES2020 的新特性,請勿直接用在生產環境, 可使用 webpack+babel 進行轉義,解決瀏覽器兼容性問題)"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"原文鏈接:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https:\/\/medium.com\/javascript-in-plain-english\/4-powerful-javascript-operators-youve-never-heard-of-487df37114ad","title":"","type":null},"content":[{"type":"text","text":"https:\/\/medium.com\/javascript-in-plain-english\/4-powerful-javascript-operators-youve-never-heard-of-487df37114ad"}]}]}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章