Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript eval() "syntax error" on parsing a function string

I have a bit of JavaScript code that is specified in a configuration file on the server-side. Since I can't specify a JavaScript function in the configuration language (Lua), I have it as a string. The server returns the string in some JSON and I have the client interpret it using a clean-up function:

parse_fields = function(fields) {
    for (var i = 0; i < fields.length; ++i) {
        if (fields[i].sortType) {
            sort_string = fields[i].sortType;
            fields[i].sortType = eval(sort_string);
        }
        return fields;
    }
}; 

So basically it just evaluates sortType if it exists. The problem is that Firebug is reporting a "Syntax error" on the eval() line. When I run the same steps on the Firebug console, it works with no problems and I can execute the function as I expect. I've tried some different variations: window.eval instead of plain eval, storing the sortType as I've done above, and trying small variations to the string.

A sample value of fields[i].sortType is "function(value) { return Math.abs(value); }". Here's the testing I did in Firebug console:

>>> sort_string
"function(value) { return Math.abs(value); }"
>>> eval(sort_string)
function()
>>> eval(sort_string)(-1)
1

and the error itself in Firebug:

syntax error
[Break on this error] function(value) { return Math.abs(value); }

The last bit that may be relevant is that this is all wrapped in an Ext JS onReady() function, with an Ext.ns namespace change at the top. But I assumed the window.eval would call the global eval, regardless of any possible eval in more specific namespaces.

Any ideas are appreciated.

like image 500
Kenny Peng Avatar asked May 03 '10 20:05

Kenny Peng


2 Answers

To do what you want, wrap your string in parentheses:

a = "function(value) { return Math.abs(value);}";
b = eval("("+a+")");
b(-1);
like image 57
jhurshman Avatar answered Nov 05 '22 11:11

jhurshman


The parentheses are required because they force the thing inside them to be evaluated in an expression context, where it must be a function-expression.

Without the parentheses, it could instead be a function declaration, and it seems as if it is sometimes being parsed that way - this could be the source of the odd/inconsistent behaviour you're describing.

Compare this function declaration:

function foo(arg) {}

with this function-expression:

var funcExpr = function foo(arg) {};

It also has to be a function-expression if it doesn't have a name. Function declarations require names.

So this is not a valid declaration, because it's missing its name:

function (arg) {}

but this is a valid, anonymous function-expression:

var funcExpr = function(arg) {};
like image 27
whatever Avatar answered Nov 05 '22 10:11

whatever