Hello, everyone, I am Lin Yiyi, this is the previous easy-to-understand JS detection principle and simulation of the implementation of the article. Read on 😋😋

Mind mapping

Types in JS

  • Basic types,Number, string, null, undefined, Boolean, new in ES6symbolIn the es11bigintThere are seven basic types
  • Reference type:Object, the function.

Data type detection method

Data types of the detection method of the communist party of China have four typeof, instanceof, constructor, the Object. The prototype. ToString. Call ()

First, the typeof

Typeof detection principle is: at the bottom of the computer according to the BINARY value of JS data type for detection.

  • typeofThe return value after detecting the type is onestringES5 also throws a string for an undefined variable typeundefinedInstead of reporting an error. But the use oflet, constDeclared variables can also cause temporary dead zones to be thrownReferenceError.
typeof undefined    //"undefined"
typeof a // "undefined"
typeof b // "ReferenceError" 
let b

typeof 12   //"number"
typeof NaN  //"number"
typeof ' '   //"string"
typeof 1n    //"bigint"
typeof function(){}     //"function"
Copy the code
  • (disadvantages)typeofCan detect in addition tonullData types other than type.nullBy testing intoobjectThis is a bug left over from history.
  • (disadvantages)typeofCan’t detect specificobjectType, because the binary of object types starts with 000. Such astypeof [] //"object"Detect arrays, re’s, dates, etc.
  • Other types of binary,000Object,00000...Null,1An integer,010Floating point number,100String,110Boolean value,- 2 ^ 30 undefined

Why is typeof NULL detectedobject

The binary value of null is 000, whereas the binary value of object starts with 000. Therefore, the typeof null is also detected as object. This is a historical bug

Consider: why can typeof judge function judge isfunctionType instead ofobject

A typeOf judgment function calls the call method to determine whether a function is an object. C. function D. function

You can be there just to make up the instanceof number

Instanceof checks whether the type on the right appears in the prototype chain of the instance on the left, and returns true or false.

  • instanceofTo determine which constructor the instance belongs to
  • instanceofDetermine that the result returned is a Boolean value.
  • instanceofIs used to check whether the current instance belongs to a class. Can be used to solvetypeofA problem with a specific object type cannot be detected.
let ary = []
console.log(ary instanceof Array)   // true

let reg = / ^ /
console.log(reg instanceof RegExp)  // true
Copy the code
  • (Disadvantage) as long as the current class appears on the prototype chain of the instancetrue, thenObjectThe result of type checking is alwaystrueIf the prototype of the instance has been modified, even if the result of the detection istrueIt is also inaccurate.
  • (disadvantages)instanceofCannot detect base data types.
// All types that appear on the prototype chain are judged to be true
let ary = []
console.log(ary instanceof Object)   // true

function fn(){}
fn.prototype = Array.prototype  // The prototype has been modified
let f = new fn()
console.log(f instanceof Array) // true
console.log(f instanceof Function) // false

// Cannot detect basic array types
console.log(1 instanceof Number)    //false
console.log(' ' instanceof String)   //false
console.log(false instanceof Boolean)   //false
Copy the code

Warm up the topic

    1. Determine the results
console.log( Function instanceof Object ); // true
console.log( Object instanceof Function ); // true
Copy the code

Object is going to be a function here

    1. Determine the results
function f(){ return; }

console.log(new f() instanceof f); // true
Copy the code

There is no doubt that the result here is true, because the prototype chain of the left instance is an instance of the right constructor

function f(){ return f; }

console.log(new f() instanceof f); // fale
Copy the code

Function f(){return f; function f(){return f; }) instanceof function f(){ return f; } result is false

Think and simulate instanceof implementation

The result is judged by whether the type on the right appears in the prototype chain of the left instance. __proto__ === class.prototype: true; otherwise, false. For prototype and prototype chain unfamiliar can see interview | you have to know JS prototype and prototype chain.

function _instanceof(example, classP) {
    let proto = Object.getPrototypeOf(example),
        classPrototype = classP.prototype
    while (true) {
        if (proto === classPrototype) {
            return true
        }
        if (proto === null) {
            return false
        }
        proto = Object.getPrototypeOf(proto)
    }

_instanceof([], Array)  //true
_instanceof(' '.Array)  // false
_instanceof(' '.Object) // true
Copy the code

There can be no constructor there

The constructor detection mechanism is as follows: constructor stores the constructor itself and uses the stored constructor to detect the type. Not familiar with the constructor can also see the interview | you have to know the JS prototype and prototype chain.

  • constructorYou can detect basic types, which is a little bit moreinstanceofBe useful
let ary = []
ary.constructor === Array   / / true, ary. Constructor = = > Array. The prototype. The constructor
ary.constructor === String  // false
ary.constructor === Object  // false

let a = 1
a.constructor === Number    // true

let s = ' '
s.constructor === String    // true
Copy the code
  • (disadvantages)constructorinstanceofIt has the same flaw, which isconstructorIt can be modified which is a redirect
Number.prototype.constructor = 'abc'
let a = 1
a.constructor === Number    // false
Copy the code

Four, the Object. The prototype. ToString. Call (), type of measurement standard

Detection mechanism is: using the Object. The prototype. ToString returns the instance owning class information, by changing the toString this point to return the type of the specified argument.

  • Object.prototype.toStringThe return format is fixed to'[object xxx]', can detect any type
Object.prototype.toString.call(1)       //"[object Number]"
Object.prototype.toString.call(' ')      //"[object String]"
Object.prototype.toString.call(null)        //"[object Null]"
Object.prototype.toString.call(undefined)       //"[object Undefined]"
Object.prototype.toString.call(Symbol())        //"[object Symbol]"
Object.prototype.toString.call([])          //"[object Array]"
Object.prototype.toString.call(function(){})        //"[object Function]"
Object.prototype.toString.call({})      //"[object Object]"
Copy the code
  • You can’t extract the data type directly, you need to transform it to get the direct type

Five, package a universal detection methodtoType()

1. Type detection in jQuery

(function () {
    // toType in jquery
    let class2type = {},
        toString = class2type.toString

    // Set the type mapping table
    let arrType = ['Number'.'String'.'Boolean'.'Symbol'.'Array'.'Date'.'Error'.'RegExp'.'Function'.'Object']
    arrType.forEach(item= > {
        class2type[`[object ${item}] `] = item.toLowerCase()
    });

    function toType(checkType) {
        if (checkType === null || checkType == undefined) {
            return checkType + ' '
        }
        return typeof checkType == 'object' || typeof checkType == 'function' ? class2type[toString.call(checkType)] : typeof checkType
    }
    window.toType = toType
})()

toType(1)   //"number"
toType(' ')  //"string"
toType(null)    //"null"
toType(undefined)   //"undefined"
toType({})  //"object"
toType(function(){})    //"function"
toType([])  //"array"
Copy the code

Nature or use of the Object. The prototype. ToString. Call ()

2. Self-encapsulate a simpler selfType()

(function () {
    function selfType(checkType) {
        let res = {}.toString.call(checkType).split(' ') [1].split('] ') [0].toLowerCase() // Regex can be used
        return res
    }
    window.selfType = selfType
})()

selfType(' ')        //"string"
selfType(1)     //"number"
selfType(null)      //"null"
selfType(undefined)     //"undefined"
selfType(function(){})     //"function"
selfType({})    //"object"
Copy the code

Sixth, the end

Thanks for reading so far, I’m Lin Yiyi, see you next time. If this article is of any help or inspiration to you, please give it a thumbs upgithub star