4個強大JavaScript運算符

2021-02-14 編程技術圈

你有沒有花一個下午的時間閱讀 Mozilla 文檔?如果有,你會發現網上有很多 JS 資料,這使我們很容易忽略那些更為基礎的 JS 運算符。

這些運算符不常見但很強大!在語法上看起來很相似,作用卻不一樣,一定要仔細閱讀。

在 JS 中,?? 運算符被稱為非空運算符。如果第一個參數不是 null/undefined(譯者註:這裡只有兩個假值,但是 JS 中假值包含:未定義 undefined、空對象 null、數值 0、空數字 NaN、布爾 false,空字符串'',不要搞混了),將返回第一個參數,否則返回第二個參數。比如,

null ?? 5 // => 5
3 ?? 5 // => 3

給變量設置默認值時,以前常用 ||邏輯或運算符,例如,

var prevMoney = 1
var currMoney = 0
var noAccount = null
var futureMoney = -1
function moneyAmount(money) {
return money || `帳戶未開通`
}
console.log(moneyAmount(prevMoney)) // => 1
console.log(moneyAmount(currMoney)) // => 帳戶未開通
console.log(moneyAmount(noAccount)) // => 帳戶未開通
console.log(moneyAmount(futureMoney)) // => -1

上面我們創建了函數 moneyAmount,它返回當前用戶餘額。我們使用 || 運算符來識別沒有帳戶的用戶。然而,當用戶沒有帳戶時,這意味著什麼?將無帳戶視為空而不是 0 更為準確,因為銀行帳戶可能沒有(或負)貨幣。在上面的例子中,|| 運算符將 0 視為一個虛假值,不應該包括用戶有 0 美元的帳戶。讓我們使用?? 非空運算符來解決這個問題:

var currMoney = 0
var noAccount = null
function moneyAmount(money) {
  return money ?? `帳戶未開通`
}
moneyAmount(currMoney) // => 0
moneyAmount(noAccount) // => `帳戶未開通`

概括地說 ?? 運算符允許我們在忽略錯誤值(如 0 和空字符串)的同時指定默認值。

??= 也被稱為空賦值運算符,與上面的非空運算符相關。看看它們之間的聯繫:

var x = null
var y = 5
console.log(x ??= y) // => 5
console.log(x = (x ?? y)) // => 5

僅當值為 null 或 undefined 時,此賦值運算符才會賦值。上面的例子強調了這個運算符本質上是空賦值的語法糖(譯者注,類似的語法糖:a = a + b 可寫成 a += b )。接下來,讓我們看看這個運算符與默認參數(譯者注,默認參數是 ES6 引入的新語法,僅當函數參數為 undefined 時,給它設置一個默認值)的區別:

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}

上述函數處理空值的方式有一個值得注意的區別。默認參數將用空參數(譯者注,這裡的空參數,只能是 undefined)覆蓋默認值,空賦值運算符將不會。默認參數和空賦值都不會覆蓋未定義的值。更多:

在公眾號頂級架構師後臺回復「架構整潔」,獲取一份驚喜禮包。

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Logical_nullish_assignment

鏈判斷運算符?. 允許開發人員讀取深度嵌套在對象鏈中的屬性值,而不必驗證每個引用。當引用為空時,表達式停止計算並返回 undefined。比如:

var travelPlans = {
  destination: 'DC',
  monday: {
    location: 'National Mall',
    budget: 200
  }
}
console.log(travelPlans.tuesday?.location) // => undefined

現在,把我們剛剛學到的結合起來,把 tuesday 加入旅行計劃中!

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

上面的例子包含了我們到目前為止所學的所有運算符。現在我們已經創建了一個函數,該函數將計劃添加到當前沒有嵌套屬性的對象 tuesday.location 中。我們還使用了非空運算符來提供默認值。此函數將錯誤地接受像「0」這樣的值作為有效參數。這意味著 budget 可以設置為零,沒有任何錯誤。

?: 又叫條件運算符,接受三個運算數:條件 ?  條件為真時要執行的表達式 : 條件為假時要執行的表達式。實際效果:

function checkCharge(charge) {
  return (charge > 0) ? '可用' : '需充值' 
}
console.log(checkCharge(20)) // => 可用
console.log(checkCharge(0)) // => 需充值

如果你寫過 JS,可能見過三元運算符。但是,你知道三元運算符可以用於變量賦值嗎?

var budget = 0
var transportion = (budget > 0) ? '火車' : '步行' 
console.log(transportion) // => '步行'

var x = 6
var x = (x !== null || x !== undefined) ? x : 3
console.log(x) // => 6

