自定义 toString 的推荐方式是什么?使用 Symbol.toStringTag 还是覆盖 toString?
What's the recommended way to customize toString? Using Symbol.toStringTag or overriding toString?
我对实现什么感到困惑,首先,我的模块将使用 Babel,因此实现 ES6 功能没有问题,其次,我将使用 class
构造来创建 class 和不是旧的原型方法。所以现在,我很困惑是要重写 toString(这是旧方法)还是像这个 MDN 文档所说的那样实现 Symbol.toStringTag,https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/toStringTag
那么推荐的方式是什么?
它们完全不同。
如果您尝试定义对象的字符串版本,请提供 toString
方法。
如果您尝试向 class 添加信息,Object.prototype.toString
将使用该信息构建其 "[object XYZ]"
字符串,请提供一个名称为 [=16 的值的方法=].
下面是差异的说明:
class Example {
constructor(x) {
this.x = x;
}
toString() {
return `Example[x=${this.x}]`;
}
get [Symbol.toStringTag]() {
return "Example";
}
}
const e = new Example(42);
console.log(e.toString()); // Example[x=42]
console.log(String(e)); // Example[x=42]
console.log(Object.prototype.toString.call(e)); // [object Example]
如果我们没有提供 get [Symbol.toStringTag]
,最后一行将输出 "[object Object]"
而不是 "[object Example]"
。
请注意,不一定是getter,它可以是数据属性。由于您使用的是 Babel,因此如果包含 Public Class Fields 支持(当前为第 2 阶段),则可以这样定义它:
class Example {
constructor(x) {
this.x = x;
}
toString() {
return `Example[x=${this.x}]`;
}
[Symbol.toStringTag] = "Example";
}
...当然它是可写的。或者:
class Example {
constructor(x) {
this.x = x;
}
toString() {
return `Example[x=${this.x}]`;
}
}
Object.defineProperty(Example.prototype, Symbol.toStringTag, {
value: "Example"
});
我对实现什么感到困惑,首先,我的模块将使用 Babel,因此实现 ES6 功能没有问题,其次,我将使用 class
构造来创建 class 和不是旧的原型方法。所以现在,我很困惑是要重写 toString(这是旧方法)还是像这个 MDN 文档所说的那样实现 Symbol.toStringTag,https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/toStringTag
那么推荐的方式是什么?
它们完全不同。
如果您尝试定义对象的字符串版本,请提供 toString
方法。
如果您尝试向 class 添加信息,Object.prototype.toString
将使用该信息构建其 "[object XYZ]"
字符串,请提供一个名称为 [=16 的值的方法=].
下面是差异的说明:
class Example {
constructor(x) {
this.x = x;
}
toString() {
return `Example[x=${this.x}]`;
}
get [Symbol.toStringTag]() {
return "Example";
}
}
const e = new Example(42);
console.log(e.toString()); // Example[x=42]
console.log(String(e)); // Example[x=42]
console.log(Object.prototype.toString.call(e)); // [object Example]
如果我们没有提供 get [Symbol.toStringTag]
,最后一行将输出 "[object Object]"
而不是 "[object Example]"
。
请注意,不一定是getter,它可以是数据属性。由于您使用的是 Babel,因此如果包含 Public Class Fields 支持(当前为第 2 阶段),则可以这样定义它:
class Example {
constructor(x) {
this.x = x;
}
toString() {
return `Example[x=${this.x}]`;
}
[Symbol.toStringTag] = "Example";
}
...当然它是可写的。或者:
class Example {
constructor(x) {
this.x = x;
}
toString() {
return `Example[x=${this.x}]`;
}
}
Object.defineProperty(Example.prototype, Symbol.toStringTag, {
value: "Example"
});