问题
I only found that the time .toString() is called is with string concatenation and string interpolation:
// Inside of Node:
> let arr = [1,3,5];
> arr.toString()
'1,3,5'
> "" + arr
'1,3,5'
> arr + ""
'1,3,5'
> `${arr}`
'1,3,5'
Supposedly, console.log prints out the string representation of the object and is supposed to use toString(), but I am not sure whether it is toString() not properly implemented usually, so console.log does something else:
> console.log(arr);
[ 1, 3, 5 ]
> console.log("arr is %s", arr);
arr is [ 1, 3, 5 ]
So inside the JavaScript itself, when is toString() ever called?
I think by polymorphism, anything we write ourselves, we can use ourObj.toString() to get the string representation of our object as string. But I wonder within JavaScript itself (all its function, libraries, classes), when is toString() actually invoked?
回答1:
In several sections of the EcmaScript language specification, there is mention of toString. One important use occurs in the abstract operation OrdinaryToPrimitive: this function will look for the object's toString or valueOf method, and execute it. The precedence can be influenced by a hint argument.
In turn, OrdinaryToPrimitive is called by the abstract operation ToPrimitive
ToPrimitive is called by ToNumber, ToString, ToPropertyKey, relational comparison, equality comparison, evaluation of expressions, the Date constructor, several stringification methods, like toJSON, ...etc.
In fact, the language is soaked with internal operations that will get to executing ToPrimitive. The specification has 200+ references to ToString.
Examples
Here is a object with a toString method implementation in order to prove that toString is called internally.
Then follow a few expressions that each trigger toString.
// Preparation
let obj = {
toString() {
this.i = (this.i||0) + 1; // counter
console.log("call #" + this.i);
return "0";
}
};
// Trigger toString via several constructs
({})[obj];
1 < obj;
1 == obj;
1 + obj;
1 - obj;
+obj;
Math.abs(obj);
parseInt(obj);
new Date(obj);
new RegExp(obj);
new Number(obj);
Symbol(obj);
"".localeCompare(obj);
[obj, null].sort();
[obj].join();
`${obj}`;
setTimeout(obj); // Not standard EcmaScript environment, but defined in the agent.
Some of these would not trigger toString() if there were a valueOf method defined on obj which would return a primitive value.
来源:https://stackoverflow.com/questions/59435952/within-the-standard-javascript-es6-environment-when-is-tostring-ever-called