How to Judge Data Type Accurately in JS

Posted by uncleronin on Sat, 29 Jun 2019 22:59:15 +0200

In my first article, I introduced the major types of JS and used typeof for output viewing. I also mentioned that each function has its own internal attribute [[class]. This class refers to the internal classification of js. This class roughly includes two types: data type and constructor.

Introduction to JavaScript Types

We talked about several major data types of JS, and also used typeof to look at several simple data type values. So today let's have a broader understanding of this aspect of knowledge. See the code below.

var num = 123;
var str = 'aflypig';
var bool = true;
var arr = [1, 2, 3, 4];
var obj = {name:'aflypig', age:21};
var func = function(){ console.log('this is function'); }
var und = undefined;
var nul = null;
var date = new Date();
var reg = /^[a-zA-Z]{5,20}$/;
var error= new Error(); 

Obviously, we only used typeof to look at several commonly used data types last time, but this time there are some built-in constructors, as well as the Array type. So, getting to the point, how can we get these values accurately (again, this is not a variable, JS measures the type of value, the variable is the container for storing the value) data type?

In fact, there are four methods, but there is only one way to identify them completely and accurately, which is also a common problem in the interview process.

I. typeof

   typeof num //number
   typeif str //string
   typeof bool //boolean
   typeof arr //object
   typeof obj //object
   typeof func//function
   typeof und //undefined
   typeof nul //object
   typeof date //object
   tyepof reg //object
   tyoeof error //object

Parsing: Typeeof recognizes simple primitive type values (such as number,string,boolean), but for complex types (Object,Array,Function), it only recognizes Function.

                    Unfined and null are inherently bug s in JS, where typeof `undefined'identifies the correct type values, but null is classified into the `Object' family.
        For the date & reg & error types here, which are post-instance objects, typeof does not identify their `constructors'(which are not data types here). Obviously typeof can't handle this complex type.

Summary: Typeof can be seen as a defined type within JS that returns its corresponding string. It does not go deep into the value itself, does not type conversion, and only returns its corresponding type value for the current value. The same data type operates the same through the typeof operator. It has no principle. That's how JS is defined. We just remember it.

2. instanceof

Judging by the above typeof, we know that it does not satisfy some pseudotypes created by built-in constructors. So, let's use constructors to look at their constructors and identify their types.

   num instanceof Number  //false
   str instanceof String   //false
   bool instanceof Boolean   //false
  
        arr instanceof Array  //true
    obj instaneof Object  //true
    func instanceof Function  //true
        und instanceof  Object   //false
        nul instanceof   Object  //false
        date instanceof Date //true
    reg instanceof RegExp //true
    error instanceof Error //true

Resolution: Here we use instanceof to compound the judgement of whether or not it is the corresponding type. First, let's look at the false item, num str bool, which does not wrap encapsulated objects when using instanceof, and instanceof is based on

Three constructor s

  num.constructor .name    //Numer
  str.constructor.name  //String
  bool.constructor.name  //Boolean
  arr.constructor.name  //Array
  obj.constructor.name  //Objeact
  func.constructor.name  //Function
  und.constructor.name  // TypeError
  nul.constructor.name  //TypeError
  date.constructor.name //Date
  reg.constructor.name // RegExp
  error.constructor.name //Error

Except for undefined and null type errors (both have no attribute values), all of the above can get the data types we want. But is that really the case?

 
  // 1⃣️
  var Structure =  function (){ }
  
  var ins = new Structure();
 
  ins.constructor.name  //Structure 
 
 //2⃣️
  
   var Person = function(){}
   var Student = function(){}
   
   Person.prototype = new Student();
   var obj = new Person();
   
   obj.constructor === Student
 

Resolution: In the first case, we can't get the exact type names for the instances generated by our constructors, which may have prevented us from using this method.

                    In the second case, because the constructor of the object is `variable', `inaccurate', we still can not get the exact type through the constructor.
        
        

Summary: Through the constructor, we can get str num bool which can not be obtained by instance, but another problem arises. The variability of the constructor, because of its uncertainty, we can not judge the correct data type in many cases, so the method of using the constructor is almost useless.

IV[[class]]
Resolution: This [[class]] refers to the classification attributes hidden within javascript, which are unreadable, non-enumerative, non-modifiable, and non-configurable. The attributes of underscore appearing on both sides belong to the attributes supported by some browsers. [[]] The two parenthesized attributes belong to JavaScript internal attributes. I remember in the previous chapter that everything in JavaScript is an object, and we can force it to be converted into a string to expose its internal [[class]] properties.

Understanding the above methods, we found that they can only complete part of the type verification, some cases are variable and inaccurate.

Object.prototype.toString.call(num);   //  "[object Number]"
Object.prototype.toString.call(str);   //  "[object String]"
Object.prototype.toString.call(bool);  //  "[object Boolean]"
Object.prototype.toString.call(arr);   //  "[object Array]"
Object.prototype.toString.call(func);  //  "[object Function]"
Object.prototype.toString.call(und);   //  "[object Undefined]"
Object.prototype.toString.call(nul);   //  "[object Null]"
Object.prototype.toString.call(date);  //  "[object Date]"
Object.prototype.toString.call(reg);   //  "[object RegExp]"
Object.prototype.toString.call(error);  //  "[object Error]"
 
arr instanceof Array  //true
    obj instaneof Object  //true
    func instanceof Function  //true
        und instanceof  Object   //false
        nul instanceof   Object  //false
        date instanceof Date //true
    reg instanceof RegExp //true
    error instanceof Error //true

We use Object's toString method to view the current object's data type. We see that using this method we can see the corresponding data type perfectly, which is exactly what we want, and each object has its own [[class]. We can understand that it is an internal classification made by JavaScript according to the built-in constructor.

How can we get less jqquery when native js is often used and difficult to demand?

The following is the jQuery sample code related to the jQuery.type() function:

jQuery.type( undefined ); // "undefined"
jQuery.type( null ); // "null"
 
jQuery.type( true ); // "boolean"
jQuery.type( new Boolean(true) ); // "boolean"
 
jQuery.type( 3 ); // "number"
jQuery.type( new Number(3) ); // "number"
 
jQuery.type( "test" ); // "string"
jQuery.type( new String("test") ); // "string"
 
jQuery.type( function(){} ); // "function"
jQuery.type( new Function() ); // "function"
 
jQuery.type( [] ); // "array"
jQuery.type( new Array() ); // "array"
 
jQuery.type( new Date() ); // "date"
 
jQuery.type( new Error() ); // New support for "error" // jQuery 1.9
 
jQuery.type( /test/ ); // "regexp"
jQuery.type( new RegExp("\\d+") ); // "regexp"
 

jquery is also implemented internally in the way we just mentioned [[class]], which returns a string fixed to lowercase letters.
We can write a line of code to simply implement the type method in jquery

function type(o){
    var s  = Object.prototype.toString.call(o);
    return s.slice(s.indexOf(" ")+1,s.length-1).toLowerCase();
}
 

type(false) //boolean
type({}) //object
type([]) //array
type("") //string
type(/^/) //regexp

 
Hope that through this superficial explanation can bring you some harvest, when you know that there is a suitable way in the end, you should think more about using other means to achieve, because doing so can expand your knowledge. For example, if we list them back and forth, I don't think many people will think about the inadequacies of constructor s and instance s and their scope of application.
 

Topics: Javascript JQuery Attribute less