Каков рекомендуемый способ настройки toString? Использование Символа.toStringTag или переопределение toString?


Я не знаю, что реализовать, во-первых, мой модуль будет использовать Babel, поэтому нет проблем с реализацией функций ES6, во-вторых, я буду использовать конструкцию class для создания класса, а не старый прототипный метод. Так что теперь я в замешательстве, если я собираюсь переопределить toString (что является старым способом) или просто реализовать Symbol.toStringTag нравится то, что говорится в этой документации MDN, https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/toStringTag Так что же такое рекомендуемый способ?

1 6

1 ответ:

Они предназначены для совершенно разных вещей.

Если вы пытаетесь определить строковую версию объекта, укажите метод toString.

Если вы пытаетесь добавить в свой класс информацию, которую Object.prototype.toString будет использовать для построения своей строки "[object XYZ]", укажите метод, имя которого является значением Symbol.toStringTag.

Вот иллюстрация разницы:

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]

Если бы мы не предусмотрели, что get [Symbol.toStringTag], то последняя строка выводила бы "[object Object]", а не "[object Example]".

Обратите внимание, что он не должен быть геттером, вместо этого он может быть свойством данных. Поскольку вы используете Babel, вы можете определить его следующим образом, если вы включаете открытые поля класса поддержка (в настоящее время Этап 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"
});