The principle _javascript technique of Object.prototype.toString method in JavaScript

Source: Internet
Author: User

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 for the Object.prototype.toString method is as follows:

15.2.4.2 Object.prototype.toString ()

When the ToString method is invoked, the following procedure is performed:

1. Gets the value of the [[Class]] property of the This object.

2. Calculates the three string "[object", the first step results result (1), and "]" the new string after the connection.

3. Returns the result of the operation of the second step (2).

[[Class]] is an internal property in which all objects (native and host) have this property. In the specification, [[class]] is defined as

Internal Properties Description
[[Class]] A string value that indicates the type of the object.

And then give 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, or 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 passing the Object.prototype.toString method, this specification does not provide any other way for the program to access the value of the property (see 15.2.4.2 ).

In other words, the string returned by the Object.prototype.toString method, with the previous fixed "[Object" and "fixed"], is the value of the internal property [[class]]. It also achieves the purpose of judging the type of object. Tools method in jquery $.type (), that's what you do.

In the ES3, the specification document does not summarize [[class]] internal properties A total of several, but we can count ourselves, the original object's [[Class]] internal properties of the value of a total of 10. respectively: "Array", "Boolean", "Date", "Error , "Function", "Math", "number", "Object", "RegExp", "String".

ECMAScript 5

In ES5.1, there are some changes in the definition of the Object.prototype.toString method and [[class]] internal properties, in addition to the more detailed specification written, and the specification of the Object.prototype.toString method is as follows:

15.2.4.2 Object.prototype.toString ()

When the ToString method is invoked, the following procedure is performed:

Returns "[Object Undefined]" If the value of this is Undefined.

Returns "[Object Null]" If the value of this is null.

Let o become the result of calling Toobject (this).

Let Class be the value of the internal property [[Class]] of O.

Returns a new string of three string "[Object, class, and]" after the connection.

It can be seen that more than ES3 1,2,3 step. 1th, 2 steps belong to the new rule, which is special, because "Undefined" and "Null" are not the values of [[Class]] properties, and it should be noted that this is independent of strict mode (most functions are in strict mode, The value of this will remain undefined or null, it automatically becomes a global object in a non strict mode. The 3rd step is not a new rule, because in the ES3 engine, the three original value types are converted to the corresponding wrapper objects in this step, but not in the specification. In ES5, the [[Class]] attribute 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]] attribute of all host objects can be except "Arguments", "Array", "Boolean", "Date", "Error", "Function", Any string other than "JSON", "Math", "number", "Object", "RegExp", "string". [[Class]] internal property is the internal engine used to determine what type of object a value belongs to. It should be noted that this specification does not provide any other way for the program to access the value of the property except through the Object.prototype.toString method (view 15.2.4.2).

And ES3 contrast, the first difference is [[class]] Internal property value of two more, into 12 kinds, one is the Arguments object [[Class]] became "Arguments", not the previous "object", there is a number of global object JSON , its [[Class]] value is "JSON." The second difference is that the values of the [[class]] internal properties of the host object cannot conflict with these 12 values, but in browsers that support ES3, it appears that there are no hosts intentionally using the 10 values.

ECMAScript 6

ES6 is still just a work draft, but to be sure, [[Class]] internal properties are gone and replaced by another internal property [[Nativebrand]]. The [[Nativebrand]] property is defined as this:

Internal Properties Property Value Description
[[Nativebrand]] Enumerates a member of the Nativebrand. The value of this property corresponds to a flag value (tag value) that can be used to differentiate between the type of the native object.

Explanation of [[Nativebrand]] Property:

The [[Nativebrand]] internal property is used to identify whether a native object is a specific type of object that conforms to this specification. The value of the internal property of [[Nativebrand]] is one of the values of the following enumerated types: Nativefunction, Nativearray, Stringwrapper, Booleanwrapper, Numberwrapper, Nativemath, Nativedate, Nativeregexp, NativeError, Nativejson, Nativearguments, Nativeprivatename. The [[Nativebrand]] internal property is used only to differentiate between a specific type of ECMAScript native object. Only the object type explicitly indicated in table 10 has [[Nativebrand]] internal properties.

Table 10-[[nativebrand]] Internal property value

Property Value corresponding type
Nativefunction Function objects
Nativearray Array objects
Stringwrapper 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

Obviously, 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 invoked, the following procedure is performed:

Returns "[Object Undefined]" If the value of this is Undefined.

Returns "[Object Null]" If the value of this is 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 the [[Hasproperty]] internal method that called O, and the parameter is @ @toStringTag.

If Hastag is false, let tag be "Object".

Otherwise

Let tag become the result of calling the [[get]] internal method of O, and the parameter is @ @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 become "???".

If the value of tag is "Arguments", "Array", "Boolean", "Date", "Error", "Function", "JSON", "Math", "number", "Object", "RegExp", or

One of the "string", let the tag become the result of the string "~" and the tag's current value connection.

Returns a new string of three string "[object", Tag, and "]" connected.

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 great change in the specification, but for ordinary users, it seems that they are not.

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]"

Where does the string "Map" come From:

15.14.5.13 map.prototype.@ @toStringTag

The initial value of the @ @toStringTag property is the string "Map."

Since the ES6 specification is still in place, all the relevant rules are likely to change, so if you want to know more details. Look at these two links, and now all you need to know is that [[class]] is gone and more complex mechanisms are used.

The above is a small set of JavaScript to share the principle of Object.prototype.toString method, I hope to help you!

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.