Since you're using .NET as an example, let's delve briefly into that. In C#, you could create a function that takes an Expression
:
void BadArgument<T>(Expression<Func<T>> argExpr)
{
}
But in order to be able to extract the variable name from a call to this function, you would have to make sure the call always uses exactly the right syntax (even though there is no way to enforce this at compile time):
if(x < 0)
BadArgument(() => x);
So it can be done, but it's very fragile and pretty slow. You're basically generating instructions to create a whole expression tree based on the lambda expression () => x
, just so the function you call can parse out that expression tree and try to find the name of the argument.
Can this sort of thing be done in javascript? Sure!
In javascript, closures are produced via internal functions, so the equivalent of the above lambda expression would be:
function(){return x;}
And since javascript is a scripting language, each function is the equivalent of its own definition as a string. In other words, calling .toString()
on the above function will yield:
function(){return x;}
This jsfiddle shows how you can leverage this in a logging-style function. You are then free to parse the resulting function string, which will be only slightly more trouble than parsing the .NET Expression Tree would be. Furthermore, getting the actual value of x
is even easier than in .NET: you just call the function!
But just because you can do it doesn't mean you should. It's nice as a gee-whiz parlor trick, but when it comes right down to it, it's not worth it:
- It's fragile: what if some developer doesn't use it right and gives you a function that you can't parse?
- It doesn't work with minification: imagine getting a message that variable
a
had an incorrect value because your minified function changed your variable names.
- It adds overhead: even a minifier can't shorten
function(){return x;}
to be smaller than "x"
.
- Finally, it's complicated. 'nuff said.