ES6 參數(shù)


我們知道,參數(shù)分為形參(parameter)和實(shí)參(argument),形參是指函數(shù)定義時的參數(shù),實(shí)參是指真正傳入函數(shù)的參數(shù)。下面,我們將從多個角度來分析,ES6中,參數(shù)的一些行為。


參數(shù)的默認(rèn)值####

函數(shù)中參數(shù)的默認(rèn)值這一設(shè)定尤為重要,不僅可以避免一些不必要的錯誤,還能簡化過程,好處很多。下面我們來看看,在ES5中,參數(shù)的默認(rèn)值是如何設(shè)定的:

function foo(num1,num2){
    num1 = num1||10;
    num2 = num2||5;
    console.log(num1,num2);
}
foo(1,2)               //1,2
foo(1)                 //1,5
foo(undefined,2)       //10,2

通常是用||運(yùn)算符來做默認(rèn)值處理,判斷傳入的參數(shù)的真假,如果為真,用傳入的參數(shù),為假值,用默認(rèn)的參數(shù)。當(dāng)然,這種方式有一定的漏洞的,比如當(dāng)我們傳入的參數(shù)是0的時候。

foo(0,2)       //10,2

就有問題了。其實(shí)得到這個結(jié)果也是意料之中的,0的隱式轉(zhuǎn)換為布爾值的結(jié)果就是false,那么應(yīng)該如何改進(jìn)呢?在ES5中,人們是這么處理的:

function foo(num1,num2){
    num1 = num1 !== undefined?num1:10;
    num2 = num2 !== undefined?num2:5;
    console.log(num1,num2);
}
foo(1,2)               //1,2
foo(1)                 //1,5
foo(undefined,2)       //10,2
foo(0,2)               //0,2

確實(shí),這樣寫看起來就萬無一失了,但是顯得太臃腫了不是嗎,在ES6中,我們可以直接使用如下方式設(shè)置默認(rèn)值:

function foo(num1=10,num2=5){
    console.log(num1,num2);
}
foo(1,2)               //1,2
foo(1)                 //1,5
foo(undefined,2)       //10,2
foo(0,2)               //0,2

下面,讓我們來思考一個問題,默認(rèn)值到底是如何影響參數(shù)的呢?傳入的參數(shù)我們知道,可以通過arguments對象獲得,那么,如果傳入的參數(shù)在函數(shù)體內(nèi)被改變,那么對應(yīng)的arguments也會改變嗎?請看下面的例子:

function foo(num1,num2){
    console.log(num1 === arguments[0]);
    console.log(num2 === arguments[1]);
    num1 = 'a';
    num2 = 'b';
    console.log(num1 === arguments[0]);
    console.log(num2 === arguments[1]);
}
foo(1,2);              //true
                       //true
                       //true
                       //true

由此可以看出,在參數(shù)被修改的時候,arguments也會跟著修改,并且保持與修改的參數(shù)一致。這是在非嚴(yán)格模式下,那么在嚴(yán)格模式下呢?請看如下例子:

'use strict'
function foo(num1,num2){
    console.log(num1 === arguments[0]);
    console.log(num2 === arguments[1]);
    num1 = 'a';
    num2 = 'b';
    console.log(num1 === arguments[0]);
    console.log(num2 === arguments[1]);
}
foo(1,2);              //true
                       //true
                       //false
                       //false

正如你所看到的,在嚴(yán)格模式下,arguments并沒有修改。那么,在ES6中的默認(rèn)值呢?看如下例子:

function foo(num1,num2=2){
    console.log(arguments.length);
    console.log(num1 === arguments[0]);
    console.log(num2 === arguments[1]);
    num1 = 'a';
    num2 = 'b';
    console.log(num1 === arguments[0]);
    console.log(num2 === arguments[1]);
}
foo(1);                //1
                       //true
                       //false
                       //false
                       //false

在嚴(yán)格模式下:

'use strict'
function foo(num1,num2=2){
    console.log(arguments.length);
    console.log(num1 === arguments[0]);
    console.log(num2 === arguments[1]);
    num1 = 'a';
    num2 = 'b';
    console.log(num1 === arguments[0]);
    console.log(num2 === arguments[1]);
}
foo(1);                //1
                       //true
                       //false
                       //false
                       //false

通過arguments.length,傳入的參數(shù)個數(shù)是1,我們可以明白,其實(shí)arguments真正收集的不是默認(rèn)值,而是輸入的參數(shù),并且只要加入了默認(rèn)值,無論是在嚴(yán)格模式,還是非嚴(yán)格模式,參數(shù)arguments都不會改變,只會保留初始值,也就是函數(shù)調(diào)用的時候傳入的最初的值。

不僅如此

ES6默認(rèn)值的用法不僅如此,它不僅可以傳入原始值,還可以是函數(shù)調(diào)用,甚至是參數(shù)本身,具體例子如下:

function add(num1,num2){
    return num1+num2
}
function foo(num1=10,num2=add(num1,5)){
    console.log(num1,num2);
}
foo(1,2)               //1,2
foo(1)                 //1,6
foo(undefined,1)       //10,1
foo()                  //10,15

