0

I came across an interview question as below but I could not figure out how javascript internals interprets the following code.

Can someone please explain how the JS engine is interpreting for in? Does that mean "in" is not a check for values being contained in an array?

const array = [1,2,3,4,5];

console.log(0 in array)


console.log("0" in array)


console.log(4 in [1,2,3,4,5])


console.log(4 in [1,2,3,4])
Not A Bot
  • 2,474
  • 2
  • 16
  • 33
Anmol
  • 91
  • 1
  • 3
  • 10
  • 2
    the last one is not looking for the value `4` it's looking for the _index_ 4 which doesnt exist – Jamiec Apr 30 '21 at 11:36
  • The `in` operator works on keys, not values. And keys are strings (also for arrays, though you'd usually notnuse that) – Jonas Wilms Apr 30 '21 at 11:37
  • I don't know javascript, but I'd guess that a) arrays are objects and element indexes are properties of the object, b) `in` looks if this property exists on an object and c) the usual javascript type coercion "magic" – Sergio Tulentsev Apr 30 '21 at 11:37
  • 1
    **None** of those uses "for in" as the title suggests. `for-in` and `in` are completely separate from each other. – T.J. Crowder Apr 30 '21 at 11:38

4 Answers4

3

in keyword in this case is a fast way to check whether the value on the right has a property given on the left.

Explanation of the examples from the question:

const array = [1,2,3,4,5];

0 in array
true

true is because the array variable contains the array object containing an element at the 0 index (the value is 1 – you can get it with array[0])

"0" in array
true

true is because the array variable contains the array object containing an element at the "0" key. JavaScript arrays are in fact objects storing elements using string property keys. Value 1 in this case is stored as a "0" property that can be also accessed by a number 0 index (as mentioned above).

4 in [1,2,3,4,5]
true

true is because the [1,2,3,4,5] array contains an element at the 4 index (value 5)

4 in [1,2,3,4]
false

false is because the [1,2,3,4] array does not contain an element at the 4 index.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
Terite
  • 1,097
  • 13
  • 23
  • `JavaScript arrays allows querying by an index given in a string form`. Actually, Javascript converts all object keys to string internally. – Wiktor Zychla Apr 30 '21 at 11:47
  • @WiktorZychla - Except Symbols. :-) – T.J. Crowder Apr 30 '21 at 11:48
  • @T.J.Crowder: correct, thanks :) – Wiktor Zychla Apr 30 '21 at 11:52
  • @Terite: it would be great if you could correct this in your answer to not to confuse future readers who somehow miss the comment section under your answer. Thanks. – Wiktor Zychla Apr 30 '21 at 11:53
  • @T.J. Crowder thanks for correcting me! Indeed I wasn't precise enough. I hope it's OK not to mention the Symbol case simplifying that "arrays are in fact objects storing elements as a string property values". Let's keep in mind that the question was on the beginner level. – Terite Apr 30 '21 at 21:43
  • Great edit!! (I can't upvote a second time. :-) ) I completely agree, no need to go into Symbols in the answer (since you don't say *all* property keys are strings). I hope you don't mind, I changed the new language slightly. – T.J. Crowder May 01 '21 at 07:12
2

Can someone please explain how the JS engine is interpreting for in?

None of those examples uses for-in, which looks like this:

for (const key in something)

They just use the in operator, which is something else entirely (though, perhaps, somewhat related).

Two things come into play in that code:

  • The in operator checks to see if the property named on the left (the name is converted to string if needed) exists in the object on the right (on the object itself, or on any of its prototypes).
  • Arrays are objects. An array index is actually a property name.

Picking up on that second point, let's look at the array [1,2,3,4,5]:

+−−−−−−−−−−−−−−−+
|    (array)    |
+−−−−−−−−−−−−−−−+
| "length":   5 | Property name is "length", value is 5
| "0":        1 | Property name is "0", value is 1
| "1":        2 |
| "2":        3 |
| "3":        4 |
| "4":        5 |
| [[Prototype]] |−−−−>Array.prototype, which has various methods
+−−−−−−−−−−−−−−−+

Based on that information:

const array = [1,2,3,4,5];
console.log(0 in array);

in converts 0 to "0" and checks for a property with that name on array. There is one, so the result is true.

const array = [1,2,3,4,5];
console.log("0" in array);

in checks for a property called "0" property on array. There is one, so the result is true.

console.log(4 in [1,2,3,4,5]);

in converts 4 to "4" and checks for a property with that name on [1,2,3,4,5]. There is one, so the result is true.

console.log(4 in [1,2,3,4]);

in converts 4 to "4" and checks for a property with that name on [1,2,3,4]. There isn't one, so the result is false.


The conversions of numbers to strings mentioned above are per the specification, but JavaScript engines optimize arrays where possible, and if dealing with such an optimized array, it can avoid converting the number to string before doing the lookup.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
0

If you are logging for(let i in [1,2,3,4]) you will see that only the indexes of the array will be logged. Since [1,2,3,4] has only index 3, 4 will result false, the other options are true.

vazsonyidl
  • 451
  • 3
  • 7
0

Perhaps this clears it up, if we look at objects not arrays you see in is actually looking to see if a property exists in an object

const obj = { foo: "bar"}
console.log( "foo" in obj )
console.log( "bar" in obj )

An array is just another type of object, which has properties that look numeric.

So your console.log(4 in [1,2,3,4]) is looking whether a property of 4 exists, not a value of 4 exists.

Jamiec
  • 133,658
  • 13
  • 134
  • 193