自定义toString的推荐方法是什么?使用Symbol.toStringTag或覆盖toString?

时间:2017-03-19 13:09:13

标签: javascript ecmascript-6 es6-class

我对实现什么感到困惑,首先,我的模块将使用Babel,因此实现ES6功能没有问题,其次,我将使用class构造来创建类而不是旧的原型方法。所以现在,我很困惑,如果我要覆盖toString(这是旧方法)或只是实现Symbol.toStringTag,就像这个MDN文档所说的那样,https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/toStringTag 那么推荐的方式是什么?

1 个答案:

答案 0 :(得分:16)

他们完全不同的事情。

如果您尝试定义对象的字符串版本,请提供toString方法。

如果您尝试向Object.prototype.toString用于构建其"[object XYZ]"字符串的班级添加信息,请提供名称为Symbol.toStringTag的值的方法。< / p>

以下是差异的说明:

&#13;
&#13;
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]
&#13;
&#13;
&#13;

如果我们没有提供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"
});