成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

JavaScript:為什么命名參數比位置參數更好

開發 前端
通常,在你傳遞一個或兩個參數的情況下,這很好,因為它很難弄亂參數的順序。但是如果你必須調用一個需要6個參數的函數,那就很難記住傳遞參數的順序。

1. 什么是位置參數?

[[338903]]

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

  1. function greet(firstName, lastName) { 
  2.   console.log(`Hello ${firstName} ${lastName}`); 
  3.  
  4. // 預期用法 
  5.  
  6. greet('Michael', 'Scott'); 
  7.  
  8. const fName = 'Harry'
  9. const lName = 'Potter'
  10. greet(fName, lName); 
  11.  
  12.  
  13. // 錯誤用法 
  14.  
  15. const firstName = 'Erlich'
  16. const lastName = 'Bachman'
  17. greet(lastName, firstName); 

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

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

2. 位置參數問題

位置參數很簡單,但是你將面臨一些挑戰。

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

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

  1. greet('Aditya', null, 'Agarwal'); 
  2. // Correct ✅ 
  3.  
  4. greet('Aditya', 'Agarwal'); 
  5. // Incorrect ❌ 

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

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

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

(3) 引起細微的錯誤

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

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

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

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

這里到底發生了什么?

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

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

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

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

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

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

3. 位置參數的替代

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

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

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

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

  1. const numbers = ['1', '4', '8', '10']; 
  2.  
  3. const result = numbers.map((item, index) => myCustomParseInt({ item, index })); 
  4.  
  5. console.log(result); // [ 1, 4, 8, 10 ] 

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

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

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

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

  1. // 位置參數 
  2. function myCustomParseInt(item, radix) { 
  3.   return parseInt(item, radix); 
  4.  
  5. // 命名參數舊的實現 
  6. function myCustomParseInt(objArgs) { 
  7.   return parseInt(objArgs.item, objArgs.radix); 
  8.  
  9. // 命名參數解構 
  10. function myCustomParseInt({ item, radix }) { 
  11.   return parseInt(item, radix); 

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

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

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

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

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

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

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

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

 

責任編輯:趙寧寧 來源: 今日頭條
相關推薦

2022-11-10 15:32:29

2012-05-11 09:50:49

iOSAndroid移動應用

2014-03-26 10:09:14

指針指針使用

2020-07-17 19:31:19

PythonR編程

2020-02-14 13:53:33

Python 開發編程語言

2022-09-05 10:01:19

VueReact

2023-02-26 23:36:08

PHPGo函數

2023-09-27 08:22:28

Windows系統管理器

2024-08-13 17:29:24

2022-03-28 11:51:00

深度學習機器學習模型

2021-01-25 07:14:53

Cloud DevOps云計算

2021-08-31 23:33:50

AndroidiOS功能

2013-01-15 10:53:36

2013-01-16 14:29:22

2010-01-20 17:32:16

C++函數

2021-01-13 10:51:08

PromissetTimeout(函數

2017-09-20 07:57:38

AWG電纜導線

2021-05-27 07:54:21

Math.max()-Infinity參數

2009-06-09 21:54:26

傳遞參數JavaScript

2018-05-30 14:49:51

編程語言API語法
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 精品国产第一区二区三区 | 国产精品色婷婷久久58 | 欧美日韩国产一区二区三区 | 亚洲3p| 欧美成人综合 | 欧美日本久久 | 国产精品久久久久久久久久久久 | 成人三级在线观看 | 久久精品欧美一区二区三区麻豆 | 激情亚洲 | 中文字幕成人 | 欧美一级久久久猛烈a大片 日韩av免费在线观看 | 久久逼逼 | 国产精品18hdxxxⅹ在线 | 一区二区三区在线免费观看 | 国产精品区二区三区日本 | 免费激情av | 色视频网站免费 | 亚洲视频在线看 | 日本在线视频一区二区 | 欧洲av在线 | 91精品国产综合久久婷婷香蕉 | 久久噜噜噜精品国产亚洲综合 | 久久久久国产精品一区二区 | 日韩在线视频免费观看 | 亚洲精品一区二区三区 | 日韩视频在线免费观看 | 日韩欧美在线免费观看视频 | 91亚洲一区 | 国产中文 | 亚洲v区| 精品一区在线免费观看 | 国产日韩精品一区二区 | 九色porny自拍视频 | 看av网| 黄一区二区三区 | 久久久久久久国产 | 国产91 在线播放 | 国产精品久久久久久久久婷婷 | 欧美成视频在线观看 | 成人综合在线视频 |