问题
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