isNaN bug

D

David Wilhelm

I'm new to the almighty comp.lang.javascript... sorry if this is a
dumbass post, but I stumbled across this JS quirk today:

isNaN([6]) is false

so an array is a number - who knew?

Dave
 
J

Joost Diepenmaat

David Wilhelm said:
I'm new to the almighty comp.lang.javascript... sorry if this is a
dumbass post, but I stumbled across this JS quirk today:

isNaN([6]) is false

so an array is a number - who knew?

Erm, that means that array is Not a Number.
 
E

Evertjan.

David Wilhelm wrote on 21 feb 2008 in comp.lang.javascript:
I'm new to the almighty comp.lang.javascript... sorry if this is a
dumbass post, but I stumbled across this JS quirk today:

isNaN([6]) is false

so an array is a number - who knew?

Dave, I expect that you won't be content
with a list of names of people that knew?
Your assumption is wrong, so your Q is unanswerable.
There is no bug.

isNaN(x) returns false, if x CAN be converted to a number.

If you want to test if a value x is a number do (typeof x == 'number').

[6] is an object, and objects can have default properties.

It seems that the default property of an array object is conversion to a
string in the isNaN() case.

Try this:

<script type="text/javascript">
var a = [6,7];
var s = 's = ' + a;
document.write(s);
</script>

You see the array is comma delimited converted to a string.

So in isNaN([6]); the array object is converted to a string "6",
that can be converted to a number.

var s = isNaN([6]);
document.write(s); // false, because "6" CAN be converted to a number

var s = isNaN([6,7]);
document.write(s); // true, because "6,7" cannot be converted to a number



</script>
 
J

Joost Diepenmaat

Henry said:
David said:
I'm new to the almighty comp.lang.javascript... sorry if this is a
dumbass post, but I stumbled across this JS quirk today:
isNaN([6]) is false
so an array is a number - who knew?

Erm, that means that array is Not a Number.

You mean it (the false results) means that an (or rather this) array
is not Not a Number.

Oh yeah, oops. :)

Thanks for the clear explanation by the way, I hadn't realized till now
that array stringification could have this effect.
 
D

dhtml

David said:
I'm new to the almighty comp.lang.javascript... sorry if this is a
dumbass post, but I stumbled across this JS quirk today:
isNaN([6]) is false
so an array is a number - who knew?
Erm, that means that array is Not a Number.

You mean it (the false results) means that an (or rather this) array
is not Not a Number.
Correct. Those double negatives can be confusing.
But most arrays would return true. The issue here is that the - isNaN
- function applies the internal - ToNumber - function to the array,
which calls the - ToPrimative - function with the hint 'Number', that
calls the array's internal [[DefaultValue]] method with the hint
'Number', which starts off trying to call the array's -valueOf -
method, but because the valueOf - methods of arrays are inherited from
Object.prototype.valueOf it is the version that return the object
itself, so [[DefaultValue]] goes on to call the array's - toString -
method, that method returns the string "6" from the one element array,
and the string "6", when received by the - ToNumber - function,
happily type-converts to a non-NaN number.

Great explanation.

var six = {
valueOf: function() { return 6; }
};

isFinite(6);
isFinite(new Date);
isFinite(Number.prototype);

For comparison operators, it is useful.

new Date <= new Date;
 
D

Dr J R Stockton

In comp.lang.javascript message <fd7220b2-393a-4d14-a2c7-b3014a780ac8@s8
g2000prg.googlegroups.com>, Thu, 21 Feb 2008 08:41:47, David Wilhelm
isNaN([6]) is false

But

isNaN([,6]) is true

which shows that arrays should really start at Element Number One <G>.
 
D

David Wilhelm

David said:
I'm new to the almighty comp.lang.javascript... sorry if this is a
dumbass post, but I stumbled across this JS quirk today:
isNaN([6]) is false
so an array is a number - who knew?
Erm, that means that array is Not a Number.

