instanceof

  • Detects whether an instance belongs to this class
const arr = [10.20]
const obj = {
    0: 10.1: 20.length: 2
}
console.log(arr instanceof Array) // true
console.log(obj instanceof Array) // false
Copy the code
  • Based on theinstanceofYou can subdivide different types of objects “and also detect primitive type object values created using constructors.”
const m = new Number(100)
console.log(m instanceof Number) // true
Copy the code
  • There are a lot of problems with being a temporary man

    • Principle:instanceofBefore calling[Symbol.hasInstance]Method based on whether its return value belongs to an instance of the class
    class Fn {
        static[Symbol.hasInstance]() {
            console.log('OK')
            return false // The instance can be determined based on the current return value}}const f = new Fn
    console.log(f instanceof Fn) // false
    Copy the code
    • __proto__ checks if the prototype of the current constructor is present in the prototype chain of the current instance, and returns true if it is

    • The prototype chain of all instances ends up pointing to Object.prototype, so instanceof Object is true for all instances

    const arr = [1.2]
    console.log(arr instanceof Object) // true
    Copy the code
    • inJSThe prototype chain is changeable, so the result is inaccurate
    function Fn() {}
    Fn.prototype = Array.prototype
    const f = new Fn
    console.log(f instanceof Array)
    Copy the code
    • Basic data type values created in a literal manner cannot be based oninstanceofBecause it is not an object itself, it does not exist__proto__This thing
    const n = 10
    console.log(n instanceof Number) // false
    Copy the code

Rewrite instanceof :(detection principle)

  • Constructor Symbol. HasInstance property method

  • Checks if the constructor’s prototype appears on the instance’s __proto__

  • Cannot detect primitive datatypes, instances of which must be objects whose own methods handle primitive datatypes.

const instance_of = function instance_of(example, classFunc) {
    if(typeofclassFunc ! = ='function') throw new TypeError('Right-hand side of "instanceof" in not callable') 
    if(example == null) return false
    
    // Support Symbol and have Symbol. HasInstance to handle this
    if(typeof Symbol! = ='undefined') {
        const hasInstance = classFunc[Symbol.hasInstance]
        if(typeof hasInstance === 'function') {
            return hasInstance.call(classFunc, example)
        } 
    }
    
    // Unsupported implementations are based on the detection prototype chain
    const prototype = classFunc.prototype
    const proto = Object.getPrototypeOf(example)
    // Arrow functions have no prototype
    if(! prototype)return false 
    while(true) {
        // Find object.prototype.__proto__ base class
        if(proto === null) return false
        // An instance of the class is found on the prototype
        if(proto === prototype) return true
        proto = Object.getProtoTypeOf(proto)
    }
}

const res = instance_of([12.23].Array)
Copy the code