1

I am new to JS. I heard that functions can be manipulated like values in this language. So I tried writing a code that asks the user for a function, then call this function, which should be alright. But it doesn't work, the code is :

   <SCRIPT language=javascript>
    var input;
   (function PromptMessage() {
       input = prompt("type the function you want called")
    })()
    input();
</SCRIPT>

And in the prompt box I type function () {alert("I am an alert box!");}

But it doesn't work, I don't see the alert. Am I doing something wrong or it is that the only callable functions are defined in the source code ?

Josh Crozier
  • 233,099
  • 56
  • 391
  • 304
sssss
  • 89
  • 3
  • possible duplicate of [What is meant by 'first class object'?](http://stackoverflow.com/questions/705173/what-is-meant-by-first-class-object) – Sean Vieira Feb 16 '15 at 17:49
  • @SeanVieira The OP is asking *'is x a first class object'*, not *'what is a first class object'*. – George Feb 16 '15 at 17:52

4 Answers4

4

Yes, functions are first class objects.

function one() {
  alert("Hello");  
}

function runAnotherFunction(anotherFunction) {
  anotherFunction();  
}

runAnotherFunction(one);

The return value of the prompt function, however, is a string.

A string containing JavaScript code is still a string and can't be called as if it was a function.

You could eval it, but that is usually a terrible idea (as is asking users to write raw JS to inject into your program in the first place).

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • Thanks so it was a type problem. I know that asking the user for a function is a bad idea, but it was just for fun, as it is the first thing I thought about that would not be possible to do in Java or C++. So now it works with eval ! – sssss Feb 16 '15 at 18:00
  • 1
    The Function constructor function is more-or-less eval by another name. – Quentin Feb 16 '15 at 18:56
1

Part of the question is about invoking a function string, so here it goes:

 var input;
  (function PromptMessage() {
       input = prompt("type the function you want called")
  })();

 function getFunctionBody(s) {
    var match = s.toString().match(/function[^{]+\{([\s\S]*)\}$/);
    return match ? match[1] : s;
 }
  
Function(getFunctionBody(input))();

enter the string in the prompt

function () {alert("I am an alert box!");}

and you should get the alert.

It's a little more work to take account of function parameters, but I'll leave that up to you as an exercise.

The Function constructor is safer than eval because it runs in it's own scope and doesn't have access to outside scope.

Miguel Mota
  • 20,135
  • 5
  • 45
  • 64
  • Thanks for this alternative solution, eval() works, but I didn't think of returning a string in a function whose return type is function so that it will be casted to a function and thus callable (that's what your code does right ?) – sssss Feb 16 '15 at 18:08
  • Yep, and it's safer than eval because it doesn't have access to outside it's scope. – Miguel Mota Feb 16 '15 at 18:19
0
(function PromptMessage() {
       var input = prompt("type the function you want called");
       eval(input)();
})()

Would do what you want, you need to evaluate the string to make it a function. Don't do this in a real website.

qwwqwwq
  • 6,999
  • 2
  • 26
  • 49
0

prompt is return string and string is not a function; use eval is execute you data like js
var input; (function PromptMessage() { input = prompt("type the function you want called") })() eval(input);

Rana Ahmer Yasin
  • 437
  • 3
  • 17