2

想检查传递给函数的参数并替换未指定的参数或“我不喜欢”的参数。为此,我做了以下事情(我想使用的原因arguments是我想要一个通用函数)(与 node.js 的结果相同,只需将 Logger 更改为控制台):

function argtest (x,y,z) {
  Logger.log ("at begin x="+x+", y="+y+", z="+z);
  arguments.length=3; // found this somewhere, doesn't help
  arguments[0]="a";
  arguments[1]="b";
  arguments[2]="c";
  Logger.log ("arguments now:");
  for (var i in arguments) {
    Logger.log ("arguments["+i+"]="+arguments[i]);
  }
  Logger.log ("at end x="+x+", y="+y+", z="+z);
}
function callArgTest () {
  argtest ();
  argtest (1,2,3);
}

所以调用的结果callArgTest是:

Logger.log([at begin x=undefined, y=undefined, z=undefined, []])
Logger.log([arguments now:, []])
Logger.log([arguments[0]=a, []])
Logger.log([arguments[1]=b, []])
Logger.log([arguments[2]=c, []])
Logger.log([at end x=undefined, y=undefined, z=undefined, []])
Logger.log([at begin x=1, y=2, z=3, []])
Logger.log([arguments now:, []])
Logger.log([arguments[0]=a, []])
Logger.log([arguments[1]=b, []])
Logger.log([arguments[2]=c, []])
Logger.log([at end x=a, y=b, z=c, []])

因此,参数 x,y,z 仅在最初指定时发生变化。在第一种情况下(argtest不带参数调用),即使在为参数赋值之后,它们仍然是未定义的。那么这里缺少什么使它起作用呢?请注意,我不想触摸 x,y,z。相反,在最终实现中,我想将参数传递给对它们起作用的函数。

4

3 回答 3

1

问题是,在调用 时argtest()arguments实际上并没有"0"要引用的属性x,或者"1"fory等:

argtest()      => arguments = { "length": 0 }
argtest(1,2,3) => arguments = { "length": 3, "0": x, "1": y, "2": z }

该引用的定义在ES5 10.611.c的步骤中进行了描述,该步骤为 的每个“索引”定义了 getter 和 setter ,但受到命名参数的数量和传递的参数数量的限制。arguments

关于您的意图:

我想在函数的开头加入一个现有的实现,调用一个函数,该函数只接受参数和一些默认值作为参数,例如defaults (arguments, "string=nana", "number=4")

你可能会发现这样的事情更容易:

function argTest(x, y, z) {
    x = typeof x !== 'undefined' ? x : ...;
    y = typeof y !== 'undefined' ? y : ...;
    // etc.
}

ES5 可以实现您想要做的事情,但这意味着使用 getter 和 setter 为每个“索引”和命名参数定义您自己的“参数”对象,无论是否通过Object.create/Object.definePropertiesget/传递值set- 而且,我会不要“简单地”考虑这个:

function argtest(x, y, z) {
    defaults({
        length: argtest.length,

        get '0'() { return x; },
        set '0'(val) { x = val; },

        get '1'() { return y; },
        set '1'(val) { y = val; },

        get '2'() { return z; },
        set '2'(val) { z = val; }
    }, ...);

    // ...
}
于 2013-01-02T23:30:54.200 回答
0

arguments[0]="a";
arguments[1]="b";
arguments[2]="c";

为什么不添加

x = arguments[0];
y = arguments[1];
z = arguments[2];

? 我想这不符合你的目标是有原因的,但我想我需要一个更现实的例子来看看什么真正能满足你的目标。

于 2013-01-02T20:45:07.843 回答
0

也许你可以做这样的事情:

var args = Array.prototype.slice.call(arguments);

然后与args? 您可以根据需要传递args到其他功能。让我知道这是否对您有所帮助,或者我是否在吠叫错误的树。

于 2013-01-02T23:21:39.073 回答