JS: Object.prototype.toString
Object.prototype.toString()
-
The input of this function is the value of this Binding.
Input can be any type, including Primitive Value.
Return a string representation. The result is usually one of the following:
const vType = ((x) => Reflect.apply(Object.prototype.toString, x, [])); console.log( vType({}) === "[object Object]", vType([]) === "[object Array]", vType(/./) === "[object RegExp]", vType(new Date()) === "[object Date]", vType(function f() {}) === "[object Function]", vType(new Set()) === "[object Set]", vType(new Map()) === "[object Map]", vType(new WeakMap()) === "[object WeakMap]", vType(new WeakSet()) === "[object WeakSet]", ); console.log( vType(function* () {}) === "[object GeneratorFunction]", vType((function* () {})()) === "[object Generator]", ); console.log( vType(Symbol()) === "[object Symbol]", vType(JSON) === "[object JSON]", vType(Math) === "[object Math]", vType(Error()) === "[object Error]", vType(new Promise(() => {})) === "[object Promise]", ); console.log( vType((x) => 3) === "[object Function]", vType(1) === "[object Number]", vType(Infinity) === "[object Number]", vType(NaN) === "[object Number]", vType("") === "[object String]", vType(true) === "[object Boolean]", vType(undefined) === "[object Undefined]", vType(null) === "[object Null]", ); (function ff() { console.log(vType(arguments) === "[object Arguments]"); })();
If input is a object, and has a Symbol key property
Symbol.toStringTag
, either own property or inherited, and its value is a string, let's say the value is tag, then the result is"[object tag]"
/* Example of object that has property key Symbol.toStringTag and value is a string. */ let jj = {}; jj[Symbol.toStringTag] = "xyz"; console.log( Object.prototype.toString.call(jj) === "[object xyz]", );
〔see Symbol Tutorial〕
〔see Symbol Object〕
Usually used like these:
Object.prototype.toString.call(obj)
〔see Function.prototype.call〕Reflect.apply( Object.prototype.toString , obj, [] )
〔see Reflect.apply〕
Often used to find out the “type of object”.
For example, {}
is a data object, but /abc/
is regexp object. 〔see Determine Type of Object〕
History of Object.prototype.toString
JavaScript language by spec does not have the concept of “different type of objects” at the language level.
The typeof
operator on
Array, RegExp, Date, JSON, etc all just return "object"
.
The only exception is function, which typeof a_function
returns "function"
.
〔see Value Types〕
However, JavaScript has some internal way to determine what type of object it is.
In ECMAScript 5.1 §8#sec-8.6.2 (2011), object has a internal slot denoted “[[Class]]”.
Its value is a string, representing the classification of the object.
This [[Class]] is what we think of the “type of object”.
Object.prototype.toString()
return the value of internal slot [[class]], in this string form "[object [[Class]]]"
(ECMAScript 5.1 §15#sec-15.2.4.2)
The possible return values are:
"[object Undefined]"
"[object Null]"
"[object Array]"
"[object String]"
"[object Arguments]"
etc
But in ES2015, the internal slot “[[Class]]” is removed from the spec. (probably because to avoid confusion with new ES2015 class feature. 〔see Class〕 )
However, the behavior of Object.prototype.toString()
is kept for backward compatibility, but how it works has changed.
ECMAScript 2015 §Fundamental Objects#sec-object.prototype.tostring
Now, if the object has a symbol
property key Symbol.toStringTag
, then that is used as part of the return value.
Else, it falls back to ES5 behavior as is.
ECMAScript 2015 added new kinds of objects, such as
Set Object
and
Map Object
.
New object's prototypes typically have symbol properties Symbol.toStringTag
.
For example, for set object, the value is the string "Set"
.
The symbol property Symbol.toStringTag
can be set by user.
ECMAScript 2015 added this note:
NOTE Historically, this function was occasionally used to access the String value of the [[Class]] internal slot that was used in previous editions of this specification as a nominal type tag for various built-in objects. The above definition of toString preserves compatibility for legacy code that uses toString as a test for those specific kinds of built-in objects. It does not provide a reliable type testing mechanism for other kinds of built-in or program defined objects. In addition, programs can use @@toStringTag in ways that will invalidate the reliability of such legacy type tests.
ECMAScript 2015 §Fundamental Objects#sec-object.prototype.tostring