首页 > 解决方案 > 在标准 JavaScript ES6 环境中,什么时候调用过 .toString() ?

问题描述

我只发现.toString()调用的时间是字符串连接和字符串插值:

// 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'

据说,console.log打印出对象的字符串表示并应该使用toString(),但我不确定它是否toString()通常没有正确实现,console.log其他的也是如此:

> console.log(arr);
[ 1, 3, 5 ]

> console.log("arr is %s", arr);
arr is [ 1, 3, 5 ]

那么在 JavaScript 本身内部,什么toString()时候调用过呢?

我认为通过多态性,我们自己编写的任何内容都可以用来ourObj.toString()将对象的字符串表示为字符串。但我想知道在 JavaScript 本身(它的所有函数、库、类)中,何时toString()实际调用?

标签: javascriptecmascript-6tostring

解决方案


在 EcmaScript 语言规范的几个部分中,都提到了toString. 抽象操作OrdinaryToPrimitive中出现了一个重要用途:该函数将查找对象toStringvalueOf方法,并执行它。优先级可能受提示参数的影响。

反过来,OrdinaryToPrimitive被抽象操作调用ToPrimitive

ToPrimitiveToNumber, ToString, ToPropertyKey, 关系比较, 相等比较, 表达式求值,Date构造函数, 几种字符串化方法, 如toJSON, ...等调用。

事实上,该语言充满了将要执行的内部操作ToPrimitive。该规范有 200 多个对ToString.

例子

这是一个带有toString方法实现的对象,以证明它toString是在内部调用的。

然后按照每个触发器的几个表达式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.

toString()如果valueOf定义了obj一个返回原始值的方法,其中一些不会触发。


推荐阅读