Wondering if anyone could shed some light as I’m pulling my hair out over this one!
I have written a simple function to validate a users Date of birth which is all well and good, or at least it was until I realised it wasn't working as expected!
The function, as below, takes 2 parameters, dobNum (the value of an input field) and dmy (a switch variable that receives either ‘dd’, ‘mm’ or ‘yyyy’). The function is called as follows with the value of an input field so there shouldn’t be any object based problems:
onblur=”validateDOB(this.value, ‘mm’);
I have spent ages trying to get to the bottom of this and there seems to be a problem with the parseInt() statement. This works fine for the days and months until you pass either a 08 (zero, eight) or a 09 (zero,nine). Here the resu开发者_StackOverflow社区lt of the parseInt() returns as 0 rather than an 8 or 9 respectively.
But this is only a problem with 08 and 09, passing numbers 01 to 07 returns 1 to 7 as expected. Similarly, when passing single digits, 1 to 9, to the function, parseInt() returns the appropriate value as an integer.Really struggling to fathom this one out. Conversely removing the parseInt statement completely seems to work however this leaves the dobNum value as a string which I don’t feel is particularly good practice.
Can anyone shed some light on this please? (this problem occurs in both firefox and IE) Many thanks, SMc
var DOBddOK = false;
var DOBmmOK = false;
var DOByyyyOK = false;
function validateDOB (dobNum, dmy) {
// Set Regexp based on dmy var.
if (dmy.length == 2) var reg = /^([0-9]{1,2})$/;
else var reg = /^([0-9]{4})$/;
var numOK = reg.test(dobNum);
alert("NumOK: "+numOK); //test
// If dobNum value passes regExp test then convert it to an integer
if (numOK) {
var numVar = parseInt(dobNum);
//var numVar = dobNum;
alert("NumVar: "+numVar); //test
}
alert("dmy: "+dmy); //test
switch (dmy) {
case "dd":
if (numOK && numVar <= 31 && numVar > 0) DOBddOK = true;
else DOBddOK = false;
break;
case "mm":
if (numOK && numVar <= 12 && numVar > 0) DOBmmOK = true;
else DOBmmOK = false;
break;
case "yyyy":
var d = new Date();
d = d.getFullYear();
if (numOK && numVar <= (d-18) && numVar >= (d-80)) DOByyyyOK = true;
else DOByyyyOK = false;
break;
}
}
When the parseInt
function finds a leading zero in the passed string, it will implicitly parse the number as octal.
It is always recommended to use the radix argument:
parseInt('08', 10); // 8
parseInt('09', 10); // 9
This have caused so many problems over the time that in the new version of the language standard, ECMAScript 5, the implicit octal detection has been removed from the parseInt
algorithm. But ES5 is not completely supported yet.
There are other ways to convert a String to Number in JavaScript that do not present this problem, for example:
The unary plus operator:
+'08'; // 8
The Number constructor called as a Function:
Number('08'); // 8
In my opinion parseInt
and the later two ways I've described have a (subtly) different semantic meaning.
The former is clearly parsing, for example:
parseInt('12px'); // 12
parseInt('10yo'); // 10
parseInt('1111', 2); // 15
And the last two ways are for doing String to Number type conversion.
It's treating strings with a leading zero as octal, you can specify a second parameter giving the radix as 10.
See link text
Try to use the radix parseInt(dobNum, 10)
to parse your integer in base 10
精彩评论