Is JavaScript test() saving state in the regex? [duplicate] - javascript

This question already has answers here:
Why does a RegExp with global flag give wrong results?
(7 answers)
Closed 7 years ago.
Open up a browser console and execute the following code:
var foo = /foo/g;
Then,
foo.test("foo") // true
Then,
foo.test("foo") // false
If you continue to execute foo.test("foo"), you will see alternating true/false responses as if the var foo is actually being modified.
Anyone know why this is happening?

Yes, that's how .test() and .exec() work when the regex is g global. They start at the end of the last match.
You can observe the current last index on the regular expression object using the .lastIndex property.
It's a writeable property, so you can reset it to 0 when/if you need. When the regex is run without finding a match, it automatically resets to 0.

The regex keeps the position of the last test. This allows searching of long strings. You can reset this by setting lastIndex = 0;

Related

Global flag in javascript [duplicate]

This question already has answers here:
Why does a RegExp with global flag give wrong results?
(7 answers)
Closed 3 years ago.
function countSmileys(arr) {
let regex = /^([:;])([-~])*([)D])$/
if(arr.length === 0) {
return 0;
}
return arr.filter(el => {
return regex.test(el);
})
}
console.log(countSmileys([':(', ';)', ':)', ';o>', ':(', ':>', ';~D']));
I wrote the code that verify to see if that is smiley face or not.
for eyes, it takes only ':/;' , for nose, '-/~' (it is fine if there is a nose)
for lips, ')/D'.
So, I wrote the regular expression with global flag first. then
it only gives
[';)', ';~D']
I finally got the right result when I eliminated g flag.
[';)', ':)', ';~D']
I have been confused to use g flags. can anyone explain this?
The issue here is using test() with the global flag on a string advances the regex's lastIndex - even if you are testing a different string in a subsequent run.
Citing from the MDN: Using test() on a regex with the global flag
If the regex has the global flag set, test() will advance the
lastIndex of the regex.
A subsequent use of test() search at the substring of str specified by lastIndex (exec() will also advance the lastIndex property).
It is worth noting that the lastIndex will not reset when testing a different string.

difference between if (!!variable), and, if (variable)? [duplicate]

This question already has answers here:
Can someone explain this 'double negative' trick? [duplicate]
(9 answers)
Closed 9 years ago.
Is there any difference (in JS) between using the double negative !! and not using it at all?
For example
if (!!variable){... vs. if (variable){...
I know there are times where I've gotten a warning using the 2nd method..
When should each be used? and when will each throw a warning in the console? (for variables, objects, arrays etc.)
Thanks!!
There is a difference for assigning it, but not for using it in a conditional statement. The reason the !! is used is because the first ! will convert your variable to its truthy evaluation and then not it. So "hello" becomes true, is then negated, becomes false, and the second ! will negate the false, resulting in true. This can be desirable when trying to obtain the thruthy value from a variable. However, there is not much gained by doing it in an if statement.
In this particular case, there is no difference. In fact, !!variable is wasteful.
However in more general cases, it casts the variable to a boolean. Personally I've only found this useful when debugging, and to learn what values are truthy and falsy.

what does the "||" in a var statement mean? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
null coalescing operator for javascript?
What does “options = options || {}” mean in Javascript?
Can someone explain me this expression? I stumbled accros the javascript line of code and I wondered what it means.
var node = element.node || element[element.length - 1].node;
node get's used like this below:
if (node.nextSibling) {
node.parentNode.insertBefore(this.node, node.nextSibling);
} else {
node.parentNode[appendChild](this.node);
}
At first i though node should be a boolean or something but it's not.
Am I correct if i think that the meaning is: node is element.node but if the node attribute is undefined node is the last element in the array of element?
Your understanding is along the right lines; be aware that even if element.node is defined, but is a falsey value (0, false etc.) that element[element.length - 1].node will be assigned to node instead.
It means, if element.node has a value represents True in boolean expressions, node will be element.node, otherwise it will be element[element.length - 1].node
Simple answer: it means OR :)
Reference: http://www.w3schools.com/js/js_operators.asp
It means OR
for example:
if this || that
means "if this or that"
So when the computer comes to the "||" part of your code, if the statement before it is true, it will stop reading that if statement and automatically execute the code underneath.
If the item before that "||" is false, then it will check the next one, and so on...

Usage of toString in JavaScript [duplicate]

This question already has answers here:
Calling member function of number literal
(3 answers)
Closed 9 years ago.
I'm reading through Douglas Crockford's JavaScript: The Good Parts, and I'm at the point where he defines a fade function. Part of this code boils down to this:
var level = 1;
var hex = level.toString(16);
So I run this in my browser's console to see what I get....
var level = 1;
level.toString(16);
Hey, it returns "1"... Fabuloso! Wunderbar!
Then to be cheeky, I try this to see what I get...
1.toString(16);
And I get
SyntaxError: Unexpected token ILLEGAL
What the what? If level is a variable equal to 1, and running this method on level works fine, then why doesn't running this method on the actual number 1 work? I tried a similar experiment with the toPrecision() method and that worked fine in both cases. What's the issue here? Is this another one of those inherent flaws in the JavaScript implementation, or am I missing something? I am testing in Google Chrome.
Related: Stack Overflow question Why don't number literals have access to Number methods?.
It's just a language grammar limitation.
Since 1. is a legal literal number (and 1.t is not) the tokeniser will split this into the following tokens:
1.
toString
(
)
And that's an illegal sequence of tokens. It's object method, instead of object . method.
In the working versions in #Joey's answer, the braces prevent the tokenizer from treating the dot as part of the number literal instead of as a separate token, as does writing:
1.0.toString()
or
1..toString()
since the tokenizer knows that the second dot must be a token on its own, and not part of the number literal.
You need 1..toString or (1).toString to get the number literal
level is a variable (and thus an object).
1 is a literal. They are not objects and the interpreter thinks about them completely differently.
http://www.cs.brown.edu/courses/bridge/1998/res/javascript/javascript-tutorial.html#4

Why is the JavaScript RegExp.test() method behaving as a toggle? [duplicate]

This question already has answers here:
Why does a RegExp with global flag give wrong results?
(7 answers)
Closed 6 years ago.
Can anyone explain why the alert() in the following JavaScript code is firing? It appears to be a bug in the RegExp.test() method which reverses its previous decision each time you run the method. I'm using IE7.
I've found a replacement that appears solid, using the string.search(regex) method instead. But, I'm curious whether anyone knows something about this.
var styleHasWidthRegex = /\bwidth\s*\:/ig;
var styleText = "WIDTH: 350px";
var result1 = styleHasWidthRegex.test(styleText);
var result2 = !styleHasWidthRegex.test(styleText);
if (result1 == result2) {
alert("This should never happen!");
}
Your regex has the global (g) flag set. Every time it is executed, it'll update an internal index (the lastIndex property) specifying where it left off, and begin searching at that point the next time through.
Of course, you don't really want that - you want it to start at the beginning every time. So ditch the g flag.
See also: Inconsistent javascript logic behavior
In this scenario, you should be needing a global tag anyways, since in css declarations a property should only be declared once.

Categories

Resources