使用无限可选参数

时间:2017-07-09 22:06:23

标签: javascript ecmascript-6

我正在尝试创建一个自定义记录器,它只包装console.log但总是在开头添加一些内容,这使得日志绝对清楚地来自我的插件。

我提出了以下代码:

var log = function(param1, param2) {
    if (typeof param3 !== 'undefined') {
        console.log('[MyPlugin]', param1, param2, param3);
    } else if (typeof param2 !== 'undefined') {
        console.log('[MyPlugin]', param1, param2);
    }
};

这允许开发人员运行以下命令:

log('foo', 'bar');
// Outputs '[MyPlugin] foo bar'

log('foo');
// Outputs '[MyPlugin] foo'

但我希望这可以改进。

此实施的问题是:

  1. 日志记录功能仅允许两个参数。如果它可以接受很多会更好。
  2. 有很多重复(多个console.log来电)。
  3. 我尝试了什么。

    我想也许ES6 spread-operator会起作用:

    var log = function(...params) {
        console.log('[MyPlugin]', params);
    };
    

    允许开发人员运行:

    log('foo', 'bar');
    // Outputs '[MyPlugin] Array [ "foo", "bar" ]'
    
    log('foo');
    // Outputs '[MyPlugin] Array [ "foo" ]'
    

    您可以看到输出与原始功能中的输出不同。

    有更好的解决方案吗?

1 个答案:

答案 0 :(得分:11)

传播符号(它不是运营商)确实会这样做,如果你使用它。您正在使用rest notation(将参数收集到数组参数中),但不使用扩展符号(在将它们传递给console.log时将它们展开)。这是你如何使用传播:

var log = function(...params) {
// Rest -----------^^^
    console.log('[MyPlugin]', ...params);
    // Spread ----------------^^^
};

示例:

var log = function(...params) {
// Rest -----------^^^
    console.log('[MyPlugin]', ...params);
    // Spread ---------------^^^
};

log("testing", 1, 2, 3);

如果您需要在不进行转换的情况下支持ES2015之前的环境,您可以使用argumentsFunction#apply执行相同操作:

var log = function() {
    var args = Array.prototype.slice.call(arguments);
    args.unshift('[MyPlugin]');
    console.log.apply(console, args);
};

直播示例:

var log = function() {
    var args = Array.prototype.slice.call(arguments);
    args.unshift('[MyPlugin]');
    console.log.apply(console, args);
};

log("testing", 1, 2, 3);