<strike id="3tkic"><sup id="3tkic"></sup></strike>

  1. <ul id="3tkic"></ul>
      <b id="3tkic"><legend id="3tkic"></legend></b>
      <b id="3tkic"><meter id="3tkic"></meter></b>

    • <strike id="3tkic"></strike>

      <blockquote id="3tkic"></blockquote>

    • 亚洲AV无码国产在丝袜线观看_亚洲第一页A∨在线_亚洲国产人成在线观看69网站_无码日韩人妻AV一区免费l

      ES2020 系列:空值合并運(yùn)算符 '??'

      2020/10/27 10:04:30   閱讀:2401    發(fā)布者:2401

      空值合并運(yùn)算符 '??'

      在本文中,我們將值既不是null 也不是undefined 的表達(dá)式稱(chēng)為已定義的(defined。

      空值合并運(yùn)算符(nullish coalescing operator)的寫(xiě)法為兩個(gè)問(wèn)號(hào)??。

      a ?? b 的結(jié)果是:

      • 如果a 是已定義的,則結(jié)果為a,
      • 如果a 不是已定義的,則結(jié)果為b。

      換句話說(shuō),如果第一個(gè)參數(shù)不是null/undefined,則?? 返回第一個(gè)參數(shù)。否則,返回第二個(gè)參數(shù)。

      空值合并運(yùn)算符并不是什么全新的東西。它只是一種獲得兩者中的第一個(gè)已定義的值的不錯(cuò)的語(yǔ)法。

      我們可以使用我們已知的運(yùn)算符重寫(xiě)result = a ?? b,像這樣:

      result = (a !== null && a !== undefined) ? a : b;

      通常?? 的使用場(chǎng)景是,為可能是未定義的變量提供一個(gè)默認(rèn)值。

      例如,在這里,如果user 是未定義的,我們則顯示Anonymous

      let user;
      alert(user ?? "Anonymous"); // Anonymous

      當(dāng)然,如果user 的值為除null/undefined 外的任意值,那么我們看到的將是它:

      let user = "John";
      alert(user ?? "Anonymous"); // John

      我們還可以使用?? 序列從一系列的值中選擇出第一個(gè)非null/undefined 的值。

      假設(shè)我們?cè)谧兞?span>firstName、lastName nickName 中存儲(chǔ)著一個(gè)用戶(hù)的數(shù)據(jù)。如果用戶(hù)決定不輸入值,則所有這些變量的值都可能是未定義的。

      我們想使用這些變量之一顯示用戶(hù)名,如果這些變量的值都是未定義的,則顯示 "Anonymous"

      讓我們使用?? 運(yùn)算符來(lái)實(shí)現(xiàn)這一需求:

      let firstName = null;
      let lastName = null;
      let nickName = "Supercoder";
      // 顯示第一個(gè)已定義的值
      alert(firstName ?? lastName ?? nickName ?? "Anonymous"); // Supercoder

      || 比較

      或運(yùn)算符|| 可以以與?? 運(yùn)算符相同的方式使用。

      例如,在上面的代碼中,我們可以用|| 替換掉??,也可以獲得相同的結(jié)果:

      let firstName = null;
      let lastName = null;
      let nickName = "Supercoder";
      // 顯示第一個(gè)真值:
      alert(firstName || lastName || nickName || "Anonymous"); // Supercoder

      || 運(yùn)算符自 JavaScript 誕生就存在,因此開(kāi)發(fā)者長(zhǎng)期將其用于這種目的。

      另一方面,空值合并運(yùn)算符?? 是最近才被添加到 JavaScript 中的,它的出現(xiàn)是因?yàn)槿藗儗?duì)|| 不太滿(mǎn)意。

      它們之間重要的區(qū)別是:

      • || 返回第一個(gè) 值。
      • ?? 返回第一個(gè) 已定義的 值。

      換句話說(shuō),|| 無(wú)法區(qū)分false、0、空字符串"" null/undefined。它們都一樣 —— 假值(falsy values)。如果其中任何一個(gè)是|| 的第一個(gè)參數(shù),那么我們將得到第二個(gè)參數(shù)作為結(jié)果。

      不過(guò)在實(shí)際中,我們可能只想在變量的值為null/undefined 時(shí)使用默認(rèn)值。也就是說(shuō),當(dāng)該值確實(shí)未知或未被設(shè)置時(shí)。

      例如,考慮下面這種情況:

      let height = 0;
      alert(height || 100); // 100
      alert(height ?? 100); // 0
      • height || 100 首先會(huì)檢查height 是否為一個(gè)假值,發(fā)現(xiàn)它確實(shí)是。
        • 所以,結(jié)果為第二個(gè)參數(shù),100。
      • height ?? 100 首先會(huì)檢查height 是否為null/undefined,發(fā)現(xiàn)它不是。
        • 所以,結(jié)果為height 的原始值,0。

      如果高度0 為有效值,則不應(yīng)將其替換為默認(rèn)值,所以?? 能夠得出正確的結(jié)果。

      優(yōu)先級(jí)

      ?? 運(yùn)算符的優(yōu)先級(jí)相當(dāng)?shù)停涸?MDN table 中為5。因此,?? = ? 之前計(jì)算,但在大多數(shù)其他運(yùn)算符(例如,+ *)之后計(jì)算。

      因此,如果我們需要在還有其他運(yùn)算符的表達(dá)式中使用?? 進(jìn)行取值,需要考慮加括號(hào):

      let height = null;
      let width = null;
      // 重要:使用括號(hào)
      let area = (height ?? 100) * (width ?? 50);
      alert(area); // 5000

      否則,如果我們省略了括號(hào),則由于* 的優(yōu)先級(jí)比?? 高,它會(huì)先執(zhí)行,進(jìn)而導(dǎo)致錯(cuò)誤的結(jié)果。

      // 沒(méi)有括號(hào)
      let area = height ?? 100 * width ?? 50;
      // ……與下面這行代碼的計(jì)算方式相同(應(yīng)該不是我們所期望的):
      let area = height ?? (100 * width) ?? 50;

      ?? 與&& 或|| 一起使用

      出于安全原因,JavaScript 禁止將?? 運(yùn)算符與&& || 運(yùn)算符一起使用,除非使用括號(hào)明確指定了優(yōu)先級(jí)。

      下面的代碼會(huì)觸發(fā)一個(gè)語(yǔ)法錯(cuò)誤:

      let x = 1 && 2 ?? 3; // Syntax error

      這個(gè)限制無(wú)疑是值得商榷的,但它被添加到語(yǔ)言規(guī)范中是為了避免人們從|| 切換到?? 時(shí)的編程錯(cuò)誤。

      可以明確地使用括號(hào)來(lái)解決這個(gè)問(wèn)題:

      let x = (1 && 2) ?? 3; // 正常工作了
      alert(x); // 2

      鏈接:https://juejin.im/post/6884019851942166536

      亚洲AV无码国产在丝袜线观看_亚洲第一页A∨在线_亚洲国产人成在线观看69网站_无码日韩人妻AV一区免费l
      <strike id="3tkic"><sup id="3tkic"></sup></strike>

      1. <ul id="3tkic"></ul>
          <b id="3tkic"><legend id="3tkic"></legend></b>
          <b id="3tkic"><meter id="3tkic"></meter></b>

        • <strike id="3tkic"></strike>

          <blockquote id="3tkic"></blockquote>

        • 泰安市| 合阳县| 山丹县| 邹城市| 连云港市| 溧水县| 田林县| 灌云县| 高密市| 黔江区| 南皮县| 清水河县| 绥化市| 缙云县| 通州区| 黎城县| 绥化市| 邵东县| 六安市| 亚东县| 安阳市| 灵宝市| 无为县| 九台市| 冀州市| 伊川县| 页游| 云龙县| 孟津县| 新余市| 凤翔县| 高平市| 邵阳县| 彭山县| 舒兰市| 察隅县| 盐池县| 乌拉特前旗| 栾川县| 威信县| 新宾|