Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding "in" keyword in Javascript

Tags:

javascript

In my attempt to really understand Javascript, rather than being a copy and paste Javascript googler, I'm going through Eloquent Javascript E-book and I happen to cross the following example:

var chineseBox = {};
chineseBox.content = chineseBox;
show("content" in chineseBox);
show("content" in chineseBox.content);

Surprisingly, they both output true. The book itself claims, "The operator in can be used to test whether an object has a certain property. It produces a boolean."

I understand that show("content" in chineseBox); is looking for a content property which it does have, its value being chineseBox. However, why does the second show() work?

To test further, I tried:

show("content" in chineseBox.content.content); //true

show("contents" in chineseBox.contents.content); //type error: undefined

show("contents" in chineseBox.content.contents); // invalid "in" operand

Question is basically, variable chineseBox{} doesn't have content property... or does it?

like image 548
bigbitecode Avatar asked Jan 12 '23 12:01

bigbitecode


2 Answers

The key is this line:

chineseBox.content = chineseBox;

This gives chineseBox a reference to itself. So:

show(chineseBox.content === chineseBox);

You should see this will also output true.

Therefore 'content' is in chineseBox as well as chineseBox.content (and chineseBox.content.content and so on) because they're all the same object, which does have a content property.


Let's look at your second and third examples. Why does one give a TypeError while the other complains about an invalid in operand?

In the second example, you have:

show("contents" in chineseBox.contents.content);

In order for the in operator to test whether the specified property ("contents") is in the specified object, it first has to evaluate what that object is. You get a type error because chineseBox.contents is undefined, and so you can't access its content property because there's no object to access.

Contrast this with the third example:

show("contents" in chineseBox.content.contents);

Now here, the in operator at least gets farther than it did in the second example. The chineseBox.content property does exist, and accessing its contents property gives you undefined. So there is no error there. But then you get an error with the in keyword itself because you can't check if a property is in undefined.

In other words, in the second example it's like you're asking "Are there any elves in Santa's house?" Santa doesn't exist, so there is no such place as "Santa's house." In the third example it's more like you're asking "Where is the oval office in Obama's brown house?" Obama exists, but he doesn't have a brown house.

like image 149
Dan Tao Avatar answered Jan 23 '23 20:01

Dan Tao


chineseBox.content = chineseBox;

Because of the self-reference, notice that chineseBox is the same object as chineseBox.content. Meaning chineseBox, chineseBox.content, chineseBox.content.content, chineseBox.content.content.content, ad infinitum, all refer to the same object.

show("content" in chineseBox);
show("content" in chineseBox.content);
show("content" in chineseBox.content.content);
show("content" in chineseBox.content.content.content);
show("content" in chineseBox.content.content.content.content);
show("content" in chineseBox.content.content.content.content.content);

(In your tests, beware the difference between content and contents with an 's'.)

like image 32
John Kugelman Avatar answered Jan 23 '23 20:01

John Kugelman