arguments
稍微學(xué)過(guò)點(diǎn)編程語(yǔ)言的人應(yīng)該都知道函數(shù)屏积、形參和實(shí)參的概念:
function foo(x,y){ // x和y都是函數(shù)foo的形參
return x+y;
}
foo(3,4); // 3和4都是函數(shù)foo的實(shí)參
在JS中使用函數(shù)的時(shí)候,函數(shù)內(nèi)部都會(huì)有一個(gè)本地變量數(shù)組arguments府框,它裝載了傳入函數(shù)內(nèi)的實(shí)參。
function foo(x,y){ // x和y都是函數(shù)foo的形參
return arguments;
}
foo(3,4); // [3,4]
foo(3,4,5,6); // [3,4,5,6] 即使在沒(méi)有定義形參的位置傳入了參數(shù),這些參數(shù)也會(huì)加入arguments隅忿。
每個(gè)被調(diào)用的函數(shù)都有自己的arguments,所以對(duì)于套用函數(shù)的情況需要注意一下邦尊。
function foo(x){
function foo2(y){
console.log(arguments)
}
foo2(x+1)
}
foo(1); // [2]
arguments是一個(gè)數(shù)組背桐,但不是Array對(duì)象的實(shí)例,所以也沒(méi)繼承Array原型鏈上的方法蝉揍。但我們可以使用Function.prototype.call(apply)嘛链峭!
我們可以對(duì)傳入的實(shí)參進(jìn)行再賦值:
arguments[0] = "hello";
arguments有一個(gè)callee屬性,它指向了當(dāng)前正在執(zhí)行的函數(shù)(也就是arguments對(duì)應(yīng)的函數(shù))又沾,我們可以這樣子再次調(diào)用這個(gè)函數(shù):arguments.callee()
弊仪。在匿名函數(shù)中熙卡,如果我們需要對(duì)這個(gè)函數(shù)循環(huán)迭代,由于它是匿名的励饵,因此我們可以且只能使用arguments.callee()
驳癌。
剩余參數(shù)
當(dāng)實(shí)參個(gè)數(shù)大于形參個(gè)數(shù)時(shí),有沒(méi)有可以比arguments更好的記載“超出部分”的參數(shù)呢役听?答案就是ES6標(biāo)準(zhǔn)中的剩余參數(shù)(rest parameter)颓鲜,它允許長(zhǎng)度不確定的實(shí)參表示為一個(gè)數(shù)組。
function(x, y, ...paraArr) {
// ...
}
如果一個(gè)函數(shù)的最后一個(gè)形參是以 ... 為前綴的典予,則在函數(shù)被調(diào)用時(shí),該形參會(huì)成為一個(gè)數(shù)組,數(shù)組中的元素都是傳遞給該函數(shù)的多出來(lái)的實(shí)參的值灾杰。舉個(gè)例子說(shuō)明:
function foo(x,y,...z){
return z;
}
foo(1,2,3,4,5); // [3,4,5] x和y后面的實(shí)參會(huì)被加載到paraArr中去
與arguments不同的是,剩余參數(shù)是Array對(duì)象的一個(gè)實(shí)例熙参,它可以使用數(shù)組的一般操作方法艳吠。
默認(rèn)參數(shù)值
在JS中,函數(shù)的參數(shù)默認(rèn)都是undefined孽椰,但是昭娩,現(xiàn)在我們可能可以賦予它一個(gè)默認(rèn)值,這使得我們的函數(shù)變得更加生動(dòng)黍匾。那么栏渺,什么是默認(rèn)參數(shù)值?
function foo(x,y="y"){
console.log(x,y);
}
foo(); // undefined "y"
foo(1); // 1 "y"
foo(1,2); // 1 2
默認(rèn)參數(shù)值的引入锐涯,允許我們?cè)诤瘮?shù)聲明或函數(shù)表達(dá)式中對(duì)形參賦予一個(gè)默認(rèn)值磕诊,當(dāng)我們調(diào)用函數(shù)但沒(méi)有給出對(duì)應(yīng)實(shí)參時(shí),該形參就會(huì)以這個(gè)默認(rèn)值為對(duì)應(yīng)的實(shí)參纹腌。
function foo(x,y="y"){
console.log(x,y);
}
foo(1); // 1 "y"
foo(1,undefined); // 1 "y"
/* 作用過(guò)程如下
{
var x,y; // 預(yù)解析霎终,x和y均為undefined
// 默認(rèn)參數(shù)值的作用過(guò)程
x = x的實(shí)參 || x的default value; // x = 1
y = y的實(shí)參 || y的default value; // y = "y"
}
*/
在函數(shù)被調(diào)用時(shí),參數(shù)默認(rèn)值會(huì)被解析升薯,所以不像Python中的例子莱褒,每次函數(shù)調(diào)用時(shí)都會(huì)創(chuàng)建一個(gè)新的參數(shù)對(duì)象。
function append(value, array = []){
array.push(value);
return array;
}
append(1); // [1]
append(2); // [2], not [1, 2]
這個(gè)規(guī)則對(duì)于函數(shù)和變量也是適用的涎劈。
function callSomething(thing = something()) { return thing }
function something(){
return "sth";
}
callSomething(); //sth
已經(jīng)被聲明的參數(shù)對(duì)于后面的默認(rèn)參數(shù)是可見(jiàn)的广凸。
function seePrev(x, y = x+"s", z = y + " hello!!!") {
return [x, y, z ];
}
seePrev("me"); //["me","mes", "mes hello!!!"]
seePrev("girl","girles"); //["girl","girles", "girles hello!!!"]
只是玩一下
默認(rèn)參數(shù)值和剩余參數(shù)目前還沒(méi)有得到廣泛支持,謹(jǐn)慎使用蛛枚,玩玩即可谅海。