在 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
的行为说明,可以参考 MDN;Symbol.toStringTag
相关可以参考这里。