isNaN bug

Discussion in 'Javascript' started by David Wilhelm, Feb 21, 2008.

  1. 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
    David Wilhelm, Feb 21, 2008
    #1
    1. Advertising

  2. David Wilhelm <> writes:

    > 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.


    --
    Joost Diepenmaat | blog: http://joost.zeekat.nl/ | work: http://zeekat.nl/
    Joost Diepenmaat, Feb 21, 2008
    #2
    1. Advertising

  3. David Wilhelm

    Evertjan. Guest

    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>


    --
    Evertjan.
    The Netherlands.
    (Please change the x'es to dots in my emailaddress)
    Evertjan., Feb 21, 2008
    #3
  4. Henry <> writes:

    > On Feb 21, 4:46 pm, Joost Diepenmaat wrote:
    >> David Wilhelm writes:
    >> > 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.

    --
    Joost Diepenmaat | blog: http://joost.zeekat.nl/ | work: http://zeekat.nl/
    Joost Diepenmaat, Feb 21, 2008
    #4
  5. David Wilhelm

    dhtml Guest

    On Feb 21, 9:27 am, Henry <> wrote:
    > On Feb 21, 4:46 pm, Joost Diepenmaat wrote:
    >
    > > David Wilhelm writes:
    > > > 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;
    dhtml, Feb 21, 2008
    #5
  6. In comp.lang.javascript message <fd7220b2-393a-4d14-a2c7-b3014a780ac8@s8
    g2000prg.googlegroups.com>, Thu, 21 Feb 2008 08:41:47, David Wilhelm
    <> posted:
    >
    >isNaN([6]) is false
    >


    But

    isNaN([,6]) is true

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

    --
    (c) John Stockton, nr London, UK. ?@merlyn.demon.co.uk Turnpike v6.05 MIME.
    Web <URL:http://www.merlyn.demon.co.uk/> - FAQqish topics, acronyms & links;
    Astro stuff via astron-1.htm, gravity0.htm ; quotings.htm, pascal.htm, etc.
    No Encoding. Quotes before replies. Snip well. Write clearly. Don't Mail News.
    Dr J R Stockton, Feb 21, 2008
    #6
  7. On Feb 21, 12:27 pm, Henry <> wrote:
    > On Feb 21, 4:46 pm, Joost Diepenmaat wrote:
    >
    > > David Wilhelm writes:
    > > > 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.
    David Wilhelm, Feb 21, 2008
    #7
  8. David Wilhelm <> writes:

    > On Feb 21, 12:27 pm, Henry <> wrote:
    > 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'));


    --
    Joost Diepenmaat | blog: http://joost.zeekat.nl/ | work: http://zeekat.nl/
    Joost Diepenmaat, Feb 21, 2008
    #8
  9. David Wilhelm

    Guest

    On Feb 21, 12:21 pm, Joost Diepenmaat <> wrote:
    > David Wilhelm <> writes:
    > > On Feb 21, 12:27 pm, Henry <> wrote:
    > > 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'));
    >
    > --
    > Joost Diepenmaat | blog:http://joost.zeekat.nl/| work:http://zeekat.nl/


    What about this?:

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

    alert(isNumber(2)); // true
    alert(isNumber([2])); // false
    alert(isNumber(NaN)); // false
    , Feb 21, 2008
    #9
  10. writes:

    > 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

    --
    Joost Diepenmaat | blog: http://joost.zeekat.nl/ | work: http://zeekat.nl/
    Joost Diepenmaat, Feb 21, 2008
    #10
  11. Dr J R Stockton <> writes:

    > 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 :)

    --
    Joost Diepenmaat | blog: http://joost.zeekat.nl/ | work: http://zeekat.nl/
    Joost Diepenmaat, Feb 22, 2008
    #11
  12. David Wilhelm

    RobG Guest

    On Feb 22, 6:45 am, wrote:
    > On Feb 21, 12:21 pm, Joost Diepenmaat <> wrote:
    > > David Wilhelm <> writes:
    > > >
    > > > 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'));

    >
    > 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.


    --
    Rob
    RobG, Feb 22, 2008
    #12
  13. On Feb 21, 6:44 pm, RobG <> wrote:
    > On Feb 22, 6:45 am, wrote:
    >
    > > On Feb 21, 12:21 pm, Joost Diepenmaat <> wrote:
    > > > David Wilhelm <> writes:

    >
    > > > > 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'));

    >
    > > 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'


    Agreed. I usually use typeof as an operator. I typed that example up a
    bit too quickly.
    Nick Fletcher, Feb 22, 2008
    #13
  14. Nick Fletcher wrote:
    > On Feb 21, 6:44 pm, RobG <> wrote:
    >> On Feb 22, 6:45 am, wrote:
    >>> On Feb 21, 12:21 pm, Joost Diepenmaat <> wrote:
    >>>> David Wilhelm <> writes:
    >>>>> 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'));
    >>> 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'

    >
    > 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
    --
    Anyone who slaps a 'this page is best viewed with Browser X' label on
    a Web page appears to be yearning for the bad old days, before the Web,
    when you had very little chance of reading a document written on another
    computer, another word processor, or another network. -- Tim Berners-Lee
    Thomas 'PointedEars' Lahn, Feb 24, 2008
    #14
  15. RobG wrote:
    > On Feb 22, 6:45 am, wrote:
    >> On Feb 21, 12:21 pm, Joost Diepenmaat <> wrote:
    >>> David Wilhelm <> writes:
    >>>> 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'));

    >> What about this?:
    >>
    >> function isNumber(x) {
    >> return (typeof(x) == 'number' && !isNaN(x));

    >
    > 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
    --
    Prototype.js was written by people who don't know javascript for people
    who don't know javascript. People who don't know javascript are not
    the best source of advice on designing systems that use javascript.
    -- Richard Cornford, cljs, <f806at$ail$1$>
    Thomas 'PointedEars' Lahn, Feb 24, 2008
    #15
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. =?Utf-8?B?c2lhag==?=

    isNaN function jscript

    =?Utf-8?B?c2lhag==?=, Mar 8, 2005, in forum: ASP .Net
    Replies:
    4
    Views:
    2,746
    =?Utf-8?B?c2lhag==?=
    Mar 8, 2005
  2. Christopher Benson-Manica
    Replies:
    0
    Views:
    413
    Christopher Benson-Manica
    May 11, 2004
  3. Skybuck Flying
    Replies:
    5
    Views:
    831
  4. Priya

    isinf() & isnan()

    Priya, Sep 19, 2006, in forum: C++
    Replies:
    2
    Views:
    615
    Priya
    Sep 19, 2006
  5. jacob navia

    isnan() for complex data

    jacob navia, Feb 4, 2008, in forum: C++
    Replies:
    5
    Views:
    516
    Barry
    Feb 5, 2008
Loading...

Share This Page