jQuery.parseJSON
The other day I was re-watching (haha, learning through repetition) "11 More
Things I Learned from the jQuery Source" and this time I was quite amazed when
Paul Irish talked about parseJSON. And the reason was the way jQuery makes the
JSON object, it's clever, it's very clever.
Let me show you. Here's jQuery's 1.5.2 parseJSON method:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | parseJSON: function( data ) { if ( typeof data !== "string" || !data ) { return null; } // Make sure leading/trailing whitespace is removed (IE can't handle it) data = jQuery.trim( data ); // Make sure the incoming data is actual JSON // Logic borrowed from http://json.org/json2.js if ( rvalidchars.test(data.replace(rvalidescape, "@") .replace(rvalidtokens, "]") .replace(rvalidbraces, "")) ) { // Try to use the native JSON parser first return window.JSON && window.JSON.parse ? window.JSON.parse( data ) : (new Function("return " + data))(); } else { jQuery.error( "Invalid JSON: " + data ); } }, |
Let's dissect that:
- Lines 2-4 are just checking you pass a string and its not empty.
- Line 7 explains itself.
- Lines 11-13 is a regular expression evaluation to make sure we have valid JSON.
The interesting part, in this case, is the return statement:
1 2 3 | return window.JSON && window.JSON.parse ? window.JSON.parse( data ) : (new Function("return " + data))(); |
If the browser has native JSON support, use that. If not, and this is the
interesting part, we'll do (new Function("return " + data))().
But what does that mean? I'm glad you asked.
- We're calling the
Functionconstructor, which will return aFunctionobject (function reference) and immediately invoke it. - The
Functionconstructor takes an "n" number of arguments that will become the function's parameters, being the last one the body of the function. We're passing only one parameter, meaning"return " + datawill become the function's body. - What does the constructed function do then? Considering
datais a JSON string it becomes rather obvious now. It returns a JavaScript object. See? I told you it was clever, no need forevalthis way.
Sources: