欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

深入學(xué)習(xí)JavaScript中的Rest參數(shù)和參數(shù)默認(rèn)值

 更新時(shí)間:2015年07月28日 10:48:30   作者:Jason Orendorff  
這篇文章主要介紹了深入學(xué)習(xí)JavaScript中的Rest參數(shù)和參數(shù)默認(rèn)值,是JS入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下

本文將討論使 JavaScript 函數(shù)更有表現(xiàn)力的兩個(gè)特性:Rest 參數(shù)和參數(shù)默認(rèn)值。
Rest 參數(shù)

通常,我們需要創(chuàng)建一個(gè)可變參數(shù)的函數(shù),可變參數(shù)是指函數(shù)可以接受任意數(shù)量的參數(shù)。例如,String.prototype.concat 可以接受任何數(shù)量的字符串作為參數(shù)。使用 Rest 參數(shù),ES6 為我們提供一種新的方式來創(chuàng)建可變參數(shù)的函數(shù)。

我們來實(shí)現(xiàn)一個(gè)示例函數(shù) containsAll,用于檢查一個(gè)字符串中是否包含某些子字符串。例如,containsAll("banana", "b", "nan") 將返回true,containsAll("banana", "c", "nan") 將返回 false。

下面是傳統(tǒng)的實(shí)現(xiàn)方式:

function containsAll(haystack) {
 for (var i = 1; i < arguments.length; i++) {
  var needle = arguments[i];
  if (haystack.indexOf(needle) === -1) {
   return false;
  }
 }
 return true;
}
 
function containsAll(haystack) {
 for (var i = 1; i < arguments.length; i++) {
  var needle = arguments[i];
  if (haystack.indexOf(needle) === -1) {
   return false;
  }
 }
 return true;
}

該實(shí)現(xiàn)用到了 arguments 對象,該對象是一個(gè)類數(shù)組對象,包含函數(shù)被調(diào)用時(shí)的實(shí)參列表。這段代碼正是我們想要的,但其可讀性卻不是最優(yōu)的。函數(shù)只有一個(gè)形參 haystack,所以不可能一看就知道該函數(shù)需要多個(gè)參數(shù),并且在遍歷 arguments 時(shí),需要特別注意遍歷的開始索引為1 ,而不是常見的 0,因?yàn)?arguments[0] 就是函數(shù)定義時(shí)的形參 haystack。如果我們想在 haystack 參數(shù)之前或之后添加一些參數(shù),我們不得不更新內(nèi)部的循環(huán)。Rest 參數(shù)解決了這些問題,下面是 使用 Rest 參數(shù)的實(shí)現(xiàn)方式:

function containsAll(haystack, ...needles) {
 for (var needle of needles) {
  if (haystack.indexOf(needle) === -1) {
   return false;
  }
 }
 return true;
}
 
function containsAll(haystack, ...needles) {
 for (var needle of needles) {
  if (haystack.indexOf(needle) === -1) {
   return false;
  }
 }
 return true;
}

以上兩個(gè)實(shí)現(xiàn)都滿足了我們的需求,但后者包含一個(gè)特殊的 ...needles 語法。我們來看看調(diào)用containsAll("banana", "b", "nan") 時(shí)的細(xì)節(jié),參數(shù) haystack 和以往一樣,將用函數(shù)的第一個(gè)實(shí)參填充,值為 "banana",needles 前面的省略號表示它是一個(gè) Rest 參數(shù),剩余的所有實(shí)參將被放入一個(gè)數(shù)組中,并將該數(shù)組賦給 needles 遍量。在這個(gè)調(diào)用中,needles 的值為 ["b", "nan"]。然后,就是正常的函數(shù)執(zhí)行了。

