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.

Community
  • 1
  • 1
VjS
  • 7
  • 4
  • 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(){}` – Hacketo Mar 20 '15 at 09:18
  • Yup, that's the correct answer. Now it makes sense. Thanks~ – VjS Mar 20 '15 at 09:22

3 Answers3

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(){}
Hacketo
  • 4,978
  • 4
  • 19
  • 34
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
Bellash
  • 7,560
  • 6
  • 53
  • 86
  • Yeah, not gonna use `eval`. – VjS Mar 20 '15 at 09:33
  • 1
    `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 – Hacketo Mar 20 '15 at 09:52
  • As you edited your answer, could you tell what is the point of the for loop ? – Hacketo Mar 20 '15 at 10:02
  • @VjS You didn't mention that! Now I edited my answer with non-eval code... Thank you Hacketo => :'( static functions – Bellash Mar 20 '15 at 10:03
  • Sorry; `eval` is usually a bad idea and I had no idea JavaScript had `eval`. – VjS Mar 20 '15 at 10:14
0
var Test = function () {
  this.SubTest = function () {}
} 

var obj = new Test()

obj['SubTest']()

or

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

window['Test']['SubTest']()
reg4in
  • 564
  • 3
  • 9