In JavaScript, there are 5 basic data types and 1 complex data type, including: Undefined, Null, Boolean, Number and String; the complex data type is Object, and there are many specific types in the Object, such as: Array, Function, Date, etc. Today we will discuss what methods to use to determine the type of a variable.
Before explaining various methods, we first define several test variables to see what the subsequent methods can parse the variable types into. The following variables almost contain the types we commonly use in actual encoding.
var num = 123; var str = 'abcdef'; var bool = true; var arr = [1, 2, 3, 4]; var json = {name:'wenzi', age:25}; var func = function(){ ('this is function'); } var und = undefined; var nul = null; var date = new Date(); var reg = /^[a-zA-Z]{5,20}$/; var error= new Error();
1. Use typeof detection
The most common thing we use is to use typeof to detect variable types. This time, we also use typeof to detect the type of variable:
( typeof num, typeof str, typeof bool, typeof arr, typeof json, typeof func, typeof und, typeof nul, typeof date, typeof reg, typeof error ); // number string boolean object object function undefined object object object object
Judging from the output results, arr, json, nul, date, reg, error are all detected as object types, and other variables can be correctly detected. When you need to determine whether the variable is of number, string, boolean, function, undefined, json type, you can use typeof to determine. Other variables cannot determine the type, including null.
Also, typeof cannot distinguish between array and json types. Because when using typeof variable, both array and json types output objects.
2. Use instance detection
In JavaScript, judging the type of a variable, you will use the typeof operator to try it. When using the typeof operator, you will have a problem using a reference type to store the value. No matter what type of object is referenced, it will return "object". ECMAScript introduces another Java operator instanceof to solve this problem. The instanceof operator is similar to the typeof operator and is used to identify the type of the object being processed. Unlike the typeof method, the instanceof method requires the developer to explicitly confirm that the object is a specific type. For example:
function Person(){ } var Tom = new Person(); (Tom instanceof Person); // true
Let's take a look at the following example:
function Person(){ } function Student(){ } = new Person(); var John = new Student(); (John instanceof Student); // true (John instancdof Person); // true
instanceof can also detect multi-layer inheritance relationships.
OK, let's use instanceof to detect the above variables:
( num instanceof Number, str instanceof String, bool instanceof Boolean, arr instanceof Array, json instanceof Object, func instanceof Function, und instanceof Object, nul instanceof Object, date instanceof Date, reg instanceof RegExp, error instanceof Error ) // num : false // str : false // bool : false // arr : true // json : true // func : true // und : false // nul : false // date : true // reg : true // error : true
From the above run results, we can see that num, str and bool do not detect its type, but we use the following method to create num, which can detect the type:
var num = new Number(123); var str = new String('abcdef'); var boolean = new Boolean(true);
At the same time, we must also see that und and nul are the detected Object types, which output true, because there is no global type of Undefined and Null in js. Both und and nul belong to Object types, so true is output.
3. Use constructor to detect
When using instanceof to detect variable types, we cannot detect the type of number, ‘string’, bool. Therefore, we need to solve this problem in another way.
The constructor is originally a property on the prototype object, pointing to the constructor. However, according to the order in which the instance object is searched for attributes, if there are no instance attributes or methods on the instance object, search on the prototype chain. Therefore, the instance object can also use the constructor attribute.
Let's first output the content, that is, what does the constructor of a variable of a numeric type look like:
function Number() { [native code] }
We can see that it points to the Number constructor, so we can use ==Num to determine whether num is of Number type, and other variables are similar:
function Person(){ } var Tom = new Person(); // undefined and null have no constructor attributes( ==Person, ==Number, ==String, ==Boolean, ==Array, ==Object, ==Function, ==Date, ==RegExp, ==Error ); // All results aretrue
From the output results, we can see that except for undefined and null, other types of variables can be determined using constructors.
However, using constructor is not a safe one, because the constructor attribute can be modified, which will cause the detected results to be incorrect, such as:
function Person(){ } function Student(){ } = new Person(); var John = new Student(); (==Student); // false (==Person); // true
In the example above, the constructor in the Student prototype is modified to point to Person, resulting in the fact that the actual constructor of the instance object John cannot be detected.
At the same time, using instanceof and constructor, the judged array must be declared on the current page! For example, a page (parent page) has a framework, a page (subpage) is referenced in the framework, an array is declared in the child page, and assigned it to a variable of the parent page. When determining the variable, Array == ; will return false; Reason:
1. Array is a reference data. During the transmission process, it is just a transfer of the reference address.
2. The address referenced by the Array native object of each page is different. The corresponding constructor of the array declared in the child page is the Array object of the child page. For judgment on the parent page, the Array used is not equal to the Array of the child page; remember, otherwise it will be difficult to track the problem!
4. Use
Let's ignore what this is, let's take a look at how it detects variable types:
( (num), (str), (bool), (arr), (json), (func), (und), (nul), (date), (reg), (error) ); // '[object Number]' '[object String]' '[object Boolean]' '[object Array]' '[object Object]' // '[object Function]' '[object Undefined]' '[object Null]' '[object Date]' '[object RegExp]' '[object Error]'
Judging from the output results, (variable) outputs a string, there is an array in the string, the first parameter is Object, and the second parameter is the type of this variable. Moreover, all variable types are detected, we only need to take out the second parameter. Or you can use (arr)=="object Array" to detect whether the variable arr is an array.
Let’s take a look at how the ECMA is defined:
( ) When the toString method is called, the following steps are taken:
1. Get the [[Class]] property of this object.
2. Compute a string value by concatenating the three strings “[object “, Result (1), and “]”.
3. Return Result (2)
The above specification defines the behavior: First, obtain an internal property of the object [[Class]], and then based on this property, return a string similar to "[object Array]" as the result (those who have seen the ECMA standard should know that [[]] is used to represent attributes used internally in the language and cannot be directly accessed from the outside, which is called "internal property"). Using this method and with call, we can obtain the internal attributes of any object [[Class]], and then convert the type detection into a string comparison to achieve our goal.
5. Implementation of $.type in jquery
A $.type interface is provided in jquery to let us detect the type of variable:
( $.type(num), $.type(str), $.type(bool), $.type(arr), $.type(json), $.type(func), $.type(und), $.type(nul), $.type(date), $.type(reg), $.type(error) ); // number string boolean array object function undefined null date regexp error
Is there a familiar feeling when I see the output? Yes, it is the second parameter of the result output using (variables).
Let’s first compare the results detected by all the above methods. The horizontal row is the detection method used, and the vertical row is the various variables:
Type judgment | typeof | instanceof | constructor | $.type | |
num | number | false | true | [object Number] | number |
str | string | false | true | [object String] | string |
bool | boolean | false | true | [object Boolean] | boolean |
arr | object | true | true | [object Array] | array |
json | object | true | true | [object Object] | object |
func | function | true | true | [object Function] | function |
und | undefined | false | - | [object Undefined] | undefined |
nul | object | false | - | [object Null] | null |
date | object | true | true | [object Date] | date |
reg | object | true | true | [object RegExp] | regexp |
error | object | true | true | [object Error] | error |
advantage | Simple to use, can output results directly | Can detect complex types | Basically, all types can be detected | Detect all types | - |
shortcoming | Too few types detected | The basic type cannot be detected and cannot be crossed iframes | Can't cross iframes, and constructor is easily modified | Undefined and null are all Object under IE6 | - |
Comparing this way, you can see the difference between the methods better, and it is really similar to the result output from $type. Let's take a look at how the $.type method is implemented internally by jquery (version 2.1.2):
// Instance object can be used directly using the method on the prototype chainvar class2type = {}; var toString = ; // Some codes are omitted... type: function( obj ) { if ( obj == null ) { return obj + ""; } // Support: Android<4.0, iOS<6 (functionish RegExp) return (typeof obj === "object" || typeof obj === "function") ? (class2type[ (obj) ] || "object") : typeof obj; }, // Some codes are omitted... // Populate the class2type map ("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { class2type[ "[object " + name + "]" ] = (); });
Let's take a look at this part first:
// Populate the class2type map ("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { class2type[ "[object " + name + "]" ] = (); }); //After the loop, the value of `class2type` is:class2type = { '[object Boolean]' : 'boolean', '[object Number]' : 'number', '[object String]' : 'string', '[object Function]': 'function', '[object Array]' : 'array', '[object Date]' : 'date', '[object RegExp]' : 'regExp', '[object Object]' : 'object', '[object Error]' : 'error' }
Let’s take a look at the type method:
// Implementation of typetype: function( obj ) { // If the passed in null or undefined, the string of this object is returned directly // If the object obj passed in is undefined, then "undefined" is returned if ( obj == null ) { return obj + ""; } // Support: Android<4.0, iOS<6 (functionish RegExp) // The lower version of regExp returns the function type; the higher version has been corrected, returning the object type // If the obj type detected using typeof is object or function, the value of class2type is returned, otherwise the typeof detected is returned. return (typeof obj === "object" || typeof obj === "function") ? (class2type[ (obj) ] || "object") : typeof obj; }
When typeof obj === "object" || typeof obj === "function", class2type[ (obj) is returned. At this point, we should understand why it is so similar to $.type. In fact, jquery is implemented, converting the '[object Boolean]' type to the 'boolean' type and returning it. If the class2type stores no type of this variable, then return "object".
In addition to the "object" and "function" types, other types are detected using typeof. That is, variables of type number, string, boolean, just use typeof.