In JavaScript, the most reliable way to determine what kind of built-in type an object's value belongs to is through the Object.prototype.toString method.
var arr = [];console.log (Object.prototype.toString.call (arr)) //"[Object Array]"
This article is about how the ToString method does this, and what the principle is.
ECMAScript 3
In ES3, the specification of the Object.prototype.toString method is as follows:
-
15.2.4.2 Object.prototype.toString ()
-
When the toString method is called, the following procedure is performed:
1. Gets the value of the [[Class]] property of this object.
2. Calculated three string "[object", the first step of the operation result (1), and "]" after the connection of the new string.
3. Returns the result of the operation of the second step (2).
[[Class]] is an intrinsic property that is owned by all objects (native and host objects). In the specification, [[class]] is defined as
Internal Properties |
Description |
[[Class]] |
A string value that indicates the type of the object. |
And then gave an explanation:
The value of the [[class]] property of all built-in objects is defined by this specification. The value of the [[class]] property of all host objects can be any value, even the value of the [[class]] property used by the built-in object. The value of the [[Class]] property can be used to determine which built-in type a native object belongs to. It should be noted that in addition to the Object.prototype.toString method, this specification does not provide any other means for the program to access the value of the property ( View 15.2.4.2).
That is, the string returned by the Object.prototype.toString method is removed from the previous fixed "[object" and the fixed "]", which is the value of the internal property [[class]]. It also achieves the purpose of judging the object type. Tool Methods in jquery $.type (), that's what this is about.
In ES3, the canonical document does not summarize the total number of [[Class]] intrinsic properties, but we can count on our own that there are 10 types of values for the native object's [[Class]] intrinsic properties. Respectively:,,, "Array"
"Boolean"
"Date"
"Error"
, "Function"
,"Math"
, "Number"
, "Object"
, "RegExp"
,"String".
ECMAScript 5
In ES5.1, there are changes to the definition of Object.prototype.toString methods and [[Class]] internal properties In addition to the more detailed specification writes, the Object.prototype.toString method is as follows:
In ES5.1, there are changes to the definition of Object.prototype.toString methods and [[Class]] internal properties In addition to the more detailed specification writes, the Object.prototype.toString method is as follows:
15.2.4.2 Object.prototype.toString ()
When the toString method is called, the following procedure is performed:
- If The value of this is undefined, it is returned
"[object Undefined]"
.
- If The value of this is null, it is returned
"[object Null]"
.
- Let O become the result of calling Toobject (this) .
- Let class be the value of the internal property of O [[Class]].
- Returns a new string of three strings "[object", class, and "]" after the connection
.
As you can see, more than ES3.1th, 2 steps belong to the new rule, which is more special, because " Undefined"
and" Null"
does not belong to the [[Class]] property value, it should be noted that this is irrelevant to strict mode (most functions in strict mode, The value of this will remain undefined or null, and will automatically become the global object in non-strict mode. The 3rd step is not a new rule, because in ES3 's engine, the three primitive value types are converted to the corresponding wrapper objects, but not written in the specification. ES5, the [[Class]] property is explained in more detail:
The value of the [[class]] property of all built-in objects is defined by this specification. The value of the [[class]] property of all host objects can be in addition to "Arguments", "Array", "Boolean", "Date", "Error", "Function", "JSON", "Math", "number", "Object", "RegExp", "string" any string other than. [[Class]] internal properties are used internally by the engine to determine what type of value an object belongs to. It should be noted that in addition to the Object.prototype.toString method, this specification does not provide any other means for the program to access the value of the property (View 15.2.4.2).
Compared with ES3, the first difference is that [[class]] internal properties of the value of two more, into 12 kinds, one is the [[Class] of the Arguments object is "Arguments", not the previous "object", there is more than the global object JSON , its [[Class]] value is "JSON". The second difference is that the value of the [[class]] intrinsic property of the host object cannot conflict with these 12 values, but in browsers that support ES3, it seems that there are no other host objects that intentionally use those 10 values.
ECMAScript 6
ES6 is still working on the draft, but it is certain that the[[class]] internal attribute is not available and is replaced by another internal property [[Nativebrand]]. The [[Nativebrand]] property is defined as:
ES6 is still working on the draft, but it is certain that the[[class]] internal attribute is not available and is replaced by another internal property [[Nativebrand]]. The [[Nativebrand]] property is defined as:
Internal Properties |
Property Value |
Description |
[[Nativebrand]] |
Enumerates a member of the Nativebrand. |
The value of this property corresponds to a flag value (tag values) that can be used to differentiate the type of the native object. |
Explanation of [[Nativebrand]] Property:
Explanation of [[Nativebrand]] Property:
[[Nativebrand]] internal properties are used to identify whether a native object is a specific type of object that conforms to this specification. The values of [[Nativebrand]] intrinsic properties are one of the values of these enumerated types: Nativefunction, Nativearray, Stringwrapper, Booleanwrapper, Numberwrapper, Nativemath, Nativedate, Nativeregexp, NativeError, Nativejson, Nativearguments, Nativeprivatename. [[Nativebrand]] internal properties are used only to differentiate between ECMAScript native objects that are specific to a particular type. only the [[Nativebrand]] intrinsic properties are available for the object type explicitly stated in Table 10.
Table 10-[[nativebrand]] values of intrinsic properties
property value |
corresponding type |
nativefunction | Td>function objects
nativearray |
Array objects |
stringwrap Per |
String objects |
booleanwrapper |
Boolean objects |
Numberwrapper |
Number Objects |
Nativemath |
The Math object |
nativedate |
Date objects |
nativeregexp |
RegExp objects |
nativeerror |
Error objects |
Nativejson |
The JSON object |
nativearguments |
Arguments objects |
nativeprivatename |
Private Name objects |
visible, unlike [[class]], not every object has [[Nativebrand]]. At the same time, the specification of the Object.prototype.toString method is changed to the following:
15.2.4.2 Object.prototype.toString ()
When the toString method is called, the following procedure is performed:
- If The value of this is undefined, it is returned
"[object Undefined]"
.
If The value of this is null, it is returned "[object Null]"
.
- Let O become the result of calling Toobject (this) .
- If O has [[Nativebrand]] internal properties, let tag be the corresponding value in table 29.
- otherwise
let
hastag be the result of calling the [[Hasproperty]] internal method of
O , with the @ @toStringTag.
- if hastag is false , let tag be
"Object"
.
- Otherwise,
let
tag be the result of calling the [[Get]] internal method of
O , with the @ @toStringTag.
- if tag is a abrupt completion, let tag become normalcompletion (
"???"
).
- let tag become tag . [[value]].
- if Type ( tag ) is not a string, let tag be
???
.
- if tag has a value of
"Arguments"
, "Array"
, "Boolean"
, "Date"
, "Error"
, "Function"
, "JSON"
, "Math"
, "Number"
, "Object"
, "RegExp"
, or any of the string, let
tag become the string "~" and the
tag Current value after the concatenated result.
- Returns a new string of three strings "[object", Tag, and "]" after the connection
.
Table 29-[[nativebrand]] flag value
[[Nativebrand]] value |
Flag Value |
Nativefunction |
"Function" |
Nativearray |
"Array" |
Stringwrapper |
"String" |
Booleanwrapper |
"Boolean" |
Numberwrapper |
"Number" |
Nativemath |
"Math" |
Nativedate |
"Date" |
Nativeregexp |
"RegExp" |
NativeError |
"Error" |
Nativejson |
"JSON" |
Nativearguments |
"Arguments" |
You can see that there has been a lot of change in the specification, but for ordinary users, it seems that they do not feel.
Perhaps you have found that the new type of map,set in ES6 is not in table 29. What do they return when they execute the tostring method?
Console.log (Object.prototype.toString.call (Map ())) //"[Object map]"
Console.log (Object.prototype.toString.call (Set ())) //"[Object set]"
How did the string "Map" come From:
15.14.5.13 [email protected] @toStringTag
@ @toStringTag The initial value of the property is the string "Map".
Since ES6 's specifications are still being worked out, various regulations are likely to change, so if you want to know more details. Look at the following two links, now just to know: [[class]] is gone, using a more complex mechanism.
Http://stackoverflow.com/questions/13151643/access-nativebrand-class-in-es6-ecmascript-6
Https://mail.mozilla.org/pipermail/es-discuss/2012-June/023676.html
The principle of the JavaScript:Object.prototype.toString method