1

我正在尝试编写一个基于先前指定的可选参数更正 a 的arguments函数function。我遇到了一个问题。似乎我不能通过arguments数组设置变量,除非它们以前以任何方式定义过。下面的代码显示了我面临的问题的一个示例。

function foo(a, b, c) {
    arguments[0] = "lorem";
    arguments[1] = "ipsum";
    arguments[2] = "dolor";

    console.log([a, b, c]);
}

foo(null);              // ["lorem", undefined, undefined]
foo(null, null);        // ["lorem", "ipsum",   undefined]
foo(null, null, null);  // ["lorem", "ipsum",   "dolor"]

记录arguments结果时总是["lorem", "ipsum", "dolor"]如此。
有没有办法解决这个问题?

我不能直接设置a,因为调用的函数b无法访问这些名称。 我的目标看起来像这样:cfoo

function foo(a, b, c) {
    var rules = [];
    // Rule for optional parameter 1 (b)
    // If it equals true the value of b is shifted to the next parameter (c)
    rules[1] = function(val) { return val !== "ipsum"; };
    optionalize(rules);

    console.log([a, b, c]);
}

foo("lorem", "dolor"); // ["lorem", undefined, "dolor"];
4

4 回答 4

2

数组并不是真正的arguments数组,而是“类数组”对象。你不能改变它的长度。

您尝试做的通常是使用

a = a || "lorem";

或者,如果您不想替换任何“虚假”参数,请使用

if (typeof a === "undefined") a = "lorem";
于 2012-12-30T15:22:28.100 回答
0

我不确定您要做什么,但是诸如 arguments[0] = a 之类的东西?一个:“lorem”等等?

于 2012-12-30T15:26:08.640 回答
0

您可以将参数转换为数组

function foo () {
     var arguments = Array.prototype.slice.call(arguments);
     arguments.push(4);
     console.log(arguments);
}
foo(1,2,3);

​</p>

于 2012-12-30T16:18:16.247 回答
0

这有点奇怪,但这是你的想法吗?

function optionalize(fn, options) {
    var i, key, rule;
    for(i = 0; i < options.length; i += 1) {
        key = fn.placement[i];
        rule = fn.ruleset[key];

        // If the rule exists and returns true, shift value to the right.
        if(rule && rule(options[i])) {
            options[i+1] = options[i];
            options[i] = undefined;
        }

        // Assign the numeric index to an alphabet key.
        // Depending on your use case, you may want to substitute a plain Object here and return that, instead of adding non-numeric properties to an Array.
        options[key] = options[i];
    }
}

// Test function
function foo(a, opts) {
    opts = opts || [];
    optionalize(foo, opts);

    console.log([a, opts.b, opts.c]);
}

// Optional argument names, in the order that they would be received.
foo.placement = ['b', 'c'];

// Optionalize rules
foo.ruleset = {
    b: function (val) { return val !== "ipsum"; }
};


// Demonstration
foo('lorem');
foo('lorem', []);
foo('lorem', ['dolor']);
foo('lorem', ['ipsum', 'dolor']);

正如dystroy的答案已经表明的那样,该arguments变量不是真正的数组,更改它可能不是一个好主意。我提供了一个不依赖arguments并尽可能使用简单 JavaScript 满足标准的解决方案。

该函数foo由一个必需参数指定a,后跟一个名为 的可选参数数组opts。一个 optionalize 规范被设置到foo, 通过placementruleset属性。optionalize 函数获取此信息并将数组的索引转换为可用的名称键,并根据需要应用规则。

于 2012-12-30T17:00:39.873 回答