Can anyone explain this (using node version 4.2.4 repl)?
var n; //undefined
/^[a-z0-9]+$/.test(n); // true!
/^[a-f0-9]+$/.test(n); // false
The variable passed to .test() is first converted to string. This is specified in the spec:
http://www.ecma-international.org/ecma-262/5.1/#sec-15.10.6.3
which points to:
http://www.ecma-international.org/ecma-262/5.1/#sec-15.10.6.2
which says:
Let R be this RegExp object.
Let S be the value of ToString(string).
So basically you're testing:
/^[a-z0-9]+$/.test("undefined"); // true!
/^[a-f0-9]+$/.test("undefined"); // false
It should now be obvious why the second test returns false. The letters u, n and i are not included in the test pattern.
Note: The function ToString() in the spec refers to the type coercion function in the underlying implementation (most probably C or C++ though there exist other implementations of js in other languages like Java and Go). It does not refer to the global function toString() in js. As such, that second line in the spec basically means that undefined will be treated as "" + undefined which returns "undefined".
Probably it's converting undefined to a string. So:
var pattern1 = /^[a-z0-9]+$/
var pattern2 = /^[a-f0-9]+$/
pattern1.test("undefined") // There are only letters
pattern2.test("undefined") // defed match, but unin does not.
RegExp.test treats n as a string "undefined".So, the range [a-f] does not cover all the characters of undefined string.In your case, the "mimimum allowable" range for passing regexp check would be [a-u]
var n; //undefined
console.log(/^[a-u]+$/.test(n)); // true
Related
It appears that the RegExp intrinsic is stateful.
So calling it twice on the same string will yield different results when the global flag g is supplied, as it advances a search along the string.
So:
var r = /(\d{3})/g;
console.log(r.test('123')); // true
console.log(r.test('123')); // false - because the search has moved past the first match
But if I add an intermediate test, I get the following:
var r = /(\d{3})/g;
console.log(r.test('123')); // true
console.log(r.test('456')); // true
console.log(r.test('123')); // true!
So is it correct to say that RegExp instances operate on the principle of considering only the last string evaluated? If the string differs from the last, it is effectively reset?
So is it correct to say that RegExp instances operate on the principle of considering only the last string evaluated?
yes
If the string differs from the last, it is effectively reset?
correct
If the global flag is omitted, is the regular expression reset in between tests?
right
Check out RegExp#lastIndex
If I say sym1 = Symbol();, is Symbol function working like below function g,
> g = function(){
| return 2; //return some random unique value based on some internal algo
| }
g()
> var sym1 = g();
> sym1
2
Now when I do var sym1 = Symbol();, and log sym1, the console displays Symbol() instead of displaying the value returned by the Symbol function.
So here's my question: How does the Symbol function work? How is the console able to display Symbol() instead of some value when you type sym1? Can we write such function?
Yes, Symbol is just a function, similar1 to an arbitrary function g() { return something }.
However, unlike the example g in your question, it does not return numbers, but symbols, which are a new primitive value type in ES6.
When I say sym1, console displays Symbol() instead of displaying the value returned by function Symbol.
What do you think is the value returned, and what do you think how it should be displayed?
The number your g function returned is just some collection of 64 bits2. Somehow3, the console derives a base 10 string from that to display the number with the digits you expect.
Now, what is a symbol? It's just a value with an identity, and we don't even know how it is implemented. It's not immediately clear how that could be displayed, or if at all. It's not a number, it's not a string. Maybe some kind of id4?
ES6 however has taken a precaution against this, and every symbol is given a description string5 that can be passed as an optional argument to the Symbol function. Also, ES6 does specify how symbols should be displayed as string in §19.4.3.2. And that's typically what the console uses.
Pretty much this "descriptive string" resembles the way the call to Symbol looked, e.g.
var sym1 = Symbol("my description");
console.log(sym1.toString()); // "Symbol(my description)"
console.log(sym1); // Symbol(my description)6
var sym2 = Symbol();
console.log(sym2.toString()); // "Symbol()"
console.log(sym2); // Symbol()6
1: However, it's a plain function, not a constructor, and cannot be called with new.
2: plus some kind of type information that it's a number, to give the 64 bits a meaning
3: to be explicit, the console probably uses .toString for numbers when it encounters a number
4: Chrome displays such for every object when you take a heap snapshot with the dev tools, for example
5: So yeah, it's a bit more than the unique identity
6: implementation-dependent, depends on your console
Is window['Symbol'] function working like below function g,
Not certain about actual Question ? Though, appear "no"
Here is the confusion, when I say, > sym1 console displays Symbol()
instead of displaying the value returned by function Symbol
Symbol() does not return a function , but a "unique and immutable data type and may be used as an identifier"
See Symbol
A symbol is a unique and immutable data type and may be used as an
identifier for object properties. The symbol object is an implicit
object wrapper for the symbol primitive data type.
var sym = Symbol("foo");
var obj = {};
obj[sym] = 1;
console.log(obj.sym); // `undefined`
console.log(Object.keys(obj)) // `[]`
console.log(obj[sym]); // `1`
See also ES6 In Depth: Symbols
typeof(Infinity) returns Number in Javascript.
But why doesn't x.isNaN, where x = 1/0, return Number ?
Sample code:
var x = 1/0;
document.write(typeof(x)); //returns Number
document.write(x.isNaN); //return undefined
P.S: I am new to Javascript and learning it from W3Schools. I would be glad if you can direct me to any other reliable resources.
isNan is not a property of any number. isNaN, however, is both a function on the global scope, and on the Number object. (With the latter one being newer / more robust version)
Since isNaN is a function, you'll have to pass the variable you'd like to check as an argument:
isNaN(x) or Number.isNaN(x) will return true, as you expected.
The reason document.write(x.isNaN); returns undefined, is because x (a Number) doesn't have the property isNan.
Numbers (including NaN) don't have an isNaN method. It's global. What you want is actually isNaN(x). (Note the capital N.)
isNaN is not a property, it is a global function or a Number static method (won't work on instantiated variables).
you'll have to use either:
isNaN(x);
Number.isNaN(x);
Preferencially, Number.isNaN, although it isn't supported in IE, Opera or Safari yet.
var place = "mundo"["Hola", "Ciao"];
Why does this return undefined? Just because it is garbage?
That is perfectly valid JS, though it doesn't do what you expect.
place is initialized to the 'Ciao' property of String('mundo'). Since it doesn't exist, it is initialized to undefined.
The tricky part:
"Hola","Ciao" is using the comma operator, evaluates "Hola", evaluates "Ciao" and returns "Ciao"
[...] in this case is property access
"mundo"[] "mundo" is converted to a String object to access the property on it.
Proof:
var place = "mundo"["Hola", "toString"];
console.log(place) // function toString() { [native code] }
The array operator on a string object will either try to index into the string and return a specific character from that string (on some JS implementations) or it will try to lookup a property on that object. If the index is a number, some JS implementations (I think this is non-standard behavior) will give you that character from the string.
// returns "m" in Chrome
"mundo"[0]
// returns undefined
"mundo"[9]
But, an array index that isn't a number will try to look for that property on the string object and your particular value won't be found on the string object and thus you get undefined.
// does a property lookup and returns "function toString{[native code]}
"mundo"["toString"]
// returns undefined - no propery named foo
"mundo"["foo"]
So, since there is no property on the string that resembles anything in ["Hola", "Ciao"], you get undefined. Technically, the browser is actually looking for the "Ciao" property when you give it this and because that property doesn't exist, you get undefined.
In a weird test, you can run this code to sort of see what's going on:
var str = new String("mundo");
str["Ciao"] = "Hello";
alert(str["Hola", "Ciao"]); // alerts "Hello"
Working demo of this: http://jsfiddle.net/jfriend00/e6R8a/
This all makes me wonder what in the heck you are actually trying to do that comes up with this odd construct.
This question already has answers here:
Why does a RegExp with global flag give wrong results?
(7 answers)
Closed 8 months ago.
have funciton in my object which is called regularly.
parse : function(html)
{
var regexp = /...some pattern.../
var match = regexp.exec(html);
while (match != null)
{
...
match = regexp.exec(html);
}
...
var r = /...pattern.../g;
var m = r.exec(html);
}
with unchanged html the m returns null each other call. let's say
parse(html);// ok
parse(html);// m is null!!!
parse(html);// ok
parse(html);// m is null!!!
// ...and so on...
is there any index or somrthing that has to be reset on html ... I'm really confused. Why match always returns proper result?
This is a common behavior when you deal with patterns that have the global g flag, and you use the exec or test methods.
In this case the RegExp object will keep track of the lastIndex where a match was found, and then on subsequent matches it will start from that lastIndex instead of starting from 0.
Edit: In response to your comment, why doesn't the RegExp object being re-created when you call the function again:
This is the behavior described for regular expression literals, let me quote the specification:
§ 7.8.5 - Regular Expression Literals
...
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.
....
You can make a simple proof by:
function createRe() {
var re = /foo/g;
return re;
}
createRe() === createRe(); // true, it's the same object
You can be sure that is the same object, because "two regular expression literals in a program evaluate to regular expression objects that never compare as === to each other even if the two literals' contents are identical", e.g.:
/foo/ === /foo/; // always false...
However this behavior is respected on all browser but not by IE, which initializes a new RegExp object every time.
To avoid this behavior as it might be needed in this case, simply set
var r = /...pattern.../g;
var m = r.exec(html);
r.lastIndex=0;
This worked for me.