當(dāng)然,如果調(diào)用的默認(rèn)值是不存在的,那么會報(bào)錯。比如:

function add1(num1,num2){
    return num1+num2
}
function foo(num1=10,num2=add(num1,5)){ //報(bào)錯,ReferenceError,add不存在
    console.log(num1,num2);
}

當(dāng)然,還有一種不太明顯的,就是第一個參數(shù)把第二個參數(shù)當(dāng)默認(rèn)值:

function foo(num1=num2,num2=10){ 
    console.log(num1,num2);
}
foo(1,2)           //1,2
foo(undefined,2)   //報(bào)錯,ReferenceError,num2不存在

因?yàn)闀簳r性死區(qū),在使用num2的時候,并沒有申明,其實(shí)上述的代碼可以大概理解為在函數(shù)內(nèi)部是這樣的:

function foo(num1,num2){ 
    let num1;
    num1 = arguments[0] !== undefined?arguments[0]:num2;
    let num2;
    num2 = arguments[1] !== undefined?arguments[1]:10;
    console.log(num1,num2);
}

由此,可以看出,使用num2的時候并沒有申明,所以會報(bào)錯。

還有一點(diǎn)值得注意,函數(shù)參數(shù)的有自己單獨(dú)的作用域和自己的暫時性死區(qū)(TDZ),和函數(shù)本身的作用域是分開的。也就是說,參數(shù)的默認(rèn)值不能使用函數(shù)內(nèi)部申明的變量。


參數(shù)的默認(rèn)值就告一段落了,下面說一個ES6引入的新的東西,作用和arguments類似,但是又不完全相同

剩余參數(shù)(Rest Parameters)####

剩余參數(shù)的申明是使用...3個點(diǎn)加在參數(shù)名前。我們知道,在JavaScript中,參數(shù)的個數(shù),傳入的多少并不重要,需求2個參數(shù),但是傳入了3個參數(shù),那么最后一個參數(shù)就會被舍去;需求2個參數(shù),但是傳入了1個參數(shù),第二個參數(shù)就是undefined,這個本身不會報(bào)錯。那么剩余參數(shù)的作用就是類似于arguments,把剩下的參數(shù)以數(shù)組的形式收集起來,具體操作如下:

function foo(num1,...num2){ 
    console.log(num2);
}
foo(0,1,2,3,4,5);          //[1,2,3,4,5]

正如你說看到的,num10,剩下的參數(shù)1,2,3,4,5全部被num2以數(shù)組的形式收集了起來。
剩余參數(shù)的概念并不復(fù)雜,但是還是需要注意2點(diǎn):

  • 剩余參數(shù)后面不能再跟參數(shù),否則會報(bào)錯:
function foo(num1,...num2,num3){       //報(bào)錯,SyntaxError,后面不能再跟參數(shù)
    console.log(num2);
}

也就是說,剩余參數(shù)只能是函數(shù)的最后一個參數(shù)。

  • 剩余參數(shù)不能運(yùn)用在對象的setter方法中。例如:
let a = {
    set name(...value) {      //報(bào)錯,SyntaxError
            // do something
        }
}

至于理由,很簡單,因?yàn)?code>setter方法本身只能接受單個數(shù),而剩余參數(shù)是一個數(shù)組,不符合要求,當(dāng)然會報(bào)錯。

最后再講一點(diǎn),如果一個函數(shù)的參數(shù)只有剩余參數(shù),那么此時,剩余參數(shù)arguments表達(dá)的差不多是一個意思,只不過剩余參數(shù)是一個更純粹的數(shù)組。arguments還背負(fù)著自己的歷史使命,比如callee,之類的。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 三,字符串?dāng)U展 3.1 Unicode表示法 ES6 做出了改進(jìn),只要將碼點(diǎn)放入大括號,就能正確解讀該字符。有了這...
    eastbaby閱讀 1,667評論 0 8
  • 1.函數(shù)參數(shù)的默認(rèn)值 (1).基本用法 在ES6之前,不能直接為函數(shù)的參數(shù)指定默認(rèn)值,只能采用變通的方法。
    趙然228閱讀 829評論 0 0
  • 函數(shù)參數(shù)的默認(rèn)值 基本用法 在ES6之前,不能直接為函數(shù)的參數(shù)指定默認(rèn)值,只能采用變通的方法。 上面代碼檢查函數(shù)l...
    呼呼哥閱讀 3,703評論 0 1
  • 參數(shù)擴(kuò)展 1.收集剩余參數(shù)到一個數(shù)組中 2.數(shù)組展開(...arr 表示把數(shù)組arr展開) 例1 例2 例3 默認(rèn)參數(shù)
    余生筑閱讀 212評論 0 0
  • 斜雨微濕飛燕子,煙波沆碭,春水隨風(fēng)皺,望極天涯云夢處,也無計(jì)瀟湘暫住。 擬泛輕舟逐晚晴,水天之際,殘照忽而逝,無情...
    莫自在閱讀 257評論 0 0

友情鏈接更多精彩內(nèi)容