代码之家  ›  专栏  ›  技术社区  ›  ScottS

将参数和默认值动态绑定到Javascript中的现有函数

  •  4
  • ScottS  · 技术社区  · 14 年前

    假设你有一些功能 已经在javascript中定义,可以定义也可以不定义自己的参数集。是否可以编写另一个函数来添加所需的参数并将该参数设置为的默认值 ? 比如:

    var someFunc = function(arg1, arg2 ...){ Do stuff...}
    var addRequired = function(argName, argValue, fn) { 
        Add the required default arg to a function...
    }
    
    addRequired("x", 20, someFunc);
    

    someFunc = function(x, arg1, arg2...) {
        x = 20;
        Do stuff...
    }
    

    我真正想要的是 一个函数的值(我已经知道如何实现),但也会将另一个对象引用绑定到同一个函数(该函数不是预先知道的,因为用户会定义它,但是用户的代码可以访问第二个对象引用,以便在自己的函数中使用)。所以在我上面的简单示例中,“20”值实际上是一个对象引用。

    谢谢你的帮助。

    2 回复  |  直到 14 年前
        1
  •  5
  •   SLaks    14 年前

    这样地:

    function addParameter(func, argIndex, argValue) {
        return function() {
            arguments[argIndex] = argValue;
            arguments.length = Math.max(arguments.length, argIndex);
            return func.apply(this, arguments);
        };
    }
    
    someFunc = function(x, arg1, arg2...) {
        Do stuff...
    }
    someFunc = addParameter(someFunc, 0, someValue);
    
        2
  •  1
  •   ScottS    14 年前

    var someFunc = function(arg1,arg2){document.write(x+'<br />'+arg1+'<br />'+arg2)};
    
    var addRequired = function(argName, argValue, fn){
        var funcString = String(fn)
        var paramPattern = new RegExp ('^function\\s*\\([^\\)]*\\b'+argName+'\\b[^\\)]*\\)');
        var alreadyExists= paramPattern.test(funcString);
        if(!alreadyExists) {
           var insertPoint1 = funcString.indexOf('(')+1;
           var insertPoint2 = funcString.indexOf('{')+1;
           var newFunc = funcString.slice(0,insertPoint1)+argName+',' +funcString.slice(insertPoint1, insertPoint2)+argName+' = '+argValue+';' +funcString.slice(insertPoint2);
           return eval('fn = '+newFunc);
        }
    }
    someFunc = addRequired('x', 20, someFunc);
    
    someFunc(1,2,3);
    

    测试arg是否已经存在,如果不存在,则输出:

    20
    2
    3
    

    因此它实现了一个参数与期望值的相加。我不知道这是否是实现它的“最佳”方式,但它起了作用。

    编辑7/9/10添加此信息:

    当我把上面的例子应用到不同的情况时,我发现上面有一个bug(我现在不记得bug是什么了,那是几周前的事了)。我想出了一些有用的办法。注意,下面没有做任何类型的检查来查看传入的函数的参数是否已经存在,事实上,当前它需要一个本身不带参数的函数(我确信这可以重写以容纳带参数的函数,类似于我上面所做的)。以下是我实际使用的简单布局:

    var addRequired = function(thisObj, func) {
        /*Here I write a string that contains additional functions to add to the 
          passed in function ('func' argument above). In this case, I just show 
          a simple addition function for the example.*/
    
        var str = 'myAddedFunction = function(x, y) {return x+y}';
    
        /*Here I am taking the string for that new function I want to add, and 
          appending the old function to it as a string after I have stripped it 
          of its 'function () {' at the beginning and its '}' at the end. NOTE: 
          If I did not care about adding a function, but just arguments, I would 
          have just assigned 'str' the value after the '+' sign below */
    
        str = str + String(func).replace(/^function\s*\([^\)]*\)[\s\n]*{/, '  ').replace(/}$/, '');
    
        /*Here I create a new function using the actual new Function declaration so
          I can define my arguments, and using the new string I created that has 
          my new functionality in it along with the user supplied functionality*/
    
        var newFunc = new Function('myArg1', 'myArg2', str);
    
        /*Now I return an anonymous function that itself returns the new function 
          with the object that is supposed to be the 'this' of the new function 
          which was passed in as the 'thisObj' argument*/
    
        return function() {return newFunc.apply(thisObj, arguments)};
    }
    

    var userFunc = function() { *do some stuff* }; //representation only
    userFunc = addRequired(someObj, userFunc); //overwrite with new functionality
    

    这允许我做的是让用户编写一个函数,提前知道他们将可以访问我提供的函数 myAddedFunction )以及我提供的参数 myArg1 , myArg2 )在他们的职能范围内。这可能看起来非常抽象,比如“为什么我会需要它”,但是对于我正在工作的项目,我(和用户)需要它,因为我利用用户的函数(以及我的添加)根据我提供的参数为用户执行一些操作。

    我忘了提一下,出于我的目的,我不需要把我要添加到新变量中的字符串传入(它总是与我添加的变量相同),但是如果我有,我会像我的文章的第一部分那样,传入字符串(可能是一个数组)以生成参数值,用这些来建造我的房子 newFunc 与。