10. Object.toString
In ES5 and earlier, each object had the internal own property [[Class]]
whose value hinted at its type. You could not access it directly, but its value was part of the string returned by Object.prototype.toString()
, which is why that method was used for type checks, as an alternative to typeof
.
Call
Во всех встроенных объектах есть специальное внутреннее свойство [[Class]]
, в котором хранится информация о его типе или конструкторе. Его можно прочитать его «в обход», воспользовавшись методом toString
стандартного объекта Object
. Для получения [[Class]]
нужна именно внутренняя реализация toString
стандартного объекта Object
, другая не подойдёт.
Object.prototype.toString()
works as follows:
Convert
this
to an objectobj
.Determine the
toString
tagtst
ofobj
.Return
'[object ' + tst + ']'
.
Этот способ подходит только для встроенных объектов
Для собственных конструкторов он работать не будет.
Symbol.toStringTag
Symbol.toStringTag
In ES6, there is no internal property [[Class]]
, anymore, and using Object.prototype.toString()
for type checks is discouraged. In order to ensure the backwards-compatibility of that method, the public property with the key Symbol.toStringTag
was introduced. You could say that it replaces [[Class]]
.
Symbol.toStringTag
symbol used to control the behavior of the Object.prototype.toString()
built-in method. Implementation of Object.prototype.toString()
for ES6+ now converts its this value into an object first via the abstract operation ToObject
and then looks for Symbol.toStringTag
on the resulting object and in its prototype chain.
Features:
Warn:
@@toStringTag
lookup on object requires huge time compare to directtoString
call.@@toStringTag
is a read-only property
Algorithm
When the toString()
method is called, the following steps are taken:
If the this value is
undefined
, return"[object Undefined]"
.If the this value is
null
, return"[object Null]"
.Let
O
beToObject(this value)
.Let
isArray
beIsArray(O)
.ReturnIfAbrupt(isArray)
.If
isArray
is true, letbuiltinTag
be"Array"
.Else, if
O
is an exoticString
object, letbuiltinTag
be"String"
.Else, if
O
has an[[ParameterMap]]
internal slot, letbuiltinTag
be"Arguments"
.Else, if
O
has a[[Call]]
internal method, letbuiltinTag
be"Function"
.Else, if
O
has an[[ErrorData]]
internal slot, letbuiltinTag
be"Error"
.Else, if
O
has a[[BooleanData]]
internal slot, letbuiltinTag
be"Boolean"
.Else, if
O
has a[[NumberData]]
internal slot, letbuiltinTag
be"Number"
.Else, if
O
has a[[DateValue]]
internal slot, letbuiltinTag
be"Date"
.Else, if
O
has a[[RegExpMatcher]]
internal slot, letbuiltinTag
be"RegExp"
.Else, let
builtinTag
be"Object"
.Let
tag
beGet(O, @@toStringTag)
.ReturnIfAbrupt(tag)
.If
Type(tag)
is not String, let tag bebuiltinTag
.Return the String that is the result of concatenating
"[object ", tag, and "]"
.
Standard library
In the JavaScript standard library, there are the following custom toString tags. Objects that have no global names are quoted with percent symbols (for example: %TypedArray%
).
Module-like objects:
JSON[Symbol.toStringTag]
→'JSON'
Math[Symbol.toStringTag]
→'Math'
Actual module objects
M
:M[Symbol.toStringTag]
→'Module'
Built-in classes
ArrayBuffer.prototype[Symbol.toStringTag]
→'ArrayBuffer'
DataView.prototype[Symbol.toStringTag]
→'DataView'
Map.prototype[Symbol.toStringTag]
→'Map'
Promise.prototype[Symbol.toStringTag]
→'Promise'
Set.prototype[Symbol.toStringTag]
→'Set'
get %TypedArray%.prototype[Symbol.toStringTag]
→'Uint8Array'
etc.WeakMap.prototype[Symbol.toStringTag]
→'WeakMap'
WeakSet.prototype[Symbol.toStringTag]
→'WeakSet'
Iterators
%MapIteratorPrototype%[Symbol.toStringTag]
→'Map Iterator'
%SetIteratorPrototype%[Symbol.toStringTag]
→'Set Iterator'
%StringIteratorPrototype%[Symbol.toStringTag]
→'String Iterator'
Miscellaneous
Symbol.prototype[Symbol.toStringTag]
→'Symbol'
Generator.prototype[Symbol.toStringTag]
→'Generator'
GeneratorFunction.prototype[Symbol.toStringTag]
→'GeneratorFunction'
Last updated
Was this helpful?