Dynamically bind argument and default to existing function in Javascript

Suppose you have some someFunc () function already defined in javascript, which may or may not have its own set of arguments. Is it possible to write another function to add the required argument and set this argument to the default for someFunc ()? Sort of:

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

Now someFunc will be defined something like this:

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

What I'm really looking for is not only to bind this value to a function (which I already know how to achieve), but also to bind another object reference to the same function (the function is not known in advance how the user will define it, but then user code has access to this second object reference for use in their own function). Therefore, in my simple example above, the value "20" will actually be an object reference.

Thanks for any help you can offer.

+4
source share
2 answers

I believe that I found the answer, although in the process I realized that I really do not need to add an argument for my purpose, I just need to add a link to this function. In any case, for the purpose of the answer, which achieves what I initially thought was necessary, I came up with:

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

What tests check if arg exists, and if not, outputs:

 20 2 3 

Thus, this led to the addition of an argument with the required value. I do not know if this is the "best" way to achieve it, but it worked.

Edited 7/9/10 to add this information:

I found that the above had a β€œmistake” when I went to apply it to a different situation than my example above (I don’t remember what the error was, which was a few weeks ago). I came up with something that worked. NOTE. The following does not do any check to check if an argument already exists for the function passed, and in fact it is currently expecting a function that DOES NOT TAKE THE ARGUMENTS OF ITSELF (I am sure that this could be rewritten to accommodate a function with arguments similar to what I did above). Here is a simple outline of what I actually used:

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

The return value is assigned to the original function passed, therefore:

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

This allows me to write a function, knowing in advance that they will have access to the function that I supply ( myAddedFunction ), as well as to the parameters that I supply ( myArg1 , myArg2 ) within their function. It may seem really abstract, for example, β€œwhy do I need it,” but for the project I'm working on, I (and the user) need it, because I use the user function (with my additions) to perform some operations for the user based on parameters which I supply.

I forgot to mention that for my purposes I did not need to pass the string that I was going to add to the new variables (these are always the same variables that I add), but if I had, I would do something like this, what was done in the first part of my post, where I went through (possibly an array) of strings to add to the argument values, and used them to create my newFunc with.

+1
source

Like this:

 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); 
+4
source

Source: https://habr.com/ru/post/1313103/


All Articles