[ES6深度解析]9:Rest引數和預設值
Rest引數
在建立API時,一個常見的需求是建立可變引數函式(引數個數不確定),這個函式可以接受任意數量的引數。例如,string.prototype.concat
方法接受任意數量的字串引數。通過使用rest引數,ES6提供了一種編寫可變引數函式的新方法。
為了演示,讓我們編寫一個簡單的可變引數函式containsAll
,它檢查一個字串是否包含許多子字串。例如,containsAll("banana","b","nan")
將返回true
,而containsAll("banana","c","nan")
將返回false
。
下面是實現這個函式的傳統方法:
function containsAll(haystack) { for (var i = 1; i < arguments.length; i++) { var needle = arguments[i]; if (haystack.indexOf(needle) === -1) { return false; } } return true; }
這個實現使用了神奇的arguments物件,這是一個包含傳遞給函式的形參的類陣列物件。這段程式碼當然做了我們想要的,但是它的可讀性不是最佳的。函式形參列表只包含一個形參haystack
,所以不可能一眼就看出函式實際上有多個實參。此外,我們必須小心地開始遍歷arguments
索引為1
而不是0
的引數,因為arguments[0]
對應於haystack
引數。如果我們想在haystack
之前或之後新增另一個引數,我們必須記住更新for迴圈。Rest引數解決了這兩個問題。下面是一個使用rest引數的containsAll
的自然ES6實現:
function containsAll(haystack, ...needles) { for (var needle of needles) { if (haystack.indexOf(needle) === -1) { return false; } } return true; }
這個版本的函式具有與第一個相同的行為,但包含特殊的...needles
語法。讓我們看看呼叫containsAll("banana","b","nan")
時如何呼叫這個特殊語法。引數haystack
像往常一樣被首先傳遞的引數賦值,即banana
。needles
前的省略號...
表示它是一個rest引數
。所有其他傳遞的引數都放在一個數組中,並賦值給變數needles
。對於我們的示例呼叫,needles
設定為[“b”,“nan”]
。然後函式繼續正常執行。
只有函式的最後一個引數才可以標記為rest引數。在呼叫中,rest引數之前的引數照常賦值。任何“額外”引數被放入一個數組中,並賦值給rest引數。如果沒有額外的引數,那麼rest形參將只是一個空陣列;rest引數永遠不會是undefined
預設引數(Default parameters)
通常,函式不需要呼叫者傳遞所有可能的引數,對於未傳遞的引數,可以使用合理的預設值。JavaScript總是有一種不靈活的預設引數形式;未傳遞值的引數預設為undefined。ES6引入了一種指定任意引數預設值的方法。這是一個例子:
function animalSentence(animals2="tigers", animals3="bears") {
return `Lions and ${animals2} and ${animals3}! Oh my!`;
}
對於每個引數,=
後面的部分是一個表示式,如果呼叫者沒有傳遞引數,則指定引數的預設值。因此,animalSentence()
返回"Lions and tigers and bears! Oh my!"
;animalSentence("elephants")
返回"Lions and elephants and bears! Oh my!"
;animalSentence("elephants", "whales")
返回"Lions and elephants and whales! Oh my!"
;
以下是與預設引數相關的一些微妙之處:
- 與Python不同,預設值表示式在函式呼叫時從左到右計算求值。這也意味著預設值表示式可以使用在它之前(左側)填充的引數的值。例如,我們可以讓我們的動物句子功能更奇妙,如下所示:
function animalSentenceFancy(animals2="tigers", animals3=(animals2 == "bears") ? "sealions" : "bears")
{
return `Lions and ${animals2} and ${animals3}! Oh my!`;
}
// animalSentenceFancy("bears") 返回 "Lions and bears and sealions. Oh my!"
- 傳遞undefined被認為等於什麼都不傳遞。因此,
animalSentence(undefined, "unicorns")
返回"Lions and tigers and unicorns! Oh my!"
- 沒有預設值的形參隱式預設為undefined。
function myFunc(a=42, b) {...}
是允許的,等同於function myFunc(a=42, b=undefined) {...}
拋棄arguments
現在我們已經看到,rest形參和預設值可以替代arguments
物件的使用,刪除arguments
通常會使程式碼更易於閱讀。除了有損可讀性之外,arguments
物件的魔力還會給優化JavaScript vm帶來麻煩。
本文來自部落格園,作者:Max力出奇跡,轉載請註明原文連結:https://www.cnblogs.com/welody/p/15180100.html
如果覺得文章不錯,歡迎點選推薦