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?
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.
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'.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With