473,625 Members | 2,999 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

JSON.parse

There is a new version of JSON.parse in JavaScript. It is vastly
faster and smaller than the previous version. It uses a single call to
eval to do the conversion, guarded by a single regexp test to assure
that it is safe.

JSON.parse = function (text) {
return
(/^(\s|[,:{}\[\]]|"(\\["\\bfnrtu]|[^\x00-\x1f"\\])*"|-?\d+(\.\d*)?([eE][+-]?\d+)?|true|fal se|null)+$/.test(text))
&& eval('(' + text + ')');
};

It is ugly, but it is really efficient. See
http://www.crockford.com/JSON/js.html
Dec 29 '05 #1
8 10404
VK

Douglas Crockford wrote:
(/^(\s|[,:{}\[\]]|"(\\["\\bfnrtu]|[^\x00-\x1f"\\])*"|-?\d+(\.\d*)?([eE][+-]?\d+)?|true|fal se|null)+$/.test(text))
&& eval('(' + text + ')');
};


Far of being a RegExp guru - trully sincerly not :-

In case of static RegExp are not they more runtime effective if
precompiled?

var re = /r/e/g/e/x/p/;
....
re.test(string) ;
....

Dec 29 '05 #2
Douglas Crockford <no****@sbcglob al.net> writes:

....
guarded by a single regexp test to assure that it is safe.

