First of all — weird question. It would help a lot to know the context of why you are asking, because obviously Javascript doesn't have exactly what you are asking. (For example, is it something specifically to do with math expressions? Does the expression have to be executed prior to calling the function, as in your example?)
Javascript does not have:
- named parameters
- first-class/dynamic expressions
Javascript does have:
- dynamic objects
- first-class functions
- closures
eval
Dynamic objects
Since this was your own stated option at the end, that you declared unacceptable, it sounds like it won't help you much. In any case, since you want the expression and the values, just passing an object of the values alone isn't going to help you.
First-class functions
As you stated, you do have access to Function.caller
, although that just outputs a String representation of the whole function. It is also non-standard.
You also have arguments
, which is an Array of the arguments that were passed in, not named. In the case of your existing code, obviously, it will be the executed result of the expression. One convenient use of arguments
is not specifying any parameters in the function signature and then iterating through the array as an open-ended list.
Closures
This is also a part of your unacceptable solution at the end, but could possibly the closest to a working solution for you, though you'd have to be flexible on the way bar
is called or where it is defined.
function foo() {
var a = 3;
var b = "hello";
var c = [0,4];
var bar = function(arg) {
alert(arg); // NaN
alert(a + " " + b + " " + c); //will alert "3 hello 0,4"
}
bar(a - b / c);
bar(c * a + b);
}
eval
Using eval and closures, you might get close to what you want.
The primary thing to remember is that in your code, a - b / c
is an expression. That is not the argument, the result of the expression is the argument. There is nothing besides a toString
on the function itself that will alert "a - b / c".
With eval
(Disclaimer: this is very hacky and not recommended! You've been warned.), you could actually pass a String as an argument, and using a closure which is bound to the space, alert what you want.
function foo() {
var a = 3;
var b = "hello";
var c = [0,4];
function hackyUglyEvalAndOutput(callback, expression) {
alert(expression); //will alert "a - b / c" (duh)
alert(a + " " + b + " " + c); //will alert "3 hello 0,4" (because of the closure)
callback(eval(expression)); // "NaN"
}
hackyUglyEvalAndOutput(bar, "a - b / c");
hackyUglyEvalAndOutput(bar, "c * a + b");
}
function bar(arg) { alert(arg); }
You could similarly parse caller
to find calls to the function and see what was passed into the argument list (I did get it to do this) but you will have no way of distinguishing which one made the call if there is more than one. From your example, that would be crucial to accomplish what you want to do.
Again — expressions are just that and nothing more; they are not arguments.
P.S. The second call to bar
will actually output NaNhello
:)