问题
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"
});
来源:https://stackoverflow.com/questions/42886953/whats-the-recommended-way-to-customize-tostring-using-symbol-tostringtag-or-ov