First, the typeof

The typeof operator returns a string representing the typeof the unevaluated operand

The usage method is as follows:

typeof operand
typeof(operand)
Copy the code

Operand Represents an expression for an object or primitive value whose type will be returned

For example

typeof 1 // 'number'
typeof '1' // 'string'
typeof undefined // 'undefined'
typeof true // 'boolean'
typeof Symbol(a)// 'symbol'
typeof null // 'object'
typeof [] // 'object'
typeof {} // 'object'
typeof console // 'object'
typeof console.log // 'function'
Copy the code

From the examples above, the first six are all basic data types. Typeof NULL is object, but this is a long-standing JavaScript Bug that does not mean null is a reference data type, and null itself is not an object

Therefore, NULL returns problematic results after typeof and cannot be used as a method to determine null. If you need to check for null in an if statement, just check for ===null

At the same time, you can find reference type data. If you use typeof to judge, except function will be recognized, the rest will output object

If we want to check whether a variable exists, we can use typeof :(cannot use if(a), if a is not declared, an error is reported)

if(typeofa ! ='undefined') {// The variable exists
}
Copy the code

Second, the instanceof

The instanceof operator is used to check whether the constructor’s prototype property appears on the prototype chain of an instance object

Use as follows:

object instanceof constructor
Copy the code

Object is the instance object; constructor is the constructor

The constructor can instantiate an object with new, and instanceof can determine if the object is an object generated by the previous constructor

// Define the constructor function
let Car = function() {}
let benz = new Car()
benz instanceof Car // true
let car = new String('xxx')
car instanceof String // true
let str = 'xxx'
str instanceof String // false
Copy the code

For instanceof implementation principles, please refer to the following:

function myInstanceof(left, right) {
    // Use typeof to determine the underlying data type. If so, return false
    if(typeofleft ! = ='object' || left === null) return false;
    // getProtypeOf is an Object API that can get the parameters of the prototype Object
    let proto = Object.getPrototypeOf(left);
    while(true) {                  
        if(proto === null) return false;
        if(proto === right.prototype) return true;// Find the same prototype object, return true
        proto = Object.getPrototypeof(proto); }}Copy the code

That is, follow the chain of archetypes until the same archetype object is found, return true, otherwise false

Third, the difference between

Typeof and instanceof are both methods for determining data types. The differences are as follows:

  • Typeof returns the primitive typeof a variable, and instanceof returns a Boolean value

  • Instanceof can accurately determine complex reference data types, but not the underlying data types

  • Typeof also suffers from the fact that while it can determine the underlying data type (except null), it cannot determine any reference data type other than the function type

As you can see, both approaches have their drawbacks and may not be sufficient for all scenarios

If you need general testing data type, Object can be used. The prototype. ToString, call this method, the uniform of the format “[Object] Xxx” string

The following

Object.prototype.toString({})       // "[object Object]"
Object.prototype.toString.call({})  // Same result as above, add call also ok
Object.prototype.toString.call(1)    // "[object Number]"
Object.prototype.toString.call('1')  // "[object String]"
Object.prototype.toString.call(true)  // "[object Boolean]"
Object.prototype.toString.call(function(){})  // "[object Function]"
Object.prototype.toString.call(null)   //"[object Null]"
Object.prototype.toString.call(undefined) //"[object Undefined]"
Object.prototype.toString.call(/123/g)    //"[object RegExp]"
Object.prototype.toString.call(new Date()) //"[object Date]"
Object.prototype.toString.call([])       //"[object Array]"
Object.prototype.toString.call(document)  //"[object HTMLDocument]"
Object.prototype.toString.call(window)   //"[object Window]"
Copy the code

Now that you know the basic usage of toString, let’s implement a universal datatype determination method

function getType(obj){
  let type  = typeof obj;
  if(type ! = ="object") {    // Check typeof first, if it is a basic data type, return directly
    return type;
  }
  // If typeof returns object, regex returns result
  return Object.prototype.toString.call(obj).replace(/^\[object (\S+)\]$/.'$1'); 
}
Copy the code

Use the following

getType([])     // "Array" typeof [] is object, so toString is returned
getType('123')  // "string" typeof returns directly
getType(window) // "Window" toString returns
getType(null)   Typeof Null is object and toString is required
getType(undefined)   // "undefined" typeof returns directly
getType()            // "undefined" typeof returns directly
getType(function(){}) // "function" typeof can determine, so the first letter is lowercase
getType(/123/g)      / / "RegExp" toString returns
Copy the code