I've been using Javascript string.match(*regex*)
function to parse the navigator.userAgent
string.
FYI, According to MDN & W3schools:
"The match() method searches a string for a match against a regular expression, and returns the matches, as an Array object."
I first parse once to get the wanted strings for the base string:
var userAgent = navigator.userAgent;
var splitted = userAgent.match(/[(][^)]+[)]|\w+\/\S+/ig);
Which gives me the following Output (Which is an Array)
Mozilla/5.0
(Macintosh; Intel Mac OS X 10_10_3)
AppleWebKit/537.36
(KHTML, like Gecko)
Chrome/41.0.2272.76
Safari/537.36
Then i parse the Navigator/Version type strings in a for loop
for (var i = 0; i < splitted.length; i++ ) {
var str = splitted[i];
if (str[0] == '(') {
} else {
var name = str.match(/[^\/]+/i);
var version = str.match(/[0-9|\.]+/i);
}
But, very surprisingly and even though I get the desired result, I get a String Object for the name and an Array Object for the version
How is it even possible ?
Here's the snippet of the code (fiddle):
var userAgent = navigator.userAgent;
var splitted = userAgent.match(/[(][^)]+[)]|\w+\/\S+/ig);
var outputDiv = document.getElementById("log");
for (var i = 0; i < splitted.length; i++ ) {
var str = splitted[i];
if (str[0] == '(') {
} else {
var name = str.match(/[^\/]+/i);
var version = str.match(/[0-9|\.]+/i);
outputDiv.innerHTML += name.toString() + " is a " + typeof(name) + "<br>";
outputDiv.innerHTML += version.toString() + " is a " + typeof(version) + "<br>";
}
};
<div id="log"></div>
--- UPDATE ---
Thanks FactoryAidan for the answer, it was a scope problem.
Conclusion: be careful when naming global variables :)
It is because you are using name
as your variable. This is a global browser window variable that is inherently a string and cannot be stored as an Array
Even if you redeclare it with var name =
, you are still in the global scope. And thus name
(aka window.name
) simply retains the last value you assign to it.
You can test this with the following on an empty page without defining any variables at all:
console.log(name===window.name) // Returns true
console.log(name,window.name) // Returns 'Safari Safari' for my browser
name
to something elseIf you change your name
variable to simply have a different name, like my_name
, it stores the result of .match()
as an Array.
var my_name = str.match(/[^\/]+/i);
var version = str.match(/[0-9|\.]+/i);
console.log(typeof my_name, my_name instanceof Array) // Returns object, true
This is your exact code wrapped inside a function and returns the correct variable types:
function getBrowserStuff(){
var userAgent = navigator.userAgent;
var splitted = userAgent.match(/[(][^)]+[)]|\w+\/\S+/ig);
for (var i = 0; i < splitted.length; i++ ) {
var str = splitted[i];
if (str[0] == '(') {
} else {
var name = str.match(/[^\/]+/i);
var version = str.match(/[0-9|\.]+/i);
console.log('Name','Typeof '+(typeof name), 'IsArray '+(name instanceof Array),name)
console.log('Version','Typeof '+(typeof version),'IsArray '+(version instanceof Array),version)
}
}
return 'whatever'
}
getBrowserStuff()
Changing the variable name
to my_name
OR wrapping code like the above function returns this:
Name Typeof object IsArray true ["Mozilla"]
Version Typeof object IsArray true ["5.0"]
Name Typeof object IsArray true ["AppleWebKit"]
Version Typeof object IsArray true ["600.3.18"]
Name Typeof object IsArray true ["Version"]
Version Typeof object IsArray true ["8.0.3"]
Name Typeof object IsArray true ["Safari"]
Version Typeof object IsArray true ["600.3.18"]
Where before it returned this:
Name Typeof string IsArray false Mozilla
Version Typeof object IsArray true ["5.0"]
Name Typeof string IsArray false AppleWebKit
Version Typeof object IsArray true ["600.3.18"]
Name Typeof string IsArray false Version
Version Typeof object IsArray true ["8.0.3"]
Name Typeof string IsArray false Safari
Version Typeof object IsArray true ["600.3.18"]
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments