<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          JavaScript小姿勢:為什么命名參數(shù)比位置參數(shù)更好

          共 4086字,需瀏覽 9分鐘

           ·

          2020-11-19 06:42


          來源:https://blog.bitsrc.io/

          1.什么是位置參數(shù)?

          你一定很熟悉位置參數(shù),即使你第一次聽到這個名字。

          function greet(firstName, lastName) {
          console.log(`Hello ${firstName} ${lastName}`);
          }

          // 預期用法

          greet('Michael', 'Scott');

          const fName = 'Harry';
          const lName = 'Potter';
          greet(fName, lName);


          // 錯誤用法

          const firstName = 'Erlich';
          const lastName = 'Bachman';
          greet(lastName, firstName);

          greet函數(shù)接受兩個參數(shù):firstName和lastName。調用者必須確保firstName是第一個參數(shù),lastName是第二個參數(shù)。這里重要的一點是,參數(shù)的名稱沒有任何意義,唯一重要的是參數(shù)傳遞的順序

          這種熟悉的方法稱為位置參數(shù)。通常,在你傳遞一個或兩個參數(shù)的情況下,這很好,因為它很難弄亂參數(shù)的順序。但是如果你必須調用一個需要6個參數(shù)的函數(shù),那就很難記住傳遞參數(shù)的順序。你不希望傳遞密碼來代替用戶名參數(shù)。

          2.位置參數(shù)問題

          位置參數(shù)很簡單,但是你將面臨一些挑戰(zhàn)。

          2.1 不能跳過中間參數(shù)

          假設你已經更改了greet函數(shù),使其現(xiàn)在需要3個參數(shù):firstName、middleName和lastName。由于許多人沒有中間名,因此你希望將MiddleName設為可選參數(shù),僅使用firstName和lastName調用greet函數(shù)的唯一方法是此方法。

          greet('Aditya', null, 'Agarwal');
          // Correct ?

          greet('Aditya', 'Agarwal');
          // Incorrect ?

          你不能只提供firstName和lastName。當可選參數(shù)的數(shù)量增加到5個時,這個問題變得更加明顯。現(xiàn)在,你必須提供5個null才能在這些參數(shù)之后提供參數(shù)。

          2.2 將類型添加到位置參數(shù)不那么干凈

          如今,為你的實用程序添加類型變得非常普遍。使用位置參數(shù),你別無選擇,只能將類型與函數(shù)定義一起內聯(lián)。這可能會使代碼有點模糊,如果我們可以在一個塊中聲明所有參數(shù)的類型定義,那就更好了。

          2.3 引起細微的錯誤

          位置參數(shù)包裝了很多隱性行為,這可能是造成微妙bug的原因。我們來看一個常見的JS技巧問題

          const numbers = ['1', '4', '8', '10'];
          console.log(numbers.map(parseInt));

          // 你可能會認為結果將是:
          [1, 4, 8, 10]

          // 這是實際的輸出:
          [ 1, NaN, NaN, 3 ]

          驚訝嗎?這種奇怪的輸出的原因隱藏在位置參數(shù)的隱性背后。你會看到map和parseInt函數(shù)在顯而易見的情況下隱藏了它們的一些秘密。

          讓我們再次查看代碼 number.map(parseInt)

          這里到底發(fā)生了什么?

          • 我們在numbers數(shù)組上運行map函數(shù)。
          • map獲取數(shù)組的第一項并將其傳遞給parseInt。
          • 現(xiàn)在,對于數(shù)組中的第一項(即1),它將執(zhí)行 parseInt(1)。對...?錯誤?。?!

          實際上,map將三個參數(shù)傳遞給其回調函數(shù)。第一個是數(shù)組中的當前項目,第二個是項目的索引,第三個是整個數(shù)組。這本身沒有問題,但真正的問題在于后一部分。

          numbers.map(parseInt)numbers.map((item) => parseInt(item)) 不同。你可以假設,由于回調函數(shù)僅接受item參數(shù)并將其傳遞給parseInt,因此我們可以跳過附加步驟。但是兩者是不同的:在前者中,我們將所有數(shù)據從map傳遞到parseInt,而在后者中,我們僅傳遞項。

          你可能不知道,但是parseInt的第二個參數(shù)稱為基數(shù)。默認情況下,基數(shù)的值為10(以10為底,因為人類遵循十進制進行計數(shù))。該代碼出了問題,就是我們將當前項目的索引作為基數(shù)值傳遞給parseInt。這些是發(fā)生的實際函數(shù)調用:

          parseInt('1', 0, [...]);
          parseInt('4', 1, [...]);
          parseInt('8', 2, [...]);
          parseInt('10', 3, [...]);

          現(xiàn)在我們知道了問題,我們如何才能做得更好?

          3.位置參數(shù)的替代

          如果一個函數(shù)可以通過名字就知道它期望的參數(shù)是什么呢?這樣即使你誤傳了額外的數(shù)據給它,它也只會使用它需要的東西。

          讓我們對parseInt進行包裝。下面是一個簡單的實現(xiàn)。

          // 實現(xiàn)
          function myCustomParseInt(objArgs) {
          return parseInt(objArgs.item, objArgs.radix);
          }

          // 使用
          const num = myCustomParseInt({ item: '100', radix: 10 });

          myCustomParseInt僅接受一個參數(shù),它是一個對象。這個對象可以有兩個鍵:item 和 radix。讓我們使用我們的自定義函數(shù)與map。必須有一個中間步驟,將回調收到的args發(fā)送到myCustomParseInt。

          const numbers = ['1', '4', '8', '10'];

          const result = numbers.map((item, index) => myCustomParseInt({ item, index }));

          console.log(result); // [ 1, 4, 8, 10 ]

          請注意,即使我們將索引傳遞給myCustomParseInt也不會造成任何問題。那是因為myCustomParseInt只會忽略它。將對象傳遞給函數(shù)的這種模式稱為命名參數(shù),它比位置參數(shù)更明確。

          要更改基數(shù),我們必須顯式傳遞基數(shù)鍵。這意味著如果要解析以2為底的字符串,則必須轉到文檔并查看參數(shù)(基數(shù))的確切名稱。如果我們盲目地傳遞任何其他鍵,它將無濟于事。這對我們來說很棒,因為它避免了意外行為。

          3.1 具有解構的命名參數(shù)

          不久前,JavaScript獲得了稱為解構的功能,讓我們在myCustomParseInt實現(xiàn)中使用它。

          // 位置參數(shù)
          function myCustomParseInt(item, radix) {
          return parseInt(item, radix);
          }

          // 命名參數(shù)舊的實現(xiàn)
          function myCustomParseInt(objArgs) {
          return parseInt(objArgs.item, objArgs.radix);
          }

          // 命名參數(shù)解構
          function myCustomParseInt({ item, radix }) {
          return parseInt(item, radix);
          }

          你會注意到,只需添加兩個花括號,我們就可以得到命名args的好處,你可以將解構視為執(zhí)行 const item = objArgs.item;。

          如果使用 undefined 調用myCustomParseInt,則JS將引發(fā)錯誤。那是因為不允許 undefined.item。為了避免這種情況,我們可以在解構結束時添加 = {}。這樣,當我們傳遞undefined時,它將執(zhí)行 {}.item 這是有效的JS。這是最終的實現(xiàn):

          function myCustomParseInt({ item, radix } = {}) {
          return parseInt(item, radix);
          }

          通過命名參數(shù)模式,我們也可以跳過我們不想提供的參數(shù),因為函數(shù)不再依賴于傳遞參數(shù)的順序。

          // 對于位置參數(shù),我們必須在之間添加一個null
          function greetPos(firstName, middleName, lastName) {}
          greetPos('Aditya', null, 'Agarwal');


          // 使用命名參數(shù),你只需提供firstName和lastName。
          function greetNamed({ firstName, middleName, lastName } = {}) {}
          greetNamed({ firstName: 'Aditya', lastName 'Agarwal' });

          總而言之,我要說的是命名參數(shù)是一種強大的模式,如今它已變得非常普遍,但是你不必總是使用它們。有時你甚至可以將兩者結合在一起。瀏覽器中的fetch API的用法如下:

          // 以url作為位置參數(shù)的請求,以及以args做命名參數(shù)的選項。
          fetch('https://google.com', {
          method: 'POST',
          headers: {
          'Content-Type': 'application/json',
          },
          });

          // basic GET requests with just positional args
          fetch('https://google.com');

          這里的強制參數(shù)(API路徑)是一個位置參數(shù),然后通過命名參數(shù)接受可選的參數(shù)。

          最后



          如果你覺得這篇內容對你挺有啟發(fā),我想邀請你幫我三個小忙:

          1. 點個「在看」,讓更多的人也能看到這篇內容(喜歡不點在看,都是耍流氓 -_-)

          2. 歡迎加我微信「qianyu443033099」拉你進技術群,長期交流學習...

          3. 關注公眾號「前端下午茶」,持續(xù)為你推送精選好文,也可以加我為好友,隨時聊騷。


          點個在看支持我吧,轉發(fā)就更好了


          瀏覽 49
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产18第一无限资源网站 | 国产黄色视频在线观看免费 | 内射网站免费观看 | 中文字幕综合在线观看 | 日本成人中文在线 |