溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JavaScript中為什么命名參數比位置參數

發(fā)布時間:2021-09-30 14:47:44 來源:億速云 閱讀:110 作者:柒染 欄目:web開發(fā)

這篇文章將為大家詳細講解有關JavaScript中為什么命名參數比位置參數,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。

1. 什么是位置參數?

JavaScript中為什么命名參數比位置參數

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

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函數接受兩個參數:firstName和lastName。調用者必須確保firstName是第一個參數,lastName是第二個參數。這里重要的一點是,參數的名稱沒有任何意義,唯一重要的是參數傳遞的順序。

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

2. 位置參數問題

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

(1) 不能跳過中間參數 /

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

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

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

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

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

(3) 引起細微的錯誤

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

const numbers = ['1', '4', '8', '10']; console.log(numbers.map(parseInt));  // 你可能會認為結果將是: [1, 4, 8, 10]  // 這是實際的輸出: [ 1, NaN, NaN, 3 ]

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

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

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

  • 我們在numbers數組上運行map函數。

  • map獲取數組的第一項并將其傳遞給parseInt。

  • 現在,對于數組中的第一項(即1),它將執(zhí)行 parseInt(1)。對...?錯誤!!!

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

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

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

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

現在我們知道了問題,我們如何才能做得更好?

3. 位置參數的替代

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

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

// 實現 function myCustomParseInt(objArgs) {   return parseInt(objArgs.item, objArgs.radix); }  // 使用 const num = myCustomParseInt({ item: '100', radix: 10 });

myCustomParseInt僅接受一個參數,它是一個對象。這個對象可以有兩個鍵:item 和  radix。讓我們使用我們的自定義函數與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只會忽略它。將對象傳遞給函數的這種模式稱為命名參數,它比位置參數更明確。

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

(1) 具有解構的命名參數

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

// 位置參數 function myCustomParseInt(item, radix) {   return parseInt(item, radix); }  // 命名參數舊的實現 function myCustomParseInt(objArgs) {   return parseInt(objArgs.item, objArgs.radix); }  // 命名參數解構 function myCustomParseInt({ item, radix }) {   return parseInt(item, radix); }

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

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

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

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

// 對于位置參數,我們必須在之間添加一個null function greetPos(firstName, middleName, lastName) {} greetPos('Aditya', null, 'Agarwal');   // 使用命名參數,你只需提供firstName和lastName。 function greetNamed({ firstName, middleName, lastName } = {}) {} greetNamed({ firstName: 'Aditya', lastName 'Agarwal' });

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

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

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

關于JavaScript中為什么命名參數比位置參數就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI