Skip to content Skip to sidebar Skip to footer

What's The Recommended Way To Customize ToString? Using Symbol.toStringTag Or Overriding ToString?

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 no

Solution 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"
});

Post a Comment for "What's The Recommended Way To Customize ToString? Using Symbol.toStringTag Or Overriding ToString?"