0

I learned I can call functions by a string representing the function name. Example here: http://www.sitepoint.com/call-javascript-function-string-without-using-eval/

My question is, how can I call the SubTest function in this case:

  function Test() {
     this.SubTest = function() { }
  }

  var functionString = 'Test.SubTest';

It doesn't work with window[functionString].

I even tried this (it's basic; just for testing) but it returns false:

function GetFunction(functionName) {
    var functions = functionName.split('.');
    if ( functions.length === 1 ) {
        var functionObj = window[functions[0]];
        if ( typeof functionObj === 'function' )
            return functionObj;
        return false;
    }
    else if ( functions.length > 1 ) {
        var functionObj = window[functions[0]];
        for ( var i = 1; i < functions.length; i++ ) {
          functionObj = functionObj[functions[i]];
        }
        if ( typeof functionObj === 'function' )
            return functionObj;
        return false;
    }
    return false;
}

var functionName = 'Test.SubTest'; // from the above code example
var functionObj = GetFunction(functionName); // returns false

Update:

Found this: How to turn a String into a javascript function call? but the getFunctionFromString still doesn't work.

2
  • You can't use Test.SubTest directly because SubTest is added on Test on it's initialization, you need to have var t = new Test() before you can use this function. GetFunction("Test.SubTest") work if you had Test.SubTest = function(){} Commented Mar 20, 2015 at 9:18
  • Yup, that's the correct answer. Now it makes sense. Thanks~ Commented Mar 20, 2015 at 9:22

3 Answers 3

1

The thing is Test.SubTest does not exist

SubTest is a property defined in the constructor function Test

That mean that the only way to access this function is to define an object

var t = new Test();
t.SubTest();

The function GetFunction("Test.SubTest") would work if the function was static, like :

function Test() {}
Test.SubTest = function(){}
Sign up to request clarification or add additional context in comments.

Comments

0
var Test = function () {
  this.SubTest = function () {}
} 

var obj = new Test()

obj['SubTest']()

or

Test = function () {}
Test.SubTest = function () {}

window['Test']['SubTest']()

3 Comments

Why should the OP try this? Please add an explanation of what you did and why you did it that way not only for the OP but for future visitors to SO.
If you have read the description of his problem, it is pretty self-explanatory.
Sure, but a good answer, one that gets upvotes, explains the reasoning and logic.
0

The problem is because typeof window['Test.SubTest'] is undefined... so, you need to instantiate the super object to call it's sub function(encapsulated function indeed). See bellow code

  .....
      else if ( functions.length > 1 ) {
    var functionObj = window[functions[0]];
    for ( var i = 1; i < functions.length; i++ ) {
      functionObj = eval('new '+functionObj+'().'+functions[i]);
    }
    if ( typeof functionObj === 'function' )
        return functionObj;
    return false;
    }
  .....

EDITS: I your comment stated you don't want to use eval consider the following solution

  .....
      else if ( functions.length > 1 ) {
    var functionObj = window[functions[0]];
    for ( var i = 1; i < functions.length; i++ ) {
       functionObj =new functionObj()[functions[i]];
    }
    if ( typeof functionObj === 'function' )
        return functionObj;
    return false;
    }
  .....

And here is the complete code for test

     function Test() {
       this.SubTest = function() { 
        this.subsubtest=function(){ alert('subsubtest')}
     }
    }

    var functionString = 'Test.SubTest.subsubtest';

    function GetFunction(functionName) {
      var functions = functionName.split('.');
      if ( functions.length === 1 ) {
          var functionObj = window[functions[0]];
          if ( typeof functionObj === 'function' )
              return functionObj;
          return false;
      }
      else if ( functions.length > 1 ) {
          var functionObj = window[functions[0]];
          for ( var i = 1; i < functions.length; i++ ) {
           functionObj =new functionObj()[functions[i]];
          }
          if ( typeof functionObj === 'function' )
              return functionObj;
          return false;
      }
      return false;
  }

  var functionName = 'Test.SubTest.subsubtest';  
  var functionObj = GetFunction(functionName); 
  alert(typeof functionObj);//function

5 Comments

Yeah, not gonna use eval.
eval il not required, new functionObj()[functions[i]]() should work but this notation and the for loop makes no sense as you could not use this method for static functions
As you edited your answer, could you tell what is the point of the for loop ?
@VjS You didn't mention that! Now I edited my answer with non-eval code... Thank you Hacketo => :'( static functions
Sorry; eval is usually a bad idea and I had no idea JavaScript had eval.

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.