自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

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

開(kāi)發(fā) 前端
通常,在你傳遞一個(gè)或兩個(gè)參數(shù)的情況下,這很好,因?yàn)樗茈y弄亂參數(shù)的順序。但是如果你必須調(diào)用一個(gè)需要6個(gè)參數(shù)的函數(shù),那就很難記住傳遞參數(shù)的順序。

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

[[338903]]

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

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

greet函數(shù)接受兩個(gè)參數(shù):firstName和lastName。調(diào)用者必須確保firstName是第一個(gè)參數(shù),lastName是第二個(gè)參數(shù)。這里重要的一點(diǎn)是,參數(shù)的名稱(chēng)沒(méi)有任何意義,唯一重要的是參數(shù)傳遞的順序。

這種熟悉的方法稱(chēng)為位置參數(shù)。通常,在你傳遞一個(gè)或兩個(gè)參數(shù)的情況下,這很好,因?yàn)樗茈y弄亂參數(shù)的順序。但是如果你必須調(diào)用一個(gè)需要6個(gè)參數(shù)的函數(shù),那就很難記住傳遞參數(shù)的順序。你不希望傳遞密碼來(lái)代替用戶名參數(shù)。

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

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

(1) 不能跳過(guò)中間參數(shù) /

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

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

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

(2) 將類(lèi)型添加到位置參數(shù)不那么干凈

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

(3) 引起細(xì)微的錯(cuò)誤

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

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

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

讓我們?cè)俅尾榭创a number.map(parseInt)。

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

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

實(shí)際上,map將三個(gè)參數(shù)傳遞給其回調(diào)函數(shù)。第一個(gè)是數(shù)組中的當(dāng)前項(xiàng)目,第二個(gè)是項(xiàng)目的索引,第三個(gè)是整個(gè)數(shù)組。這本身沒(méi)有問(wèn)題,但真正的問(wèn)題在于后一部分。

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

你可能不知道,但是parseInt的第二個(gè)參數(shù)稱(chēng)為基數(shù)。默認(rèn)情況下,基數(shù)的值為10(以10為底,因?yàn)槿祟?lèi)遵循十進(jìn)制進(jìn)行計(jì)數(shù))。該代碼出了問(wèn)題,就是我們將當(dāng)前項(xiàng)目的索引作為基數(shù)值傳遞給parseInt。這些是發(fā)生的實(shí)際函數(shù)調(diào)用:

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

現(xiàn)在我們知道了問(wèn)題,我們?nèi)绾尾拍茏龅酶?

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

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

讓我們對(duì)parseInt進(jìn)行包裝。下面是一個(gè)簡(jiǎn)單的實(shí)現(xiàn)。

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

myCustomParseInt僅接受一個(gè)參數(shù),它是一個(gè)對(duì)象。這個(gè)對(duì)象可以有兩個(gè)鍵:item 和 radix。讓我們使用我們的自定義函數(shù)與map。必須有一個(gè)中間步驟,將回調(diào)收到的args發(fā)送到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 ] 

請(qǐng)注意,即使我們將索引傳遞給myCustomParseInt也不會(huì)造成任何問(wèn)題。那是因?yàn)閙yCustomParseInt只會(huì)忽略它。將對(duì)象傳遞給函數(shù)的這種模式稱(chēng)為命名參數(shù),它比位置參數(shù)更明確。

要更改基數(shù),我們必須顯式傳遞基數(shù)鍵。這意味著如果要解析以2為底的字符串,則必須轉(zhuǎn)到文檔并查看參數(shù)(基數(shù))的確切名稱(chēng)。如果我們盲目地傳遞任何其他鍵,它將無(wú)濟(jì)于事。這對(duì)我們來(lái)說(shuō)很棒,因?yàn)樗苊饬艘馔庑袨椤?/p>

(1) 具有解構(gòu)的命名參數(shù)

不久前,JavaScript獲得了稱(chēng)為解構(gòu)的功能,讓我們?cè)趍yCustomParseInt實(shí)現(xiàn)中使用它。

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

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

如果使用 undefined 調(diào)用myCustomParseInt,則JS將引發(fā)錯(cuò)誤。那是因?yàn)椴辉试S undefined.item。為了避免這種情況,我們可以在解構(gòu)結(jié)束時(shí)添加 = {}。這樣,當(dāng)我們傳遞undefined時(shí),它將執(zhí)行 {}.item 這是有效的JS。這是最終的實(shí)現(xiàn):

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

通過(guò)命名參數(shù)模式,我們也可以跳過(guò)我們不想提供的參數(shù),因?yàn)楹瘮?shù)不再依賴(lài)于傳遞參數(shù)的順序。

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

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

  1. // 以u(píng)rl作為位置參數(shù)的請(qǐng)求,以及以args做命名參數(shù)的選項(xiàng)。 
  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'); 

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

 

責(zé)任編輯:趙寧寧 來(lái)源: 今日頭條
相關(guān)推薦

2022-11-10 15:32:29

2012-05-11 09:50:49

iOSAndroid移動(dòng)應(yīng)用

2014-03-26 10:09:14

指針指針使用

2020-02-14 13:53:33

Python 開(kāi)發(fā)編程語(yǔ)言

2020-07-17 19:31:19

PythonR編程

2023-02-26 23:36:08

PHPGo函數(shù)

2023-09-27 08:22:28

Windows系統(tǒng)管理器

2022-09-05 10:01:19

VueReact

2024-08-13 17:29:24

2022-03-28 11:51:00

深度學(xué)習(xí)機(jī)器學(xué)習(xí)模型

2021-01-25 07:14:53

Cloud DevOps云計(jì)算

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++函數(shù)

2009-06-09 21:54:26

傳遞參數(shù)JavaScript

2017-09-20 07:57:38

AWG電纜導(dǎo)線

2021-05-27 07:54:21

Math.max()-Infinity參數(shù)

2021-01-13 10:51:08

PromissetTimeout(函數(shù)

2009-07-08 09:47:49

Scala 2.8Scala
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)