Within The Standard Javascript Es6 Environment, When Is .tostring() Ever Called?
Solution 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
.
// Preparationlet obj = {
toString() {
this.i = (this.i||0) + 1; // counterconsole.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);
newDate(obj);
newRegExp(obj);
newNumber(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.
Solution 2:
To illustrate some perhaps more common cases:
- String interpolation (probably most useful)
- String addition or concatenation
- Creation of a symbol or string
- As a property key
- Used by
Array
'sjoin()
Inside of Node console:
> let foo = { a: 123, toString: function() { return`an object with value ${this.a}`; } };
> foo
{ a: 123, toString: [Function: toString] }
> foo.toString()
'an object with value 123'
> foo.a = 456;
456
> foo.toString()
'an object with value 456'
> `${foo}`'an object with value 456'
> "foo: " + foo
'foo: an object with value 456'
> "foo: ".concat(foo)
'foo: an object with value 456'
> let d = {};
> d[foo] = "hello";
'hello'
> d
{ 'an object with value 456': 'hello' }
> Symbol(foo)
Symbol(an object with value 456)
> String(foo)
'an object with value 456'
> let bar = Object.assign({}, foo); // clone
> bar.a = 789;
789
> [foo, bar].join(" - ")
'an object with value 456 - an object with value 789'
Post a Comment for "Within The Standard Javascript Es6 Environment, When Is .tostring() Ever Called?"