Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ToPrimitive Abstract operation clarification #1328

Open
jfet97 opened this issue Aug 6, 2018 · 2 comments
Open

ToPrimitive Abstract operation clarification #1328

jfet97 opened this issue Aug 6, 2018 · 2 comments

Comments

@jfet97
Copy link

jfet97 commented Aug 6, 2018

Book: Types & Grammar

Chapter 4: Coercion

ToString subchapter says:
"But as shown earlier, if an object has its own toString() method on it, and you use that object in a string-like way, its toString() will automatically be called, and the string result of that call will be used instead.

Note: The way an object is coerced to a string technically goes through the ToPrimitive abstract operation (ES5 spec, section 9.1), but those nuanced details are covered in more detail in the ToNumber section later in this chapter, so we will skip over them here."

ToNumber subchapter says:
"To convert to this primitive value equivalent, the ToPrimitive abstract operation (ES5 spec, section 9.1) will consult the value (using the internal DefaultValue operation -- ES5 spec, section 8.12.8) in question to see if it has a valueOf() method. If valueOf() is available and it returns a primitive value, that value is used for the coercion. If not, but toString() is available, it will provide the value for the coercion."

At this point, what if I use this object like a string?

var obj = {
    valueOf : function valueOf() { 
    return "valueOf"
    }, 
    toString : function toString() { 
    return "toString"
    }
}

"hi " + obj; 

ToString subchapter let me think that toString() method will be called, but ToNumber subchapter is clearer and I understand that toValue() method, if it exist, will be called instead of toString() method.
And that's what happens:

"hi " + obj; // "hi valueOf"

Now let's move on to the Explicitly: Strings <--> Numbers (sub?)subchaper where you can read:
"String(..) coerces from any other value to a primitive string value, using the rules of the ToString operation discussed earlier."
This is not completely true, because:

String(obj);

will output "toString", ignoring valueOf() method.
So, the sentence I reported from Explicitly: Strings <--> Numbers (sub?)subchaper caused me to expect the same behaviour explained into ToString subchapter with ToNumber subchapter reference.

I'm not an expert, I'm studying JS using your books so interpret ES5 standard is quite hard for me, but it seems that the [DefaultValue]] internal method of an Object is called with an hint (String/Number) and that hint specifies if valueOf() metod has to be ignored. By default the hint is Number, so maybe a statement like:

"hi " + obj; 

won't set that hint to String, as it seems to do:

String(obj);

It could be that ES6 changed this behaviour? Maybe before ES6 the previous instructions led to the same result.

@getify
Copy link
Owner

getify commented Aug 6, 2018

You are correct about the hints. I didn't get into that detail into the book, as it seemed too deep even for a chapter that's all about the deep details. ;-)

@jfet97
Copy link
Author

jfet97 commented Aug 6, 2018

Ahahaha I understand! Sincerely this part of the book has led me to misunderstand more than one times the real behavior of JS...but I'm not a writer, I understand that it is not easy at all 😅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants