2010-06-17 77 views
4

假設您已經在javascript中定義了一些函數someFunc(),該函數可能已經定義了自己的參數集,也可能沒有定義它自己的參數集。是否可以編寫另一個函數來添加必需的參數並將該參數設置爲默認值someFunc()?喜歡的東西:將參數和默認值動態綁定到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將一個粗略的定義,像這樣:

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

我所真正需要的是對不僅一個這個值綁定到一個函數(我已經知道如何實現),還綁定了另一個對象引用,該函數不會提前知道,因爲用戶會定義它,但是用戶的代碼可以訪問這個第二個對象引用以供他們自己使用功能)。所以在我上面的簡單示例中,「20」值實際上是一個對象引用。

感謝您提供任何幫助。

+2

* someFunc *應該用這個新參數來做什麼?我不明白你在說什麼。也許更具體的例子會有所幫助。 – Pointy 2010-06-17 19:14:31

回答

1

我相信我找到了答案,但在這個過程中,我才明白,我並不真的需要加一個參數爲我的目的,我只需要添加該函數的參考。總之,對於達到什麼,我本來以爲我想要的答案的目的,我想出了:

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 

因此它實現了所需值的參數的添加。我不知道這是否是實現這一目標的「最佳」方式,但它起了作用。

編輯10年7月9日添加此信息:

我發現上面有一個「錯誤」,當我去將它應用到一個不同的情況比我上面的例子(我不記得現在是什麼錯誤,那是幾個星期前)。我想出了一些有用的東西。請注意,以下內容不會進行任何類型的檢查,以查看傳入的函數是否已存在參數,實際上,它當前期望的函數不取自變量本身(我確信這可以被重寫爲適應函數與參數,類似於我上面做的)。這裏是什麼,我實際使用一個簡單的佈局:

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)以及我提供的參數(myArg1myArg2)。這可能看起來很抽象,比如「爲什麼我會需要它」,但是對於我正在開發的項目,我(和用戶)需要它,因爲我利用用戶的函數(通過添加)來執行一些操作用戶基於我提供的參數。

我忘了提及,爲了我的目的,我不需要將要創建的字符串傳遞給新的變量(它總是與我添加的變量相同),但如果我有,我會做類似於我的文章的第一部分所做的事情,我在其中傳入(可能是數組)字符串以形成參數值,並使用它們來構建我的newFunc

4

像這樣:

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);