JSON.parse = function (text) {
return
(/^(\s|[,:{}\[\]]|"(\\["\\bfnrtu]|[^\x00-\x1f"\\])*"|-?\d+(\.\d*)?([eE][+-]?\d+)?|true|fal se|null)+$/.test(text))


Looks reasonable (but a comment stating what it is supposed to match
would would make it much more readable :)

For efficiency, I'd change \s to \s+.

If the regexp doesn't match, then false is returned. This can also
be the value of the JSON expression. Perhaps it would be safer to
return undefined if the test fails, i.e.,
re.test(text) ? eval("("+test+" )") : undefined;
or
if(re.test(text )) { return eval("("+test+" )"); }

Also, you could move the creation of the RegExp object out of the
function, and reuse it for each call, instead of creating a new,
lengthy, RegExp for each call. However, that is only important if
calls are frequent, which they probably shouldn't be anyway.

/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleD OM.html>
'Faith without judgement merely degrades the spirit divine.'
Dec 29 '05 #3
Lasse Reichstein Nielsen wrote in news:ac******** **@hotpop.com in
comp.lang.javas cript:
Also, you could move the creation of the RegExp object out of the
function, and reuse it for each call, instead of creating a new,
lengthy, RegExp for each call. However, that is only important if
calls are frequent, which they probably shouldn't be anyway.


VK, stated something simialar to this too.

But AIUI a RegExp that comes from a /.../ expression is (supposed
to be) compiled when the function body is compiled, IOW it only
happens once, the /.../ expresion having been replaced with a
compiled RegExp object.

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Dec 29 '05 #4

Lasse Reichstein Nielsen napisal(a):
Looks reasonable (but a comment stating what it is supposed to match
would would make it much more readable :)

For efficiency, I'd change \s to \s+.


Please oh please, don't sacrifice unambiguity for grammar correctness.
.. matches any single character. The above would mean a sequence of one
or more whitespaces followed by a single arbitrary character (...and
then the rest of re) which not only slows the regexp instead of
speeding it up, but also changes its meaning.
It took me a while to understand the . means the end of the sentence
here.

For efficiency, I'd change "\s" to "\s+".

Sure the rules of English state the final dot should go INSIDE the
quotation marks, but that would be even worse.

Dec 29 '05 #5
VK

Douglas Crockford wrote:
There is a new version of JSON.parse in JavaScript. It is vastly
faster and smaller than the previous version. It uses a single call to
eval to do the conversion, guarded by a single regexp test to assure
that it is safe.

JSON.parse = function (text) {
return
(/^(\s|[,:{}\[\]]|"(\\["\\bfnrtu]|[^\x00-\x1f"\\])*"|-?\d+(\.\d*)?([eE][+-]?\d+)?|true|fal se|null)+$/.test(text))
&& eval('(' + text + ')');
};

It is ugly, but it is really efficient. See
http://www.crockford.com/JSON/js.html


Semi-irrelevant to this post but important to know:

1. JSON engine versioning
Would the above to be considered as JSON 1.01, JSON 1.1 or JSON 2.0 or
?
It is crutial for benchmark references and proper download refs.

2. In the light of recent events (like JSON as one of official data
interfaces of Yahoo!) does author plan to change anyhow the licensing
(I hope not).

3. Leaving JSON engine in the public domain would it be possible to
narrow the covering license? So far JSON goes under the proprietary
"The Software shall be used for Good, not Evil." As good as it is -
would it be possible to move the software under one of more lecally
specific free software licenses? Like GNU General License or another
well defined copyleft license? If it is not desirable could author to
collaborate on the definition of Evil in the application to JSON? Say
non-ECMA-compliant code or no Firefox support - would it be an evil? Or
the license means the Evil in the social and religious aspects only?

I'm not trying to be nasty - but sometimes a dot counts for big
troubles.

Dec 29 '05 #6
Rob Williscroft wrote:
Lasse Reichstein Nielsen wrote [...]:
Also, you could move the creation of the RegExp object out of the
function, and reuse it for each call, instead of creating a new,
lengthy, RegExp for each call. However, that is only important if
calls are frequent, which they probably shouldn't be anyway.


VK, stated something simialar to this too.

But AIUI a RegExp that comes from a /.../ expression is (supposed
to be) compiled when the function body is compiled, IOW it only
happens once, the /.../ expresion having been replaced with a
compiled RegExp object.


`/.../' is equivalent to `new RegExp(...)', see ECMAScript (ES) 3, 7.8.5.
There is a RegExp object created on each call and GC'd shortly after, so
it is more efficient to create that object once and make it globally
available. To avoid spoiling the global namespace and attach the object
reference to the method that uses it, I wrote

JSON.parse = function(...) { ... JSON.parse.rx ... };
JSON.parse.rx = /.../

However, it should be taken into account that RegExp.prototyp e.test() is
doing very much the same as RegExp.prototyp e.exec() does (ES3, 15.10.6.3)
and so it may not be wise to use a globally available RegExp object that
retains the status of the last match.
PointedEars
Dec 29 '05 #7
Thomas 'PointedEars' Lahn wrote in
news:13******** ********@Pointe dEars.de in comp.lang.javas cript:
Rob Williscroft wrote:
Lasse Reichstein Nielsen wrote [...]:
Also, you could move the creation of the RegExp object out of the
function, and reuse it for each call, instead of creating a new,
lengthy, RegExp for each call. However, that is only important if
calls are frequent, which they probably shouldn't be anyway.
VK, stated something simialar to this too.

But AIUI a RegExp that comes from a /.../ expression is (supposed
to be) compiled when the function body is compiled, IOW it only
happens once, the /.../ expresion having been replaced with a
compiled RegExp object.


`/.../' is equivalent to `new RegExp(...)', see ECMAScript (ES) 3,
7.8.5. There is a RegExp object created on each call and GC'd shortly
after, so it is more efficient to create that object once and make it
globally available. To avoid spoiling the global namespace and attach
the object reference to the method that uses it, I wrote

JSON.parse = function(...) { ... JSON.parse.rx ... };
JSON.parse.rx = /.../


Thanks for the reference,

Standard ECMA-262 3rd Edition - December 1999

7.8.5 Regular Expression Literals

A regular expression literal is an input element that is converted
to a RegExp object (section 15.10) when it is scanned. The object
is created before evaluation of the containing program or function
begins. Evaluation of the literal produces a reference to that object;
it does not create a new object. ...

The above confirms my "AIUI" above, and confirms that there *isn't*
a "new RegExp object created on each call".

Has this version (ECMA-262) been superseeded ?
However, it should be taken into account that RegExp.prototyp e.test()
is doing very much the same as RegExp.prototyp e.exec() does (ES3,
15.10.6.3) and so it may not be wise to use a globally available
RegExp object that retains the status of the last match.


This shouldn't be a problem for a RegExp that only ever has test()
called on it (as with the OP's code) as AFAICT exec() will only
ever reset the lastIndex property to 0 (which is the default anyway).

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Dec 29 '05 #8
Rob Williscroft wrote:
Thomas 'PointedEars' Lahn wrote [...]:
Rob Williscroft wrote:
But AIUI a RegExp that comes from a /.../ expression is (supposed
to be) compiled when the function body is compiled, IOW it only
happens once, the /.../ expresion having been replaced with a
compiled RegExp object.
`/.../' is equivalent to `new RegExp(...)', see ECMAScript (ES) 3,
7.8.5. There is a RegExp object created on each call and GC'd shortly
after, so it is more efficient to create that object once and make it
globally available. To avoid spoiling the global namespace and attach
the object reference to the method that uses it, I wrote

JSON.parse = function(...) { ... JSON.parse.rx ... };
JSON.parse.rx = /.../


Thanks for the reference,

Standard ECMA-262 3rd Edition - December 1999

7.8.5 Regular Expression Literals

A regular expression literal is an input element that is converted
to a RegExp object (section 15.10) when it is scanned. The object
is created before evaluation of the containing program or function
begins. Evaluation of the literal produces a reference to that object;
it does not create a new object. ...

The above confirms my "AIUI" above, and confirms that there *isn't*
a "new RegExp object created on each call".


Yes, indeed. Somehow I overlooked the following sentences all the time,
and it appears I was not the only one here. Thank /you/ for pointing that
out.
Has this version (ECMA-262)
It is ECMA-262 (ECMAScript) _Edition_ 3, actually.
been superseeded ?


There is a PDF and Microsoft Word version of the ECMAScript Language
Specification that have 3 more pages (ref. PDF versions), are titled
"Edition 3 Final" and dated March 24, 2000 inside. (They refer to
themselves being downloadable from ftp.ecma.ch. However, [ftp.]ecma.ch
is no longer and ftp.ecma-international.o rg appears not to provide
access with anonymous login.)

These can be downloaded from

<URL:http://www.mozilla.org/js/language/>

Although it does not appear to include the required corrections mentioned
in the errata, the "Final" addition and the date indicate that this is the
latest revision published by the ECMA; it is unclear why only the December
1999 revision is linked on ecma-international.o rg. (Maybe the mozilla.org
folks have access to more recent information on ECMA's FTP server because
the Mozilla Foundation is an ECMA member.) A text comparison between the
two revisions I did today is inconclusive as yet.

However, whether it should be considered normative or not, that latest
revision says the same as its predecessor; you are correct.
However, it should be taken into account that RegExp.prototyp e.test()
is doing very much the same as RegExp.prototyp e.exec() does (ES3,
15.10.6.3) and so it may not be wise to use a globally available
RegExp object that retains the status of the last match.


This shouldn't be a problem for a RegExp that only ever has test()
called on it (as with the OP's code) as AFAICT exec() will only
ever reset the lastIndex property to 0 (which is the default anyway).


No, it could pose a problem since the next match will start from the
position the `lastIndex' property indicates. The value of that property is
reset to 0 iff "I < 0 or I > length" (15.10.6.2.6.), where according to
step 2 `length' refers to the length of the string the method is passed.
It is unclear what `I' refers to; known implementations suggest that this
is a typo not covered in the errata and actually `i' is meant. If we
assume this, `i' would be the value of ToInteger(lastI ndex), according to
step 4, which is in fact the behavior of those implementations . That means
previous calls of RegExp.prototyp e.exec() on the same RegExp object do
affect the current call on the same object, unless

| 5. If the global property is false, let i = 0.

According to 15.10.4.1,

| The global property of the newly constructed object is set to a Boolean
| value that is true if F contains the character "g" and false otherwise.

So it does not pose a problem _here_, as Douglas is not using a global
expression (and the expression is anchored on both sides anyway.)
PointedEars
Dec 29 '05 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

16
2685
by: G Matthew J | last post by:
http://htmatters.net/htm/1/2005/07/evaling-JSON.cfm This is more or less in response to Mr Crockford's admonition a few months ago, "fork if you must". Ironically, although in that usenet post he calls what I am suggesting "brittle", his own Javascript JSON parser is not valid JSON, but rather conforms to my proposed variation on JSON!! With an identifier prepended to the front of the JSON block, and function literals as values: see...
20
6838
by: Luke Matuszewski | last post by:
Welcome As suggested i looked into JSON project and was amazed but... What about cyclical data structures - anybody was faced it in some project ? Is there any satisactional recomendation... PS i am ready to use JSON as data/object interchange when using AJAX and my J2EE project - because it is easier to traverse the JavaScript object than its XML representation (so of course may argue).
2
3742
by: Kevin Newman | last post by:
Hello, I noticed that the JavaScript library for JSON posted on json.org (http://www.json.org/json.js) is modifying Object.prototype (adding a method - toJSONString). I thought this was considered bad practice because it can disrupt the use of for in loops on Objects. Am I incorrect? Thanks,
2
60199
by: radykl | last post by:
Can anyone explain me why you need to add open and close parenthesis to a JSON text in order to use eval() to parse it? For example: var json = "{a: 'abc', b: 'def'}"; var obj1 = eval("(" + json + ")"); //ok! var obj2 = eval(json); //syntax error! why are parenthesis necessary?
11
11214
by: saril.ks | last post by:
Hi The JSON object I am using is as below . this object is returned after an AJAX call {"application" :} In the JS i am using the below code data = ajaxRequest.responseText ;
23
3195
by: dhtmlkitchen | last post by:
JSON We all know what it is. In ECMAScript 4, there's a JSON proposal: Object.prototype.toJSONString String.prototype.parseJSON The current proposal, String.prototype.parseJSON, returns an object.
9
10864
by: Jon Paal [MSMD] | last post by:
using json like ( {"Records": , "RecordCount":"1" } ) and jquery like: $.ajax({ .... success: function(json, status) {
4
2393
by: ShutterMan | last post by:
I have a JSON object as below (data is from SQL Server Northwind Database). But doing an eval on it returns an error "unterminated string constant" or such. Can someone help me pinpoint the element that is causing the grief? Sorry to post the entire object, but Im hoping someone has a parse utility that will help find whats wrong. { "TABLE":}, { "COL":"},{"DATA":"Education includes a BA in psychology from Colorado State University in...
0
8253
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8189
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8497
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7182
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
5570
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4192
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2621
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
1802
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
2
1499
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.