JS的“论点”特殊性让​​我感到非常困惑

时间:2015-08-21 01:25:33

标签: javascript

我有这个电话:

function del(Model, modelName, model_id, req, res, next, cb) {

    if(req.query.optimisticDelete){
        optimisticDelete(arguments);
    }
    else{
        pessimisticDelete(arguments);
    }
}

问题当然是,参数没有正确传递给optimisticDelete和pessimisticDelete函数。

在理想的JS世界中,这可能有用,但我很容易理解为什么它没有。

但它并没有消除这个事实,我只是不想为每个调用输入所有参数,事实上我也想省略del函数签名中的参数,所以这将是最理想的情况,虽然我需要一个对req对象的引用,我现在不知道了:

  function del() {

        if(req.query.optimisticDelete){
            optimisticDelete(arguments);
        }
        else{
            pessimisticDelete(arguments);
        }
    }

但当然,当传递参数时,它似乎不会神奇地分离成单独的参数。

而且,这也不起作用:

function del(Model, modelName, model_id, req, res, next, cb) {

    if(req.query.optimisticDelete){
        optimisticDelete(Array.prototype.slice.call(arguments));
    }
    else{
        pessimisticDelete(Array.prototype.slice.call(arguments));
    }
}

如果您了解我要做的事情,请告诉我是否可能以及如何,

2 个答案:

答案 0 :(得分:6)

您正在使用单个参数调用optimisticDelete,该参数是arguments特殊对象,其中包含原始调用的所有参数。如果要将它们展开,则需要使用apply:

optimisticDelete.apply(null, arguments);

没有必要先将arguments转换为数组。 MDN说:

  

您还可以使用arguments作为argsArray参数。 arguments是函数的局部变量。它可以用于被调用对象的所有未指定的参数。因此,在使用apply方法时,您不必知道被调用对象的参数。您可以使用arguments将所有参数传递给被调用对象。

答案 1 :(得分:5)

有两个问题。首先,arguments对象很奇怪,但它不是那个很奇怪。在一个简单的函数调用中,没有什么可以神奇地变成参数列表。但是,有Function.prototype.apply,这最终是你想要的。

首先,您需要将arguments转换为普通数组:

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

或者,如果您关心运行时效率:

var plainArgs = [];
for (var i = 0; i < arguments.length; ++i)
  plainArgs[i] = arguments[i];

注意 - 这个步骤可能没有必要,但是将arguments对象从函数中传出会使优化器抛弃他们的小手并放弃你的功能。)

另一个注释 - 完全忽略了将arguments传递给.apply()的问题。我错了。)

完成此操作后,您可以使用.apply()

    optimisticDelete.apply(null, plainArgs);

.apply()函数期望其第二个参数是一个数组。该数组成为函数的各个参数。 .apply()的第一个参数是您希望this在函数调用中使用的值;因为你在原始代码中打电话给optimisticDelete()“裸”,所以我通过null,但你可以通过你想要的任何东西。