Let's say we have an object by the variable name of obj
and ToPrimitive abstract method has been called on it implicitly. This implicit call happens when you do a comparison like this - obj == 5
|| false == obj
etc.
Basically when one of the operands in a ==
comparison is a primitive and other one is an object.
For our case let's say we have this comparison - [] == 9
.
The following is an attempt to clarify the working of toPrimitive as per spec :-
- First we check whether
typeof []
is object or not which it is in our case. - Now we check for hint which will be default here.
- Then we see if
toPrimitive
has been explicitly defined or not on the concerned object. Since it hasn't been for[]
, thenexoticToPrim
will beundefined
. - Now
OrdinaryToPrimitive([],number)
will be invoked for default hint. - Since in our case hint is number, following will happen:-
- Let methodNames be like a list of
["valueOf","toString"]
. - Loop over these methods and first check if method is callable (which both of the stated are)
- Check if result of [].method() is a primitive or not.
-
[].valueOf() = []
but[].toString() is ""
which being a primitive will be chosen.
- Let methodNames be like a list of
- So updated comparison will be
"" == 9
.
I am no expert in specs debunking but I think this is what is happening. Feel free to comment and correct me if there is any wrong conclusion derived here.
Top comments (2)
Nice post.
2 small suggestions -
It's probably better not to call it as
Symbol.toPrimitive(obj)
- someone might think that is a runnable code, but what you meant is the ToPrimtive abstract methodI think it's ok to skip the assert statements - it's probably there because the same function/algo can be called from multiple places and this will ensure that it is always called correctly. It doesn't change the algo itself.
Thanks for the suggestions. Updated the post :)
Some comments have been hidden by the post's author - find out more