Skip to main content

Default Parameters and Rest Parameters_ES6 Notes 4

Free2016-04-17#JS#ES6默认参数#ES6不定参数#JS可变参函数#JS设置默认参数

Default parameters and rest parameters were previously implemented through certain tricks, now they are finally "legitimate"

I. Purpose

The goal of default parameters and rest parameters is to completely replace the arguments object.

Strict mode ('use strict';) imposes some restrictions on arguments, as follows:

  • eval and arguments cannot be bound or assigned through program syntax

  • The value of parameters does not change with changes to the arguments object, and vice versa

  • arguments.callee is no longer supported

(Excerpted from Strict mode - JavaScript | MDN)

The first two points express dissatisfaction with the arguments object, but since the arguments object is the key method for implementing variadic functions (of course, Object/Array type parameters can also be used to simulate, but not as convenient and flexible as arguments), it still needs to be supported. Therefore, it is hoped to restrict the arguments object through strict mode (as a patch).

The third point indicates that the black magic technique has been sealed. arguments now lives up to its name (only deals with parameters).

ES6 (the new version) goes one step further based on strict mode, hoping everyone will gradually forget about the arguments object. Rest parameters are the alternative solution, along with the complementary default parameters.

II. Rest Parameters

The ...arg syntax brings better semantics (indicating rest parameters).

Rest parameters provide another way to implement variadic functions (functions that can accept any number of parameters) without needing the arguments object. The characteristics are as follows:

  • Better readability; you can see from the parameter list that the function is variadic, and it solves the parameter indexing problem (arguments[0]).

  • Rest parameters must be at the end of the parameter list. The value is [] when there are no additional parameters, not undefined.

For example:

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

The convenience brought by rest parameters is that parameter operations are easier. Such steps are no longer needed:

var fn = function(a, b) {
    var args = Array.prototype.slice.call(arguments);
    // Cut off named parameters a and b
    var others = args.slice(2);
    // ...
}

III. Default Parameters

The arg=defaultVal syntax represents default parameters, just like in other languages. The characteristics are as follows:

  • defaultVal can be any legal expression, so the default value of the current parameter can be generated based on the parameters on the left.

  • Passing undefined acts as a placeholder; the default value is still used instead of the passed undefined.

  • The standard stipulates that using the arguments object is prohibited in functions that use rest parameters or default parameters, but Chrome 49, FF 45, and thinkjs have not implemented this restriction.

For example:

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

// Dynamically generate default values and pass 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 object
function fun(arg = 'defaultVal', ...aOther) {
    var args = Array.prototype.slice.call(arguments);
    console.log(args.length);
}
fun(1, 2, 3);   // 3

These are nice little additions that avoid the previously cumbersome写法 that required comments:

/**
 * [fn description]
 * @param  {[type]}   a [description]
 * @param  {[type]}   b Optional, default value is {}, represents xxx
 * @return {Function}   [description]
 */
var fn = function(a, b) {
    b = b || {};    // Set b's default value to {}
}

This old method is both troublesome and error-prone (even more troublesome when b can be 0 or false). With default parameters, extra comments are no longer needed, unless the default value generation method is very complex and requires additional explanation through comments.

IV. Summary

This chapter has very little content, mainly improvements in code readability, 2 points:

  • Setting default parameters is more convenient; the syntax is the default syntax.

  • Variadic functions have a more reasonable implementation method, no longer dependent on the arguments object.

References

  • "ES6 in Depth": A free e-book provided by InfoQ Chinese Station

Comments

No comments yet. Be the first to share your thoughts.

Leave a comment