3

When I use in operator in javascript, I find something strange. It seems that in uses a similar rule as == but not the same. Here are some tests:

var obj = {1: 'a', 3: 'b'};
1 in obj     //=> true
'1' in obj   //=> true
[1] in obj   //=> true
true in obj  //=> false

Because 1 == '1' == [1] == true, so it seems that operand will be cast to string or integer type before comparison with in operator except for boolean. So I wonder am I right?

foolyoghurt
  • 347
  • 3
  • 14
  • 1
    Nothing to do with comparison there. Anyway, this leads to an interesting JavaScript fact: *all* property names are internally strings. – user2864740 Apr 27 '14 at 03:54
  • 2
    @user2864740 At least, until [`Map`s](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) become regularly available. – Jonathan Lonowski Apr 27 '14 at 03:57

2 Answers2

2

You're correct. It will first convert the left operand to a string, note however that the rules for converting between various data types in JavaScript are a lot more subtle than you might think.

true == "true"   //=> true
true == "1"      //=> true
"true" == "1"    //=> false

The precise rules are fairly complicated*, but the important thing to remember here is that when a Boolean is converted directly to a string, this is the result:

true.toString()  //=> "true"
false.toString() //=> "false"

So this is exactly the behavior you should expect, for example:

var obj = { "true": "a", "false": "b" };
true in obj      //=> true
false in obj     //=> true
1 in obj         //=> false

* See Does it matter which equals operator (== vs ===) I use in JavaScript comparisons?

Community
  • 1
  • 1
p.s.w.g
  • 146,324
  • 30
  • 291
  • 331
1

They appear to be different contexts.

These check keys, where true isn't a key.

1 in obj     //=> true
'1' in obj   //=> true
[1] in obj   //=> true
true in obj  //=> false

1 == '1' == [1] == true

This checks bit value where 1 is true.

0 == false should be true.

visc
  • 4,794
  • 6
  • 32
  • 58