参数变戏法是不可能的,因为当传递undefined时arguments.length也会增加

时间:2018-10-08 13:12:21

标签: javascript

我有一个具有以下签名 s 的缩放功能:

scale (xy, cx = 0, cy = 0)
scale (x, y, cx = 0, cy = 0)

我的函数定义如下:

function scale (x, y = x, cx = 0, cy = 0)

为确保大小写scale (xy, cx = 0, cy = 0)正常工作,我需要对参数进行弄乱。我曾经那样做:

if (arguments.length == 3) {
  // juggle
}

但是,当此功能与仅中继其参数的另一个功能一起使用时,则会出现问题:

function scaleFoo(x, y, cx, cy) {
    return scale (x, y, cx, cy)
}

scaleFoo不在乎其参数是否有效。它只是中继一切。 但是在那种情况下,arguments.length总是4。即使cyundefined

我知道我可以使用scale.call来解决此问题,但在这种情况下,我需要通过this,我确实想避免。我更喜欢使用更好的if分支的解决方案。

2 个答案:

答案 0 :(得分:1)

function scaleFoo(x, y, cx, cy) {
    return scale (x, y, cx, cy)
}

按名称传递参数时,将得到这样的包装器函数,如果使用三个参数调用包装器之一,则将传递undefined。例如,scaleFoo(1, 2, 3)将导致它随后调用scale(1, 2, 3, undefined)

您也可以添加逻辑以检查包装函数中的参数,但不能很好地缩放(无双关)。想象一下原始函数然后需要处理多达五个参数。您将需要再次在包装器中包含参数计数逻辑。

您可以采用的另一种方法是检查每个参数是否为undefined,但是很多时候也不可行,例如,如果这确实是一个有效值。

相反,您可以简单地使用Function#apply将整个参数对象从包装器传递到原始函数:

function scale (x, y = x, cx = 0, cy = 0) {
  console.log("Number of arguments passed: ", arguments.length);
  console.log("x", x, "y", y, "cx",  cx, "cy", cy);
}

function scaleFoo(x, y, cx, cy) {
    return scale.apply(this, arguments);
}

scaleFoo(1);
scaleFoo(1, 2);
scaleFoo(1, 2, 3);
scaleFoo(1, 2, 3, 4);

没有其他真正好的方法可以包装函数,并且仍然可以对数量不同的传入值进行操作,而无需通过arguments或其ES6替换{{3 }}。

答案 1 :(得分:0)

我想告诉你一些方法

function scaleFoo(x, y, cx, cy) {
  // Here arguments.length will be 3. and cy will be `undefined`
  // Therefore whenever you will call scale function it will four arguments
    return scale (x, y, cx, cy)
}

您可以这样做

function scaleFoo(x, y, cx, cy) {
    if (arguments.length === 3)
        return scale (x, y, cx)
    else
        return scale (x, y, cx, cy)
}

但是,如果您像这样通过代码传递undefined会更好,

scale(x, void 0, cx, cy)
// void 0 == undefined

并且在您的标度函数条件下应该是

function scale(x, y, cx, cy) {
    if (y === void 0) {}
}