Symbol.toStringTag

JavaScript

在 JavaScript 中,如果试图将一个对象(Object)转化为字符串,会得到:[object Object]。类似的,JavaScript 中常见如下的代码来检查一个对象的类型:

Object.prototype.toString.call('foo');     // "[object String]"
Object.prototype.toString.call([1, 2]);    // "[object Array]"
Object.prototype.toString.call(3);         // "[object Number]"
Object.prototype.toString.call(true);      // "[object Boolean]"
Object.prototype.toString.call(undefined); // "[object Undefined]"
Object.prototype.toString.call(null);      // "[object Null]"

Object.prototype.toString.call(new Map());       // "[object Map]"
Object.prototype.toString.call(function* () {}); // "[object GeneratorFunction]"
Object.prototype.toString.call(Promise.resolve()); // "[object Promise]"

然而,这一判断对其他一般的对象或者类并不是非常的友好,比如:

class A { }
Object.prototype.toString.call(new A()); // "[object Object]"

JavaScript 中新增加了 Symbol.toStringTag 这一 Symbol 值。通过对 Symbol.toStringTag 进行赋值,可以改变输出时候的行为,达到自定义 Tag 的效果。举例来说:

class A {
  get [Symbol.toStringTag]() {
    return 'A';
  }
}
Object.prototype.toString.call(new A()); // "[object A]"

在回到最开始举的例子上。前面的六种情况,是 JavaScript 默认就有的行为。而最后的三种,则是对应类型在 prototype 上对 Symbol.toStringTag 进行了赋值导致的行为。具体来说:

Array.prototype[Symbol.toStringTag] // => undefined
Map.prototype[Symbol.toStringTag] // => "Map"

两类有细微的差别。

更多关于 Object.prototype.toString 的行为说明,可以参考 MDNSymbol.toStringTag 相关可以参考这里