function nullishAssignment(x,y) {
  return (x == null || x == undefined) ? y : x 
}
nullishAssignment(null, 8) // => 8
nullishAssignment(4, 8) // => 4

在結束之前,讓我們使用三元運算符重構前面示例中的函數:

function addPlansWhenUndefined(plans, location, budget) {
 var newPlans =
   plans.tuesday?.location === undefined
     ? {
         plans,
         tuesday: {
           location: location ?? "公園", 
           budget: budget ?? 200
         },
       }
     : console.log("已安排計劃");
 newPlans ??= plans;
 return newPlans;
}

我們現在已經學習了這些運算符的使用方法,在這裡有更多關於這些運算符的知識。

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators

(譯者註:文中前三個運算符是 ES2020 的新特性,請勿直接用在生產環境, 可使用 webpack+babel 進行轉義,解決瀏覽器兼容性問題)

PS:歡迎在留言區留下你的觀點,一起討論提高。如果今天的文章讓你有新的啟發,歡迎轉發分享給更多人。

版權申明:內容來源網絡,版權歸原創者所有。除非無法確認,我們都會標明作者及出處,如有侵權煩請告知,我們會立即刪除並表示歉意。謝謝!

相關焦點

  • 七天學會javascript第一天javascript介紹
    javascript介紹javascript數據類型javascript運算符javascript對象javascriptjavascript :客戶端編程。javascript是由客戶端去解釋運行的。怎麼引入javascript 呢?
  • 9 個極其強大的 JavaScript 技巧
    下面列舉一些非常強大的 JavaScript hack 技巧。 1. Replace All 我們知道 string.Replace() 函數只會替換第一個項目。 你可以在這個正則表達式的末尾添加 /g 來替換所有內容。
  • 2.7.4 JavaScript邏輯運算符的使用
    邏輯運算符就是用於對一個或多個布爾值進行邏輯運算。在JavaScript中的邏輯運算符有&&(邏輯與)、||(邏輯或)、!(邏輯非)。1.與運算符:&&語法格式:a && b //當a和b都為真時,結果為真,否則為假如,(7>4)&&(3>2) //結果為true(7>4)&&(3<2) //結果為false
  • JavaScript運算符:== VS.
    其實在JavaScript中還有一個另外一個運算符===。那麼這兩者有何不一樣呢?這篇文章就一起來看看JavaScript中==和===有何不同。關係表達式==和===都是JavaScript中的關係表達式運算符,與對應的還有!=和!==。==和===運算符主要用於比較兩個值是否相等。當然它們對相等的定義不盡相同。
  • 20個常用的JavaScript簡寫技巧
    讓我們一個個來看看 JavaScript 的簡寫技巧吧。 1. 聲明變量 2. 給多個變量賦值 我們可以使用數組解構來在一行中給多個變量賦值。 3. 三元運算符 我們可以使用三元(條件)運算符在這裡節省 5 行代碼。
  • javascript流程語句
    3.結構化程序是由若干個基本結構組合而成,每一個結構可以包含若干條語句和其它基本結構。共有三種基本結構:順序、分支、循環順序:從上朝下執行的代碼就是順序選擇:根據不同的情況,執行對應代碼循環:重複做一件事情順序結構 順序結構是最簡單的程序結構,它是由若干個依次執行的處理步驟組成的。
  • Javascript之運算符
    二、位操作符位操作符的使用在日常工作中使用的很少,但是為了理解他們,我們需要學習計算機底層的一些知識,那就會是非常枯燥的,如果有興趣可以去閱讀MDN關於位運算符的相關文章,我在這裡只簡單地將其列出。:按位與 ( & )、按位或 ( | )、按位異或 ( ^ )、按位非 ( ~ )、左移 ( << )、右移 ( >> )、無符號右移 ( >>> );三、運算符的優先級在數學中規定要先計算乘除再計算加減,在js中我們也規定了自己的法則,我們稱之為運算符的優先級。
  • 9個極其強大的JavaScript技巧
    1.提取唯一值我們可以使用 Set 對象和 Spread 運算符,創建一個剔除重複值的新數組。將數字轉換為字符串我們只需使用帶空引號的串聯運算符即可。將字符串轉換為數字用 + 運算符即可。請注意這裡的用法,因為它只適用於「字符串數字」。
  • javascript語言的六大運算符功能,你掌握了多少?
    今天小編要給大家分享的是JS的運算符與及運用,那麼問題來了,什麼是JS運算符呢?這裡所說的運算符,是指用來對數據進行加、喊、乘、除等運算,JS常見的運算符主要有:一:算術運算符:對數字類型進行+、-、*、/的算術運算,如下圖:例:打開谷歌瀏覽器的開發者工具,找到控制臺,控制臺的功能非常強大,可以當作一個計算器使用,如我們輸入上圖以上數字和運算符,分別按下回車,其結果如下:
  • 2.7.1 JavaScript算術運算符的使用
    算術運算符是定義數學運算的符號,通常在數學表達式中使用,實現數值類型操作數間的數學計算。JavaScript中常用的算術運算符有+(相加)、-(相減)、*(相乘)、/(相除)、%(求餘)、++(自增)、--(自減)等。1.相加運算符:+如,7+4 //結果為112.
  • JavaScript中逗號運算符,鮮為人知的秘密
    這些表達式也含有其他運算符、變量和函數。逗號運算符有何作用它可按順序連接兩個表達式,先從左到右估算所有運算數,然後返回最後一個運算數的值。需要注意的是,逗號運算符不同於數組、對象、函數參數中的逗號。答案是一些運算符以及大多數的函數都會有副作用。舉個例子,varr = (console.log(1),console.log(2),console.log(3),4);可以看到1,2,3顯示在控制面板上,4賦值給變量varr。
  • 第一篇:JavaScript基本語法
    <script>標籤的type屬性表示腳本語言是javascript。<script>標籤可放置在HTML 頁面的<body>或者<head>標籤內。(4)JavaScript是跨平臺的腳本語言JavaScript代碼的執行依賴於瀏覽器,與瀏覽器所在系統環境無關,只要計算機能運行瀏覽器,並且瀏覽器支持JavaScript代碼,就可正確執行。
  • JavaScript
    Attribute屬性(通過Element進行操作)1.3.4 Text文本1.3.5 總結1.4 事件1.4.1 基本概念1.4.2 常用的事件1.4.3 事件的綁定2 js高級2.1 面向對象2.1.1 類的定義2.1.2 字面量類的定義(常用)
  • JavaScript最新提議:新的邏輯賦值運算符
    邏輯賦值運算符提議(https://github.com/tc39/proposal-logical-assignment)引入以下複合賦值運算符:a ||= ba &&= ba ??= b現有複合賦值運算符JavaScript已經有以下複合賦值運算符:算術賦值運算符:+= -= *= /= %= **=
  • 每日一課 | JavaScript基礎
    (因為面向對象需要具有封裝、繼承、多態的特徵)JavaScript語言中包含三個核心:ECMAScript基本語法、DOM、BOM 11. 使用<script></script>標籤: 2    屬性: 3    charset(可選)字符集設置、 4    defer(可選執行順序)值:defer、 5    language(已廢除)、 6    src(可選)使用外部的js腳本文件 7    type(必選)類型:值:text/javascript 8
  • 程式設計師必須掌握的 12 個 JavaScript 技能!
    本文論述的12個概念,對於 JavaScript 開發者來說都是非常重要的。本文將與大家分享 12 個實用的 JavaScript 技能,未來我也將在 Github 的 JS Tips&Tidbits 倉庫(https://github.com/nas5w/javascript-tips-and-tidbits)中持續更新此概念列表。
  • 12 個非常有用的 JavaScript 技巧
    作者: Caio Ribeiro Pereira轉載自:W3CPlus http://www.w3cplus.com/javascript/12-extremely-useful-hacks-for-javascript.html 譯者: 大漠在這篇文章中將給大家分享12個有關於JavaScript的小技巧。
  • 什麼是javascript?javascript需要學哪些內容?這篇文章告訴你!
    4.1.4 遺漏聲明4.1.5 顯示聲明與隱式聲明區別JS中變量聲明分顯式聲明和隱式聲明。剩餘可以是任意字母,美元符號,下劃線和數字(3)不能使用javascript中的關鍵字(保留字)來命名變量(4)中文也可以聲明變量,不建議使用它。
  • 一文讀懂 JavaScript 和 Python 九大語義區別
    前幾天我一直在研究算法和數據結構,因為對於程式設計師而言,最重要能力的就是解決問題,所有任何程式設計師都應該擁有強大的解決問題的基礎能力。兩天前我開始學習Python,開始對這門語言有了更多的理解。我開始將其與JavaScript進行比較,因為JavaScript是我日常工作中使用的語言。JavaScript和Python是兩門非常重要的語言。
  • Javascript之if條件語句和三目運算符
    二、三目運算符語法:條件語句 ? 執行語句1 : 執行語句2;說明:(1)、先設定一個條件,寫在問號的前面,然後兩個執行語句緊跟問號書寫,中間使用冒號隔開。(3)、三目運算符可以作為if條件語句的簡化版使用,合理的使用能夠簡化我們的代碼量,雖然可以多個三目運算符進行嵌套,但是不建議那樣使用,個人感覺那樣代碼閱讀率較差,不利於後期維護。