-1

I am trying to create a variable which when put together with another variable creates a function call. EG:

var firstexpression = "MyFunction";
var secondexpression = "();";
var totalexpression = firstexpression + secondexpression;

And this would make totalexpression read as "MyFunction();" I want to be able to basically call this function from within an Array. This is what I came up with:

<!DOCTYPE html>
<html>
<body>

<p>test</p>

<p id="demo"></p>

<script>
function Banana() {
return "Junk";
}
var junker = "Banana" + "();";
var fruits = [junker];
document.getElementById("demo").innerHTML = fruits[0].toString();
</script>


</body>
</html>

This just returns "Banana();", but it doesn't run "Banana();". I know it isn't as simple as what I put up there, but there has to be a way to do something like this in Javascript. Does anyone have any suggestions to this? I know this can probably be done with JQuery. But I want to avoid JQuery if at all possible. Thank you!

user1924218
  • 99
  • 1
  • 11
  • 2
    What are you *really* trying to do? You won't find code anything like that in JavaScript written by people who know the language. What is the problem you're trying to solve? – Pointy Aug 14 '15 at 23:39
  • 2
    Note: You can pass the function itself around as a value and call it later -- `var fruits = [Banana]; ...innerHTML = fruits[0]();`. – Jonathan Lonowski Aug 14 '15 at 23:41

4 Answers4

1

You're just concatting strings, and strings don't run anything. If you want to evaluate strings, use eval (but be very careful):

var fruits = [eval(junker)];

Here's your full demo:

<p>test</p>

<p id="demo"></p>

<script>
function Banana() {
return "Junk";
}
var junker = "Banana" + "();";
var fruits = [eval(junker)];
document.getElementById("demo").innerHTML = fruits[0].toString();
</script>

Useful resource: Why is using the JavaScript eval function a bad idea?

Community
  • 1
  • 1
Shomz
  • 37,421
  • 4
  • 57
  • 85
  • 1
    Yup, thus the warning. – Shomz Aug 14 '15 at 23:39
  • What are the warnings or things I need to be careful of with Eval? Is there something else that would be safer to use? – user1924218 Aug 14 '15 at 23:43
  • Click the warning link, there are millions of other resources about that online. Do not use eval unless you absolutely have no other choice. We have no idea what you're trying to do, and if it was me, I'd just do: `document.getElementById("demo").innerHTML = Banana();` – Shomz Aug 14 '15 at 23:44
  • @epascarello, better ways to evaluate strings? Show us. – Shomz Aug 15 '15 at 00:18
  • There is NO reason to eval a string to run a function. A better data structure like some of the other answers and it is amazing what you can do. – epascarello Aug 15 '15 at 00:24
  • 1
    I didn't ask this question, nor I have any information apart from what OP wrote in it... he may be trying to **build a nuclear bomb**, or a **small grocery app**, we can guess all day, but we don't know... He wanted to evaluate the string he concatted and that's what I've showed him, including the links to see why eval can be dangerous... and I've said not to use it ever unless absolutely necessary. `"There is NO reason to eval a string to run a function"`... unless you want to have a string that runs the function, in which case it's a damn good reason... – Shomz Aug 15 '15 at 00:27
  • 1
    Shomz.. This-> "unless you want to have a string that runs the function, in which case it's a damn good reason.." :-) Thanks! – user1924218 Aug 15 '15 at 01:48
1

While you've already accepted an answer, I'd suggest, rather than using eval(), that you instead wrap all the required functions into an Object, and and use an Array of function-names – created automatically, using Object.keys() – from which the functions can be accessed and exectuted:

// creating an object to hold the functions:
var fn = {
    'banana': function() {
      return 'A function called "banana" was exectuted.';
    },
    'orange': function() {
      return 'The mysterious "orange" function was called.';
    },
    'anotherName': function() {
      return 'The function going by the name of "anotherName" was called.';
    }
  },

  // Using Object.keys() to retrieve an Array of the
  // keys - the function names - from the fn Object:
  functions = Object.keys( fn );

// this looks a little complicated, but:
// fn[]() (the outermost part) is simply using square-bracket
// notation to call and run a function held within the fn Object;
// functions[] is used to access an Array element at the index
// supplied by the call to: Math.floor(Math.random() * functions.length
// which returns a random integer in the range of 0 - functions.length:
console.log(fn[functions[Math.floor(Math.random() * functions.length)]]());

var fn = {
    'banana': function() {
      return 'A function called "banana" was exectuted.';
    },
    'orange': function() {
      return 'The mysterious "orange" function was called.';
    },
    'anotherName': function() {
      return 'The function going by the name of "anotherName" was called.';
    }
  },
  functions = Object.keys(fn);

snippet.log(fn[functions[Math.floor(Math.random() * functions.length)]]());
<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

External JS Fiddle demo for experimentation.

References:

David Thomas
  • 249,100
  • 51
  • 377
  • 410
0

Here's the way that I thought of...

  <script>
    var myArray = [];

    Array.prototype.Banana = function() {
      return "Junk";
    };

    console.log(myArray.Banana());
  </script>

This prototypes the Banana function so that it could be called from any array that you make.. not sure if this is what u wanted?

SuperVeetz
  • 2,128
  • 3
  • 24
  • 37
0

If what you want to do is to run a global function using its name stored as a string in a variable, the following should work in a non-evil-eval way:

<!DOCTYPE html>
<html>
<body>

<p>test</p>

<p id="demo"></p>

<script>
function Banana() {
return "Junk";
}
var junker = "Banana";
var fruits = [junker];
document.getElementById("demo").innerHTML = window[fruits[0]]();
</script>


</body>
</html>

window gives you access to the global namespace.

Ozan Bellik
  • 483
  • 2
  • 6
  • How's that different from what Jonathan wrote in the comments? – Shomz Aug 14 '15 at 23:48
  • @Shomz, well technically, it's subtly different in behavior. His answer is a lot more sensible in most cases, but if you want to be able to change what "Banana" points to in the relevant namespace and have that change carry over to the code that will run your function, storing the key and not the function is the way to go. – Ozan Bellik Aug 14 '15 at 23:53
  • For some reason though, this does not work well. I do think this may work a slightly better than Eval in theory.. But its just not working. :( – user1924218 Aug 15 '15 at 00:02
  • Jonathan wrote: `...innerHTML = fruits[0]();` which will behave exactly the same since the context in both cases is window. – Shomz Aug 15 '15 at 00:03
  • @Shomz, you're absolutely right that it will do the same thing with no other changes to the code, just like calling Banana directly or better yet putting Junk directly in the p tag would produce the same result. Not sure if you read the second sentence in my comment, but I meant to imply that if the OP wanted to later on add Banana = function() { return "some other junk;"} or window.Banana... or to change this to use a different object as a namespace, then he might want to hold on to the name of the function rather than the function itself. – Ozan Bellik Aug 15 '15 at 00:09
  • @user1924218, did you try jsfiddle only or in an html doc directly, as well? My guess is that it doesn't work in jsfiddle because jsfiddle doesn't run your code in the global namespace. If you want to make it work in jsfiddle, you could try something like http://jsfiddle.net/hs6aheye/1/ – Ozan Bellik Aug 15 '15 at 00:14