Strange JavaScript Regex Behavior in Firefox and Opera After KeyUp Event
Create a page containing the attached code snippet and view the page in Firefox (or Opera, they both do this, but not IE or Safari). Type "8" (or any other digit) followed by a single letter, say "e", repeated several times. Each time you hit the "e" key, the result of the RegExp test that gets printed back into the second text box will alternate between true/false. WHY???
This simplified test case demonstrates what I think is a bug, but one that appears in current versions of two major browsers. The regular expression is testing for the existence of a digit. If I put one digit at the start of the test string, no quantity of subsequent characters should alter the result. This is one example of many - I have found that many regex patterns return unexpected results when used to test the value of a text box following the KEYUP event.
If you place a breakpoint on the return line and copy the return expression into the Firebug console it will always return true, even though executing that same line immediately after returns false.
The answer I am looking for is either an explanation of this behaviour that would convince me it isn't a bug, or a practical workaround that makes the second box always return true. Meanwhile I've reported it on BugZilla.
Hmm. Intriguing. The regex should test the value in the textbox, it seems as if that value is not always equal to what you actually see?
Btw, you don't need a letter to have this behavior. Hit Shift, Alt, Ctrl (without anything else), or Home, End, arrow keys, whatever you fancy: the behavior is the same regardless.
On thing that can be said of this "bug" (if it is one, but I'll get back at you) is that it is very consistent... :)
One more thing on this quest. Though it is not a bug, it seems odd that just typing nothing (i.e., Ctrl, Alt, Home etc) also triggers this behavior. But if you think of it, in the light of my analysis above, you'll see that it is consistent: the lastIndex property is moved one position to the right, which is, when a string is made of one character, the end of the string. Then, /\d/ will match false. Next time, the pointer is at the beginning of the string. Then, /\d/ will match true.
Like I said: intriguing. Like I said: not intuitive :)
Ah. You know what, I've hit this same problem before in a different disguise and I didn't recognise it. Unfortunately is that the example I've given is hugely simplified from what I'm actually trying to achieve. Suffice to say anyway that in this instance I can live without the "g" modifier and that has corrected the behaviour. That said, there will be instances where I can't do without it. In those cases, would the "new RegExp()" constructor syntax be the way to go?
> In those cases, would the "new RegExp()" constructor syntax be the way to go?
That is the safest, I believe. There are subtle differences between the following four versions (one will throw an error, I don't consider that one):
Will call the constructor of RegExp, because the first argument is of type String and the second is not undefined
Will not call the constructor of RegExp, instead, it returns the first argument
Will call the constructor because of "new"
Will call the constructor because of "new" and create a regular expresion object that is a copy of the the first argument and resets lastIndex.
When I say "will call the constructor" it means that a fresh new object will be created and the lastIndex property will be reset.
If you use the syntax as you described, the same happens as number 2 below, without the lastIndex property being reset. You can, however, reset that property manually as follows, which will also cure this problem (then, you will have to assign your /\d/g firstly, of course):
1. var re = RegExp("\\d", "g");2. var re = RegExp(/\d/g);2a. var re = RegExp(/\d/, "g"); // error3. var re = new RegExp("\\d", "g");4. var re = new RegExp(/\d/g);
Thanks for the detailed additional explanation - saves me a lot of headaches looking all this stuff up ;)
JavaScript
JavaScript is a dynamic, object-based language commonly used for client-side scripting in web browsers. Recently, server side JavaScript frameworks have also emerged. JavaScript runs on nearly every operating system and in almost every mainstream web browser.
Btw, you don't need a letter to have this behavior. Hit Shift, Alt, Ctrl (without anything else), or Home, End, arrow keys, whatever you fancy: the behavior is the same regardless.
On thing that can be said of this "bug" (if it is one, but I'll get back at you) is that it is very consistent... :)