只能將函數(shù)的最后一個(gè)函數(shù)作為 Rest 參數(shù),在函數(shù)被調(diào)用時(shí),Rest 參數(shù)之前的參數(shù)都將被正常填充,之外的參數(shù)將被放入一個(gè)數(shù)組中,并將該數(shù)組作為 Rest 參數(shù)的值,如果沒有更多的參數(shù),那么 Rest 參數(shù)的值為一個(gè)空數(shù)組 [],Rest 參數(shù)的值永遠(yuǎn)都不會是 undefined。
參數(shù)的默認(rèn)值

通常,調(diào)用一個(gè)函數(shù)時(shí),不需要調(diào)用者傳遞所有可能的參數(shù),那些沒有傳遞的參數(shù)都需要一個(gè)合理的默認(rèn)值。JavaScript 對那些沒有傳遞的參數(shù)都有一個(gè)固定的默認(rèn)值 undefined。在 ES6 中,引入了一種新方法來指定任意參數(shù)的默認(rèn)值。

看下面例子:

function animalSentence(animals2="tigers", animals3="bears") {
  return `Lions and ${animals2} and ${animals3}! Oh my!`;
}
 
function animalSentence(animals2="tigers", animals3="bears") {
  return `Lions and ${animals2} and ${animals3}! Oh my!`;
}

在每個(gè)參數(shù)的 = 后面是一個(gè)表達(dá)式,指定了參數(shù)未傳遞時(shí)的默認(rèn)值。所以,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!"。

參數(shù)默認(rèn)值需要注意的幾個(gè)細(xì)節(jié):

    與 Python 不一樣的是,參數(shù)默認(rèn)值的表達(dá)式是在函數(shù)調(diào)用時(shí)從左到右計(jì)算的,這意味著表達(dá)式可以使用前面已經(jīng)被填充的參數(shù)。例如,我們可以將上面的函數(shù)變得更有趣一點(diǎn):

function animalSentenceFancy(animals2="tigers",
  animals3=(animals2 == "bears") ? "sealions" : "bears")
{
 return `Lions and ${animals2} and ${animals3}! Oh my!`;
}

 
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 等同于沒有傳遞該參數(shù)。因此,animalSentence(undefined, "unicorns") 將返回 "Lions and tigers and unicorns! Oh my!"。
    如果沒有為一個(gè)參數(shù)指定默認(rèn)值,那么該參數(shù)的默認(rèn)值為 undefined,所以

function myFunc(a=42, b) {...}
 
function myFunc(a=42, b) {...}

等同于

function myFunc(a=42, b=undefined) {...}
 
function myFunc(a=42, b=undefined) {...}

拋棄 arguments

通過 Rest 參數(shù)和參數(shù)的默認(rèn)值,我們可以完全拋棄 arguments 對象,使我們的代碼可讀性更高。此外,arguments 對象也加深了優(yōu)化 JavaScript 的難題。

希望以上兩個(gè)新特性可以完全取代 arguments。作為第一步,在使用 Rest 參數(shù)或參數(shù)的默認(rèn)值時(shí),請避免使用 arguments 對象,假如 arguments 對象還不會立即被移除,或者永遠(yuǎn)不會,那么也最好是避免在使用 Rest 參數(shù)或參數(shù)默認(rèn)值時(shí)使用 arguments 對象。
兼容性

Firefox 15 以上的版本已經(jīng)支持這兩個(gè)新特性。然而,除此之外,還沒有其他任何瀏覽器支持。最近,V8 的實(shí)驗(yàn)環(huán)境添加了對 Rest 參數(shù)的支持,而參數(shù)默認(rèn)值還有一個(gè) issue,JSC 也對 Rest 參數(shù)和參數(shù)默認(rèn)值提了一些 issue。

Babel 和 Traceur 這兩個(gè)編譯器都已經(jīng)支持了參數(shù)默認(rèn)值,所以你可以大膽使用。
結(jié)論

盡管從技術(shù)層面上看,這兩個(gè)新特性在并沒有給函數(shù)引入新的行為,但它們可以使一些函數(shù)的聲明更具表現(xiàn)力和可讀性。

相關(guān)文章

最新評論