[译]JavaScript中的剩余参数和默认参数

原文:http://blog.mozilla.org/jorendorff/2012/05/29/rest-arguments-and-default-arguments-in-javascript/


在过去的两周,Benjamin Peterson在SpiderMonkey中实现了两个ES6新特性.如果你经常写JS的话,一定会喜欢这两个特性.

剩余参数(Rest arguments)是我们熟悉的arguments对象的很好的替代品.语法如下:

function f(arg1, arg2, ...rest) {
    alert("你传入了" + rest.length + "个额外的参数.");
}

这非常类似于Python, Lisp, 以及Ruby中的剩余参数.在每次调用函数f的时候,前几个形参都会按照顺序被赋上对应的实参值,在这个例子中就是arg1和arg2.其他多出来的实参就会存储在数组rest中.如果没有传入多余的实参,rest就是一个空数组.

arguments对象不同的是,一个剩余参数是一个真实的数组,也就是说可以使用所有的数组方法,包括.shift(), .forEach(), .map()等.还有一个很重要的差别是,arguments对象在每一级的嵌套函数中都会被重新定义,不管你需要不需要,而剩余参数不会,就和普通变量一样,可以在闭包中通过作用域链访问到上层函数的剩余参数.

默认参数(Default arguments)是这样的:

function fade(element, seconds=0.5, targetOpacity=0) {
    $(element).animate({opacity: targetOpacity}, seconds * 1000);
}

当你调用这个函数的时候,如果你没有给某个拥有默认值的形参传值,则这些形参会自动被赋上默认值.

fade(form, 0.2, 1);  // 没有使用默认值:
                     // 快速淡入
fade(form, 3);       // targetOpacity设置为默认值0:
                     // 缓慢淡出
fade(form);          // seconds设置为默认值0.5,
                     // targetOpacity设置为默认值0:
                     // 正常速度淡出

默认值可以是任意的表达式,甚至还可以使用到前面的形参,比如:

function logEvent(event, logger=findLoggerFor(event.target)) {
    ...
}

logger的默认值依赖于event参数.

(默认参数的一些技术细节:和Python不同的是,在函数每次被调用时,这个默认参数的值都会被重新计算,也就是说,如果一个参数的默认值被设置为=[]的话,该参数的值每次都会是一个新的数组.另外一个需要注意的是,目前的提案规定如下,仅在调用者省略一个实参的情况下,对应的形参才会取默认值.如果调用者显式的传一个undefined值给形参,则该形参的值就是undefined,而不会去取默认值.不过现在TC39正在讨论,看要不要改成,即使在调用者显式传入undefined的情况下也让形参取默认值.虽然其他语言没有这么干的,但在用JavaScript操作DOM的使用中,很多情况下都适合这么干.现在SpiderMonkey是依据当前的提案来实现的,一旦提案有改变,我们会更新我们的实现.)

译者注:读者也许不理解和python比较的这几句话,如果你想知道的话:

在python中,拥有默认参数值的参数有时并不像是在JavaScript中的局部变量一样每次都重新求值.看个例子:

>>> def spam(eggs=[]): 
...     eggs.append("spam")
...     return eggs
... 
>>> spam()
['spam']
>>> spam()
['spam', 'spam']
>>> spam()
['spam', 'spam', 'spam']
>>> spam()
['spam', 'spam', 'spam', 'spam']

这两个新特性都有望成为ES6标准的一部分.Benjamin依然干劲十足,他会给我们带来更多新东西.

译者注:Benjamin Peterson是一个今年刚刚进入Mozilla的实习生,他的另一项壮举是删除了由Brendan Eich最初编写,在SpiderMonkey中用了17年的反编译器.

posted @ 2012-11-26 22:30  紫云飞  阅读(6432)  评论(0编辑  收藏  举报