【问题标题】:Prepend argument to arguments then apply将参数添加到参数然后应用
【发布时间】:2014-06-09 14:32:08
【问题描述】:

我有一个函数,message,它接受一个参数来定义消息的类型,然后它加入任何其他参数来形成消息,这纯粹是一种技巧。

看起来像这样:

function message(type) {
    var msg = _.rest(arguments).join(" ");

    // Really the type will be used to set the class on a div
    // But I'm just using console.log to keep it simple for now.
    console.log(type + ": " + msg);
}

我想提供辅助函数error、warning、info,它们只需使用正确的类型调用message。我只是不确定解决此问题的最佳方法。我想不出两种方法,但我不确定我是否正确地处理它,或者我可能过于复杂了。

第一种方式似乎有点多余,创建一个包含第一个 arg 和参数的新数组,然后将其展平。

message.apply(this, _.flatten(["error", arguments]));

第二种方式感觉有点……乱?

Array.prototype.unshift.call(arguments, "error");
message.apply(this, arguments);

虽然根据我的经验:

(function() {
    Array.prototype.unshift.call(arguments, 0);
    console,log(arguments);
})(1, 2, 3);

我得到以下输出:

[0, 1, 2, 3, undefined, undefined, undefined, ..., undefined]

【问题讨论】:

    标签: javascript arguments call apply


    【解决方案1】:
    var args = Array.prototype.slice.call(arguments); // Make real array from arguments
    args.unshift("error");
    message.apply(this, args);
    

    见How can I convert the "arguments" object to an array in JavaScript?

    【讨论】:

    • 应该使用 .call 让它在任何地方都能工作 var args = Array.prototype.slice.call(arguments);
    【解决方案2】:

    在 ES5 中,这可能比先转换为真正的数组然后unshift 更有效:

    var args = Array.prototype.concat.apply(["error"], arguments);
    message.apply(this, args);
    

    编辑:最好避免扁平化输入数组:

    var args = ["error"];
    args.push.apply(args, arguments);
    message.apply(this, args);
    

    【讨论】:

    • 小心使用它,好像arguments 的元素是数组,它们将被“展平”到数组中,而不是作为元素本身添加。例如var args = Array.prototype.concat.apply(["error"], ["apple", "banana", ["carrot", "cherry"]]) 错误地变为 args = ["error", "apple", "banana", "carrot", "cherry"]。
    猜你喜欢
    • 2020-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-22
    • 2011-11-30
    • 1970-01-01
    • 1970-01-01
    • 2021-08-09
    相关资源
    最近更新 更多