0

I have searched and found numerous discussions on this but none of the solutions seem to work.

Scenario: I have a central script which processes a complex calculator. This calculator has over a 1000 separate calculators, each of which is called via a function.

Each of those functions is loaded dynamically based on user selection (keep overhead down etc...)

So, core script is similar to this:

var m1 = 5;
var m2 = 8;


dynamicfunction1();
dynamicfunction2();

var m3 = m1 + m2;

The dynamic functions can change the values of m1 for example, depending on criteria (I'm keeping the example short).

So, I want to first check if the function exists before I run it, if not, ignore it.

So, I intended to have:

FncChk("dynamicfunction1");
FncChk("dynamicfunction2");

Below is an example where I have created one function, but tried to test 2 (clearly 1 doesn't exist). The issue comes around window[] (applied rather than eval(); )I just don't seem to be able to get the string to translate into a function name to execute it.

function MonkeysEatBananas() {
    alert("Function triggered, Monkeys are eating bananas");
}

function FncChk(FuncName) {
    var fn = window[FuncName];
    alert(fn + "---> " + FuncName);

    if (typeof fn == "function" ){alert("Run function hetttre");}else{alert("Function "+FuncName+" not loaded");}
    }
}



FncChk("MinionsEatBananas");

FncChk("MonkeysEatBananas");

I can validate the function as a function by using an inline statement like:

if(  typeof MonkeysEatBananas == "function" ){alert("Run function here");}else{alert("Function "+FuncName+" not loaded");} 

but not when I wrap it in a function for wider user and less code. I just know I'm doing something stupid but I've killed hours on this, hence time to fire a flare! Any kicks in the right direction appreciated.

14
  • Idk where to start. Why'd you tag jQuery? Commented Jul 17, 2017 at 14:44
  • Don't do this all in the global window space. Use properties of an object literal Commented Jul 17, 2017 at 14:47
  • 1
    and "function" !== \'function'\ Commented Jul 17, 2017 at 14:47
  • 1
    There are close to 800000 lines of calculation. over 1000 calculators Commented Jul 17, 2017 at 15:01
  • 1
    Your code appears to work fine. Have a look at this jsfiddle.net/rcondrnt and see what I've not done that you're doing. Commented Jul 17, 2017 at 15:39

2 Answers 2

1

You can use window["functionName"] directly, as long as the function is global.

To test if a function, use typeof window["functionName"] == "function" and to execute, just add ().

function abc() { console.log("abc")}

function runFunc(f)
{
  var fn = window[f];
  //console.log(fn)
  if (typeof fn == "function") fn(); else console.log(f + " not found")
}

runFunc("abc");
runFunc("def");

The jquery version is pretty much the same:

function abc() { console.log("abc")}

function runFunc(f)
{
  var fn = window[f];
  if ($.isFunction(fn)) fn(); else console.log(f + " not found")
}

runFunc("abc");
runFunc("def");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

If you use namespaces, you can do the same but just using the object instead of window (depending on how you implement namespaces, basic object example below):

var calc = {};
calc.abc = function() { console.log("abc") }

calc.runFunc = function(f) {
  var fn = calc[f];
  if (typeof fn === "function") fn();
  else console.log(f + " not found")
}

calc.runFunc("abc");
calc.runFunc("def");

// global namespace (window) now only has 'calc' and not all the calc functions
console.log("window[abc] = " + window["abc"]);

// can also call directly
calc.abc();

Here's an alternative namespacing method using a self-executing function (or, if you're a stickler: Immediately-Invoked Function Expression (IIFE))

var calc = (function() {

  var publicScope = {};

  //Public method
  publicScope.runFunc = function(f) {
    var fn = methods[f];
    if (typeof fn === "function") fn();
    else console.log(f + " not found")    
  };

  var methods = {}; 

  //Private method
  methods.abc = function () {
    console.log("abc");
  }

  //Return only the public parts
  return publicScope;
}());

calc.runFunc("abc");
calc.runFunc("def");

//cannot call directly (as they're private) (gives error)
calc.methods.abc();

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks @freedom-m That is a great explanation. I hope this thread who helps others, your answer is very comprehensive. During searches all I could find were the odd one liners etc. rather than an actual working solution. kudos :)
1

You could use the in operator:

if("func" in window) func();

and you may have a look at OOP, and dynamic function names are always a bad idea...

1 Comment

Thanks Jonas, that didn't work. I'm looking to validate if it is a function within a simple function name. So function IsItFunction(somefunctionnamecheck){ IF yes, execute, IF not function ignore }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.