I'm confused on what to implement, first, my module will use Babel so there are no problems implementing ES6 features, second, I will use the class
construct to create class and not the old prototypal method. So now, I'm confused if I'm going to override toString (which is the old way) or just implement Symbol.toStringTag like what this MDN documentation said, https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/toStringTag
So what is the recommended way?
可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
回答1:
They're for different things entirely.
If you're trying to define the string version of your object, provide a toString
method.
If you're trying to add information to your class that Object.prototype.toString
will use to build its "[object XYZ]"
string, provide a method whose name is the value of Symbol.toStringTag
.
Here's an illustration of the difference:
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]
If we hadn't provided that get [Symbol.toStringTag]
, that last line would output "[object Object]"
rather than "[object Example]"
.
Note that it doesn't have to be a getter, it can be a data property instead. Since you're using Babel, you could define it like this if you include Public Class Fields support (currently Stage 2):
class Example {
constructor(x) {
this.x = x;
}
toString() {
return `Example[x=${this.x}]`;
}
[Symbol.toStringTag] = "Example";
}
...although of course it would be writable. Alternately:
class Example {
constructor(x) {
this.x = x;
}
toString() {
return `Example[x=${this.x}]`;
}
}
Object.defineProperty(Example.prototype, Symbol.toStringTag, {
value: "Example"
});