默认参数和不定参数_ES6笔记4

一.作用

默认参数和不定参数的目标是完全取代arguments对象

严格模式('use strict';)对arguments做了一些限制,如下:

  • eval和arguments不能通过程序语法被绑定(be bound)或赋值

  • 参数的值不会随arguments对象的值的改变而变化,反之亦然

  • 不再支持arguments.callee

(摘自严格模式 – JavaScript | MDN

前两条都是对arguments对象的不满,但因为arguments对象是实现可变参函数的关键方法(当然,也可以用Object/Array类型参数模拟,但不如arguments方便灵活),还得继续支持,所以希望通过严格模式(补丁)来限制arguments对象

而第三条表示黑科技被封印了,arguments现在名副其实了(只和参数打交道)

ES6(新版本)在严格模式的基础上更进一步,希望大家慢慢忘掉arguments对象,而不定参数就是替代方案,还有锦上添花的默认参数

二.不定参数

...arg语法带来了更好的语义(表示不定参数)

不定参数提供了可变参函数(可以接受任意多个参数的函数)的另一种实现方式(不需要arguments对象),特点如下:

  • 可读性更好,从参数列表就可以看出该函数是可变参函数,而且解决了参数索引(arguments[0])的问题

  • 不定参数必须在参数列表末尾,没有额外参数时值为[],而不是undefined

例如:

function containsAny(s, ...aSubStr) {
    for (var subStr of aSubStr) {
        if (s.indexOf(subStr) !== -1) {
            return true;
        }
    }

    return false;
}
// test
console.log(containsAny('ECMAScript 6', 'es'));         // false
console.log(containsAny('ECMAScript 6', 'es', '6'));    // true

不定参数带来的便利是参数操作更容易了,不再需要这样的步骤:

var fn = function(a, b) {
    var args = Array.prototype.slice.call(arguments);
    // 切掉命名参数a和b
    var others = args.slice(2);
    // ...
}

三.默认参数

arg=defaultVal语法表示默认参数,与其它语言一样。特点如下:

  • defaultVal可以是任意合法表达式,所以可以根据左边的参数生成当前参数的默认值

  • undefined相当于占位符,仍然使用默认值,而不是传入的undefined

  • 标准规定在使用不定参数或默认参数的函数中禁止使用arguments对象,但Chrome49,FF45和thinkjs都没有实现此限制

例如:

function error(type = 'Undefined') {
    console.log(`${type} error occurs`);
}
// test
error();            // Undefined error occurs
error('Script');    // Script error occurs

// 动态生成默认值与传入undefined
function hoho(name, sex, words = sex === 'F' ? 'Hi Girl' : 'Hello boy') {
    console.log(`${words}, you are ${name}`);
}
hoho('Sam', 'M');   // Hello boy, you are Sam
hoho('Lis', 'F');   // Hi Girl, you are Lis
hoho('Mee', 'F', undefined);    // Hi Girl, you are Mee

// arguments对象
function fun(arg = 'defaultVal', ...aOther) {
    var args = Array.prototype.slice.call(arguments);
    console.log(args.length);
}
fun(1, 2, 3);   // 3

算是锦上添花的小东西,避免了以前需要借助注释繁琐写法:

/**
 * [fn description]
 * @param  {[type]}   a [description]
 * @param  {[type]}   b 可选,默认值为{},表示xxx
 * @return {Function}   [description]
 */
var fn = function(a, b) {
    b = b || {};    // 设置b的默认值为{}
}

这种老方法既麻烦又容易出错(b可以为0或者false时更麻烦),有了默认参数就不需要多余的注释了,除非默认值生成方式很复杂,需通过注释额外说明

四.总结

本篇内容非常少,主要是代码可读性上的提升,2点:

  • 设置默认参数更方便了,语法就是默认语法

  • 可变参函数有了更合理的实现方法,不再依赖arguments对象了

参考资料

  • 《ES6 in Depth》:InfoQ中文站提供的免费电子书

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*

code