最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

equality - javascript truthy numbers - Stack Overflow

programmeradmin4浏览0评论

Based on these rules:

Falsy:

  • false
  • 0 (zero)
  • '' or "" (empty string)
  • null
  • undefinded
  • NaN (e.g. the result of 1/0)

Truthy: Everything else

I fail to find the correct explanation as to why in following tests, only number 1 evaluates to "true"

0 == true ("false")
1 == true ("true")
2 == true ("false")
othernumber == true ("false")

Based on these rules:

Falsy:

  • false
  • 0 (zero)
  • '' or "" (empty string)
  • null
  • undefinded
  • NaN (e.g. the result of 1/0)

Truthy: Everything else

I fail to find the correct explanation as to why in following tests, only number 1 evaluates to "true"

0 == true ("false")
1 == true ("true")
2 == true ("false")
othernumber == true ("false")
Share asked Sep 13, 2018 at 19:50 DavidDavid 436 bronze badges 3
  • 4 The == operator has its own rules for how different types are converted, and specifically x == true does not mean, "is x truthy?". – Pointy Commented Sep 13, 2018 at 19:51
  • if (2 == true) console.log('nope'); if (2) console.log('yes') – Eydrian Commented Sep 13, 2018 at 19:55
  • 1 "NaN (e.g. the result of 1/0)" Actually, the result of 1/0 is Infinity. NaN is what you get when you try to convert something (a string, for instance) to a number and it cannot be converted: Number("foo") is NaN, for instance. – T.J. Crowder Commented Sep 13, 2018 at 19:56
Add a ment  | 

6 Answers 6

Reset to default 5

The "truthy" and "falsy" rules only apply when the value itself is being used as the test, e.g.:

var str = "";
if (str) {
    // It's truthy
} else {
    // It's falsy
}

== has its own, different, set of rules for determining the loose equality of its operands, which are explained thoroughly in the spec's Abstract Equality Comparison algorithm:

  1. If Type(x) is the same as Type(y), then
    • Return the result of performing Strict Equality Comparison x === y.
  2. If x is null and y is undefined, return true.
  3. If x is undefined and y is null, return true.
  4. If Type(x) is Number and Type(y) is String, return the result of the parison x == ToNumber(y).
  5. If Type(x) is String and Type(y) is Number, return the result of the parison ToNumber(x) == y.
  6. If Type(x) is Boolean, return the result of the parison ToNumber(x) == y.
  7. If Type(y) is Boolean, return the result of the parison x == ToNumber(y).
  8. If Type(x) is either String, Number, or Symbol and Type(y) is Object, return the result of the parison x == ToPrimitive(y).
  9. If Type(x) is Object and Type(y) is either String, Number, or Symbol, return the result of the parison ToPrimitive(x) == y.
  10. Return false.

See the spec for the full details of the various abstract operations listed in there, although the names pretty much say what they do. (If you look at the spec, you'll see ! prior to ToNumber in various places; I've removed it above. It's not the logical NOT operator, it's a spec notation related to "abrupt pletions.")

Let's follow that through for your 2 == true example:

  1. The types aren't the same, so keep going
  2. x isn't null, so keep going
  3. x isn't undefined, so keep going
  4. Type(x) is indeed Number, but Type(y) is not String, so keep going
  5. Type(x) is not String, so keep going
  6. Type(x) is not Boolean, so keep going
  7. Type(y) is Boolean, so return the result of x == ToNumber(y)
    • ToNumber(true) is 1, and since 2 == 1 is false, the result is false

But notice that step 7 is different for your 1 == true example:

  1. Type(y) is Boolean, so return the result of x == ToNumber(y)
    • ToNumber(true) is 1, and since 1 == 1 is true, the result is true

It's a very interesting reason, according to this book, when you pare anything to a boolean like you are doing, for example in x == y it follows this pattern:

If Type(x) is Boolean, return the result of the parison ToNumber(x) == y.

If Type(y) is Boolean, return the result of the parison x == ToNumber(y).

Thus, when you pare 1 == true it's actually doing 1 == ToNumber(true) which then turns into 1 == 1, but when you do 2 == true it turns into 2 == 1 which is false fo course.

This and some other reasons given in the book suggest to not pare things to boolean values.

When you make a parison to a boolean, it doesn't matter if the value itself is truthy or falsy, since it is never turned into a booleam, but the boolean is coerced into a type that can be pared to the other side of the == operator.

I hope you find this answer satisfactory.

using == is different from if(something) This test will give you your expected results:

function truthyFalsyTest()
{
    if(0) 
    {
       console.log("true");
    }
    else
    {
        console.log("false");
    }

    if(1) 
    {
       console.log("true");
    }
    else
    {
        console.log("false");
    }

    if(2) 
    {
       console.log("true");
    }
    else
    {
        console.log("false");
    }

    if(2222) 
    {
       console.log("true");
    }
    else
    {
        console.log("false");
    }
}

truthyFalsyTest();

In JavaScript (==) is an equality operator operator where type conversion is done. The more strict (===) identity operator will not do type conversion.

For example, even though a number is not a boolean, you can use a numeric value where a boolean value is expected if using the (==) operator.

But, if you enforce the stricter (===) operator, you will see that '1 === true' will evaluate to false.

0 is false that doesn't mean othernumber will be true.. Simple example. If you use === in condition then you will see the false for all numbers.

(0 == true) // false
(1 == true) // true

It works fine. However, in below example, I have not used not operator (!) in the condition. So if condition is true it should print true else false. Still it will give you reverse result.

if(0){console.log("true")}else{console.log("false")} // false
if(1){console.log("true")}else{console.log("false")} // true
if(15){console.log("true")}else{console.log("false")} // true

Now if you convert numbers to Boolean then it will give the result what you were thinking.

Boolean(0) == true // false
Boolean(1) == true // true
Boolean(2) == true // true
Boolean(othernumber) == true // true

Thanks

Based on these rules: The issue here is that == does NOT operate by these rules. Whether something is truthy or not and how it behaves during equality tests are two different things. For the record a more correct test for truthyness would be

if (value) 
    return true;
else
    return false;

or even shorter - a direct conversion Boolean(value) (and the implicit conversion !!value.

However, during an equality test, both sides of == will be transformed to the same base type and then the actual test occurs. MDN has a list of rules for the conversion - straight from it a 1 == true uses a number and a boolean, therefore, the base type for both is number. The JavaScript environment will resolve this by calling ToNumber(booleanValue), so here is what the equality test actually tests

var convertedBooleanOperand = Number(true);

console.log("convertedBooleanOperand", convertedBooleanOperand);

In reality, 2 == true is converted to 2 == 1 which is false.

发布评论

评论列表(0)

  1. 暂无评论