I had a similar condition required to check if the String type constructor name is "String"
or "string"
.
I am lost with outputs of following JS code:
(typeof([].constructor.name)).constructor.name
"String"
typeof([].constructor.name).constructor.name
"string"
But when I test output of following code I get more confused:
(typeof([].constructor.name))
"string"
typeof([].constructor.name)
"string"
"string".constructor.name
"String"
According to my understanding the output should always be "String".
Can anyone put some bright light on what I am missing or whats going wrong with above code?
After playing with the console I found the following, it seems like typeof(a).b
might be equivalent to typeof (a).b
so it seems like the following are equivalent
(typeof([].constructor.name)).constructor.name
(typeof [].constructor.name).constructor.name
However for the second example it seems like the following is executed
typeof([].constructor.name).constructor.name
typeof ([].constructor.name).constructor.name
The second parenthesis in the first example is acting as a grouping operator and that might be the reason of the weird results
"string"
and "String"
valuesAs you may already know we can access the name of a named function through the name
property
function A(){}
A.name // A
Also when you create a function behind the curtains an object is created which is accessible through the function's prototype
property, this object has a reference to the function itself through its constructor
property
function A(){}
A.prototype // {constructor: A}
A.prototype.constructor === A // true
Whenever you create an "instance" of a function its hidden [[Prototype]]
property (aka __proto__
) points to the prototype of the constructor so
[].__proto__ === Array.prototype // true
Since an empty array doesn't have the property constructor
defined on it, JS looks in the object pointed by __proto__
which for the empty array as seen above is the Array.prototype
which has a constructor
property therefore
[].constructor === Array // true
From this place the resolution of the operand gets trivial
[].constructor.name // "Array"
[].constructor.name.constructor === String // true
[].constructor.name.constructor.name // "String", i.e. the name of the `function String() {}`
So in your examples
(typeof [].constructor.name).constructor.name
// evaluated to
(typeof "Array").constructor.name
// evaluated to
"string".constructor.name
// evaluated to
String.name
// evaluated to
"String"
And for the second example
typeof ([].constructor.name).constructor.name
// evaluated to
typeof "String"
// evaluated to
"string"
Moral of the story: use typeof operator
instead of typeof()
.
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