在JavaScript中调用具有可变数量参数的函数(类似于call())

时间:2013-12-19 19:24:28

标签: javascript

我熟悉call()的方式,您可以传递可变数量的参数,这些参数在被调用时将被加载到函数的参数中。我正在尝试做一些相关的事情,我通过forEach(类似于jQuery的each)在RaphaelJS中通过嵌套集对象进行递归,确定子元素是否是另一个集合,并应用带变量的函数如果没有参数的数量。我想使它成为通用的,以便我可以应用任何函数,但使我传递的函数具有简单的参数构造函数,而无需访问函数的arguments属性。

function recursiveFncApply(set, fnc, args) {
    set.forEach(function(item) {
        if (item.type == 'set') {
            recurseApplyFncToSets(item, fnc, args);
        } else {
            fnc(item, args);
        }
    });
}

function translateOperation(element, operation, x, y)
    // do stuff to element with operation, x, and y args without accessing
    // accessing arguments property
}

recursiveFncApply(passedSet, translateOperation, [arg1, [arg2, ...]]);

我想这样做,这样我就可以使用多个函数,而不必重复使用确定参数的代码并在使用前正确分配它们。我不确定是否有某些功能或语言实用程序,我缺少这些功能或语言实用程序可以使我这样做,或者以某种方式以编程方式从传递给recursiveFncApply的其余参数“构造”函数调用。这在JavaScript中是否可行?

澄清:我想将可变数量的参数传递给我的递归函数,该递归函数将传递给我想要应用于我的递归函数正在处理的集合的内容的任何函数。所以我希望能够使recursiveFncApply与任何函数一起工作,同时仍然使用一个与通过call()执行的函数类似的参数结构。

除了translateOperation之外,我还有其他功能:

function anotherFunction(element, differentArg) {
    // do something with one argument
}

理想情况下,我可以这样使用我的recursiveFncApply

recursiveFncApply(passedSet, translateOperation, operation, x, y);
recursiveFncApply(passedSet, anotherFunction, singleArg);

以这种方式:

recursiveFncApply(passedSet, anotherFunction, singleArg);

我认为这与我call()的工作方式类似:

anotherFunction.call(this, element, differentArg);

..无需更改anotherFunction的结构来整理arguments属性,或传递对象/数组。

2 个答案:

答案 0 :(得分:0)

事实证明,菲利克斯金有正确的想法/是最接近的。一旦我意识到我实际上正在尝试做什么,我就找到了对我的问题的直接答案,这是从函数到函数的传递参数(找到答案here)。所以我得到了这个代码:

function recursiveSetFncApply(set, fnc/*, variable */) {
    var me = this;
    var parentArgs = arguments;
    set.forEach(function(element) {
        if (element.type == 'set') {
            parentArgs[0] = element;
            me._recursiveSetFncApply.apply(me, parentArgs);
        } else {
            // Generate args from optional arguments and pass forward; put element in args at front
            var args = Array.prototype.slice.call(parentArgs, 2);
            args.unshift(element);
            fnc.apply(element, args);
        }
    });
}

我使用arguments引用parentArgs,因为我需要更新set中的arguments属性,然后再将其传递到下一个递归循环,否则我遇到无限循环,因为它根本没有更新,因为它使用的是原始参数集。我的印象是apply()实际上不会传递参数,而只是将数组弹出到您必须通过索引访问的新函数中 - 事实并非如此。当我在apply()上使用translateElementOperation时,我在他们确切的位置获得了我需要的所有参数。这是我通过递归应用运行的更新函数:

function translateElementOperation(element, operation, x, y) {
    var currentPath = element.attr('path');
    translatedPath  = Raphael.transformPath(currentPath, [operation, x, y]);
    element.attr('path', translatedPath);
}

感谢大家的帮助!

答案 1 :(得分:0)

使用.apply代替.call

functionName.apply(element, [any, number, of, variables, ...]);

// instead of this
functionName.apply(element, set, of, variables, ...);

这样更有用:

var fnVars = [];// fill this anyway you want.

functionName.apply(element, fnVars);