Using Javascript's Function() Constructor To Deserialize JSON Data
Posted December 10, 2009 at 2:38 PM by Ben Nadel
Last night, I was reading the jQuery Cookbook (review to come soon) and I came across something that I had never seen before; or rather, they mentioned something that I had never seen before (the concept was not actually demonstrated in the book). They mentioned in a side note that Javascript's Function() constructor could be used to evaluate JSON (Javascript Object Notation) data. I very rarely ever use the Function() constructor, so I wanted to see if I could get this to work.
The Function() constructor takes an optional list of argument names and final content argument and builds a function object using the given content as the method body such that this:
- function foo( bar ){ alert( bar ); };
... and this:
- var foo = new Function( "bar", "alert( bar );" );
... are equivalent.
Because our JSON data is string-based in its serialized format as is the above method body, we can easily create a function using the serialized JSON data:
- <!DOCTYPE HTML>
- <html>
- <head>
- <title>Using Function() To Deserialize JSON Data</title>
- <script type="text/javascript">
-
- // Mimic the JSON string as it might come back from a
- // remote AJAX call.
- var jsonString = "{ 'myArray': ['a','b','c'] }";
-
- // Use the Function constructor to create a function
- // that will return the JSON object. Because the Function
- // constructor takes a string value, we can easily
- // integrate it directly into the method definition.
- //
- // NOTE: Immediately invoke the method such that it
- // returns the evaluated JSON value.
- var jsonValue = (new Function( "return( " + jsonString + " );" ))();
-
- // Log the new de-serialized JSON value.
- console.log( jsonValue );
-
- </script>
- </head>
- <body>
- <!--- No data. --->
- </body>
- </html>
As you can see, our dynamically generated method body simply returns the JSON data. When we run the above code, we get the following Firebug console output:
| | | | | |
| | ![]() | | ||
| | | |
Cool - works just fine. I am not sure how this is being run internally to the Javascript engine, or if it's doing anything different than the eval() statement does. I just wanted to see if I could get it to work.
Reader Comments
That's pretty sweet. I'd like to see some speed tests done on this code Ben. Wonder if you could just create a "deserializeJSON() method once and reuse it rather than creating a new one each time.
@Andy,
As far as speed, I would assume that going the Function() route is going to be slower than just going straight to eval() simply because there's probably overhead in creating the resultant function.
I think jQuery, under the hood, will try to the native JSON object it is available, or default to eval() or something - so, the other obvious benefit to abstraction is that you can have a centralized point of branch-logic.
Doesn't appear to work that way. Must be something special in the constructor.
@Andy,
Hmmm, I don't know. I've never actually looked at their evaluation technique; but, I thought I had read something about it leveraging the internal JSON object in the new browsers.
I feel bad about posting links from ASP.NET, but anyway this performance test is quite interesting. It's about the performance between eval(), a new function and the native support of common browsers. http://bit.ly/92Fl5
@Roman,
No worries about .NET ;) It's still good results. Thanks for posting it.
This sounds a bit sketchy. Could a hacker not use this to return a malicious script as JSON data?
@Brian,
No more so than with the use of an eval() statement.
Something else to watch for as I learn AJAX then.
@Brian,
I might be very ignorant here, but I get very suspect of all the hoopla people have over the eval() / hacker stuff. It's one thing when people have an issue with AJAX-driven data; but, a lot of people get in a huff about the use of eval() to strictly internal usage.
I'm not really sure how big a problem it is. I read about it all the time.
I follow the "best practice" guidelines whenever I find them for whatever programming languages I'm using, but is that enough to protect my apps/websites? I hope so. It's not like I'm leaving out a "Welcome Hacker" mat on my virtual front porch. But those guys can be pretty persistent in finding vulnerabilities and exploiting them.
Aside: How about posting some of YOUR Best Practices for ColdFusion or JQuery or anything really?
@Brian,
MY best practices?? Hmm, that's an interesting question. I'll do some thinking and see if I can formalize some stuff.
Thanks for this article, very helpful.
@Danny,
Glad you found it useful.
the most brilliant idea i've ever seen. i tested with ASP.NET JavaScriptSerializer class and it worked. thank you.




