Domanda

Can someone please explain Why does Boolean(Infinity) is true but Boolean(NaN) is false?

Infinity || true

expression gives Infinity. `

NaN || true

` expression gives true.

È stato utile?

Soluzione

EMCAScript's logical OR casts its arguments to booleans using ToBoolean, which behaves as follows for numbers:

The result is false if the argument is +0, −0, or NaN; otherwise the result is true.

Thus, NaN becomes false, and Infinity becomes true. We sometimes refer to values as "truthy" or "falsy" depending on whether ToBoolean coerces them to true or false.

If you look at the spec for logical OR, the operator returns either the original lval or rval (left/right value), not its coerced boolean value. This is why (Infinity || true) == Infinity: the value of ToBoolean(lval) is true, so the expression returns the original lval.

Altri suggerimenti

This is a combination of two things: How "truthiness" is tested, and the curiously-powerful || operator.

  1. Truthiness: When using boolean logic in JavaScript, the arguments are converted to booleans. How this happens is covered in the spec, Section 9.2, which says amongst other things that when converting a value to a boolean from a number:

    The result is false if the argument is +0, −0, or NaN; otherwise the result is true.

  2. Curiously-powerful || operator: JavaScript's || operator does not evalute to true or false. It evaluates to its left-hand argument if that argument is "truthy," or its right-hand argument otherwise. So 1 || 0 is 1, not true; and false || 0 is 0 (even though 0 is falsey). So for the same reason, Infinity || true is Infinity, not true.

    This feature of || is incredibly powerful. You can do things like this, for instance:

    someElement.innerHTML = name || "(name missing)";
    

    ...and if name is not undefined, null, 0, "", false, or NaN, innerHTML gets set to name; if it is one of those values, it gets set to "(name missing").

    Similarly, you can have default objects:

    var obj = someOptionalObject || {};
    

    The uses are many and varied. You do have to be careful, though, that you don't unintentionally weed out valid falsey values like 0 when you're defaulting things in this way. :-)

    A chain of || operators strung together (a || b || c) returns the first truthy argument in the chain, or the last argument if none of them are truthy.

    The && operator does something quite similar: It returns its first argument if that argument is falsey, or its right argument otherwise. So 0 && 1 is 0, not false. 2 && 1 is 1, because 2 is not falsey. And chains of them return the first falsey arg, or the last arg, which is handy when you need to get a property from a nested object:

    var prop = obj && obj.subobj && obj.subobj.property || defaultValue;
    

    ...returns obj if it's falsey, or obj.subobj if it's falsey, or obj.subobj.property if neither of the first two is falsey. Then the result of that || defaultValue gives you either the property, or the default.

It is because NaN stands for "not a number", practically speaking it has no value. In certain languages (like Java, AS3) this is the default value of an uninitialized floating point variable. However Infinity (no matter positive/negative) is a valid representation of an unreachable value.

When you convert their numeric value to boolean, it has come into effect.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top