摘要:在中,引入了一種新方法來指定任意參數的默認值。看下面例子在每個參數的后面是一個表達式,指定了參數未傳遞時的默認值。如果沒有為一個參數指定默認值,那么該參數的默認值為,所以等同于原文鏈接
Rest 參數
通常,我們需要創建一個可變參數的函數,可變參數是指函數可以接受任意數量的參數。例如,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 參數之前或之后添加一些參數,我們不得不更新內部的循環。Rest 參數解決了這些問題,下面是 使用 Rest 參數的實現方式:
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。
實現Rest參數的函數 restArgs
var restArgs = function (func, startIndex) { // rest參數從哪里開始,如果沒有,則默認視函數最后一個參數為rest參數 // 注意, 函數對象的length屬性, 揭示了函數的參數個數 /* ex: function add(a,b) {return a+b;} console.log(add.length;) // 2 */ startIndex = startIndex == null ? func.length - 1 : +startIndex; // 返回一個支持rest參數的函數 return function () { // 校正參數, 以免出現負值情況 var length = Math.max(arguments.length - startIndex, 0); // 為rest參數開辟數組存放 var rest = Array(length); // 假設參數從2個開始: func(a,b,*rest) // 調用: func(1,2,3,4,5); 實際的調用是:func.call(this, 1,2, [3,4,5]); for (var index = 0; index < length; index++) { rest[index] = arguments[index + startIndex]; } // 根據rest參數不同, 分情況調用函數, 需要注意的是, rest參數總是最后一個參數, 否則會有歧義 switch (startIndex) { case 0: // call的參數一個個傳 return func.call(this, rest); case 1: return func.call(this, arguments[0], rest); case 2: return func.call(this, arguments[0], arguments[1], rest); } // 如果不是上面三種情況, 而是更通用的(應該是作者寫著寫著發現這個switch case可能越寫越長, 就用了apply) var args = Array(startIndex + 1); // 先拿到前面參數 for (index = 0; index < startIndex; index++) { args[index] = arguments[index]; } // 拼接上剩余參數 args[startIndex] = rest; return func.apply(this, args); }; };參數的默認值
通常,調用一個函數時,不需要調用者傳遞所有可能的參數,那些沒有傳遞的參數都需要一個合理的默認值。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) {...}
原文鏈接
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/86772.html
摘要:返回一個對象,遍歷對象自身和繼承的所有可枚舉屬性不含,與相同和在紅寶書中就已經提到過屬性,表示的是引用類型實例的一個內部指針,指向該實例的構造函數的原型對象。 半個月前就決定要將ES6的學習總結一遍,結果拖延癥一犯,半個月就過去了,現在補起來,慚愧慚愧。 阮一峰的《ES6標準入門》這本書有300頁左右,除了幾個新的API和js語法的擴展,真正有價值的內容并不多。所謂存在即合理,每部分的...
摘要:函數調用會在內存形成一個調用記錄,又稱調用幀,保存調用位置和內部變量等信息。等到運行結束,將結果返回到,的調用幀才會消失。方法用于將一組值,轉換為數組。,和遍歷數組方法返回一個布爾值,表示某個數組是否包含給定的值,與字符串的方法類似。 ES6 簡介 ES6, 全稱 ECMAScript 6.0 ,是 JavaScript 的下一個版本標準,2015.06 發版。 let 和 const...
摘要:模板字符串甚至還能嵌套解構賦值允許按照一定模式,從數組和對象中提取值,對變量進行賦值,這被稱為解構。運算符使用場景應該稍少一些,主要是處理不定數量參數,可以避免對象的使用。 es6中較為常用的書寫風格 為了書寫的方便,es6中提出了很多比較友好的書寫方式,其中最為常見的屬于以下幾個: 字符串模板 `abcdef${test}` 解構賦值 let [a, b, c] = [1,...
摘要:返回布爾值,表示參數字符串是否在原字符串的頭部。模板字符串之中還能調用函數。其他對字符串還有許多擴展,例如對字符表示的擴充以及為字符串提供了遍歷方法詳情請點擊正則的擴展構造函數在中,構造函數的參數有兩種情況。 ES6對各種基本類型都做了擴展,內容有些多,本章節挑選比較重要的擴展說明。 1 字符串的擴展 1.1 includes(), startsWith(), endsWith() 傳...
摘要:字符串的擴展字符的表示法允許采用形式表示一個字符,其中表示字符的碼點。返回布爾值,表示參數字符串是否在源字符串的頭部。使用和這兩個常量,用來表示這個范圍的上下限。對于那些無法用個二進制位精確表示的小數,方法返回最接近這個小數的單精度浮點數。 字符串的擴展 字符的 Unicode 表示法 JavaScript 允許采用uxxxx形式表示一個字符,其中xxxx表示字符的 Unicode 碼...
閱讀 1198·2021-11-10 11:35
閱讀 2925·2021-09-24 10:35
閱讀 2957·2021-09-22 15:38
閱讀 2807·2019-08-30 15:43
閱讀 1338·2019-08-29 18:39
閱讀 2558·2019-08-29 15:22
閱讀 2789·2019-08-28 18:17
閱讀 612·2019-08-26 13:37