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?
When you create a custom class or struct, you should override the ToString method in order to provide information about your type to client code. For information about how to use format strings and other types of custom formatting with the ToString method, see Formatting Types.
Expected output As you can see above, we can override the toString() method of the Student class to get a meaningful presentation of the object. In conclusion, it's a good idea to override toString() , as we get proper and customized output when an object is used.
So, whenever you use or print a reference variable of type in which toString() method is not overrided, you will get an output like above. You will not get what the object actually has in it. There will be no information about state or properties of an object.
We can override the toString() method in our class to print proper output. For example, in the following code toString() is overridden to print the “Real + i Imag” form.
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"
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With