You mean it (the false results) means that an (or rather this) array
is not Not a Number.

But most arrays would return true. The issue here is that the - isNaN
- function applies the internal - ToNumber - function to the array,
which calls the - ToPrimative - function with the hint 'Number', that
calls the array's internal [[DefaultValue]] method with the hint
'Number', which starts off trying to call the array's -valueOf -
method, but because the valueOf - methods of arrays are inherited from
Object.prototype.valueOf it is the version that return the object
itself, so [[DefaultValue]] goes on to call the array's - toString -
method, that method returns the string "6" from the one element array,
and the string "6", when received by the - ToNumber - function,
happily type-converts to a non-NaN number.

Thanks for the explanation. I guess I'll just use 'typeof' to
determine if something is a number.
 
J

Joost Diepenmaat

David Wilhelm said:
Thanks for the explanation. I guess I'll just use 'typeof' to
determine if something is a number.

but typeof(NaN) == 'number'.

var i =NaN;
alert(isNaN(i)+" "+(typeof(i)!='number'));
 
T

titosrevenge

but typeof(NaN) == 'number'.

var i =NaN;
alert(isNaN(i)+" "+(typeof(i)!='number'));

What about this?:

function isNumber(x) {
return (typeof(x) == 'number' && !isNaN(x));
}

alert(isNumber(2)); // true
alert(isNumber([2])); // false
alert(isNumber(NaN)); // false
 
J

Joost Diepenmaat

What about this?:

function isNumber(x) {
return (typeof(x) == 'number' && !isNaN(x));
}

alert(isNumber(2)); // true
alert(isNumber([2])); // false
alert(isNumber(NaN)); // false

As far as I can tell, that would work. Note that both Infinities would
return true, which may or may not be what you want in any specific
application.

IOW: isNumber(1/0) == isNumber(-1/0) == true
 
J

Joost Diepenmaat

Dr J R Stockton said:
isNaN([,6]) is true

which shows that arrays should really start at Element Number One <G>.

You have recieved the reward for "funniest argument for 1-based arrays"
(r) year 2008.

Don't drink it all in one place :)
 
R

RobG

What about this?:

function isNumber(x) {
return (typeof(x) == 'number' && !isNaN(x));

Is the use of a pseudo-call operator considered "best practice"?
There was greate debate about that some time ago, I don't think it was
conclusive whether to use it or not. I think it is much better to
write:

typeof x == 'number'

so that there is no confusion: typeof is an operator, not a function.
If it is considered bettter to use brackets around the expression,
would you write things like:

var p, i=0;
for (p in(obj)) {
++(i);
}

}

alert(isNumber(2)); // true
alert(isNumber([2])); // false
alert(isNumber(NaN)); // false

and:

alert(isNumber('2')); // false


which may (or may not) be what the OP expects.
 
N

Nick Fletcher

Is the use of a pseudo-call operator considered "best practice"?
There was greate debate about that some time ago, I don't think it was
conclusive whether to use it or not. I think it is much better to
write:

typeof x == 'number'

Agreed. I usually use typeof as an operator. I typed that example up a
bit too quickly.
 
T

Thomas 'PointedEars' Lahn

Nick said:
Agreed. I usually use typeof as an operator. I typed that example up a
bit too quickly.

It would seem that there is a pattern, as you can only use `typeof' as an
operator and as nothing else, because it *is* an operator. Maybe you meant
to say you usually write a `typeof' operation without parentheses around the
operand and (necessarily) with whitespace between operator and operand.


PointedEars
 
T

Thomas 'PointedEars' Lahn

RobG said:
Is the use of a pseudo-call operator considered "best practice"?

I find your notion that there could be such a thing as a "pseudo-call
operator" rather confusing. There is an operand that is an expression
with parentheses.
There was greate debate about that some time ago, I don't think it was
conclusive whether to use it or not. I think it is much better to
write:

typeof x == 'number'

so that there is no confusion: typeof is an operator, not a function.

ACK


PointedEars
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top