Why is the 'in' operator throwing an error with a string literal instead of logging false?
In a sense it is a matter of timing. String literals do not have any properties. The reason that you can call methods and lookup properties on primitive strings is because JavaScript automatically wraps the string primitive in a String
object when a method call or property lookup is attempted. JavaScript does not interpret the in
operator as a method call or property lookup so it does not wrap the primitive in an object and you get an error (because a string primitive is not an object).
See Distinction between string primitives and String objects
Also, the same docs referenced in your question specifically note that using in
on a string primitive will throw an error.
You must specify an object on the right side of the
in
operator. For example, you can specify a string created with theString
constructor, but you cannot specify a string literal.
It throws an error because in is an operator for objects:
prop in object
but when you declare a string as ``
(` string(template) literals) or "" ''
(",' string literals) you don't create an object.
Check
typeof new String("x")
("object")
and
typeof `x`
("string").
Those are two different things in JavaScript.
JavaScript operator in
only applicable to an Object
s instances.
When you using constructor new String('abc')
this will causing creating of a String
object instance.
In other side, when you using only string literals or call function String('abc')
without new
it creates an string primitive. (like Number
and Boolen
)
Some behaviour of primitives and objects is differrent, look at this simple example's output:
console.log(typeof (new String('ddd'))) // "object"
console.log(typeof ('ddd')) // "string"
console.log(eval('1 + 2')) // 3
console.log(eval(new String('1 + 2'))) // {"0":"1","1":" ","2":"+","3":" ","4":"2"}
In code where you use methods on string primitives javascript engine automatically wraps primitives with corresponding objects to perform methods call.
But in
it is not an method call, its language operator an in this case wrapping is not applied.
PS: Sorry for my english.