preface

This article documents a handwritten implementation of the instanceof operator.

Related articles recommended

  • Interviewer series: Please write an anti – shake or throttle function debounce/throttle
  • 10 minutes quick handwriting implementation: Call /apply
  • 5 minutes quick handwriting implementation: bind
  • 5 minutes fast handwriting implementation: new

describe

The instanceof operator is used to test whether constructor. Prototype exists on the prototype chain of the parameter Object.

grammar

object instanceof constructor
Copy the code

parameter

  • object

    An instance object

  • constructor

    A constructor

After clear basic information, the following nonsense does not say directly open whole

1. The first edition of instanceof

function myInstanceof1(L, R) {
    // Declare a variable to get the __proto__ of the object
    let link = L.__proto__
    // Loop (when link finally points to null, return false if null is not found)
    while(link ! = =null) {
        // Return true if r.protoType is found on the prototype chain of L
        if(link === R.prototype) return true
        // Step down
        link = link.__proto__
    }
    return false
}

/ / test

function Car(make, model, year) {
  this.make = make;
  this.model = model;
  this.year = year;
}
const auto = new Car('Honda'.'Accord'.1998);

console.log(myInstanceof1(auto, Car)); // true
console.log(myInstanceof1(auto, Object)); // true

console.log(auto instanceof Car); // true
console.log(auto instanceof Object); // true

Copy the code

The first version completed the mainline functionality, but all that was left to do was check functions, handle bounds, and handle exceptions. Everywhere. That’s what happens.

Talking about the first version of the problem, it was obvious that input parameters needed validation

2. Instanceof version 2

How does Instanceof handle the left and right parameters

1 instanceof Number // false
' ' instanceof String // false
true instanceof Boolean // false
null instanceof Boolean // false
NaN instanceof Number // false
undefined instanceof Number // false
0 instanceof Number // falseAnd you can see that for the left-hand parameter whatever type of parameter you put in, rightinstanceofIt's all normal execution. Let's try the right sidevar a = {}
a instanceof 1 // Uncaught TypeError: Right-hand side of 'instanceof' is not an object
a instanceof ' ' // Uncaught TypeError: Right-hand side of 'instanceof' is not an object
a instanceof true // Uncaught TypeError: Right-hand side of 'instanceof' is not an object
a instanceof null // Uncaught TypeError: Right-hand side of 'instanceof' is not an object
a instanceof NaN // Uncaught TypeError: Right-hand side of 'instanceof' is not an object
a instanceof undefined // Uncaught TypeError: Right-hand side of 'instanceof' is not an object
a instanceof 0 // Uncaught TypeError: Right-hand side of 'instanceof' is not an object
a instanceof {} // Uncaught TypeError: Right-hand side of 'instanceof' is not callable
Copy the code

Check the left and right input parameters according to the above results

function myInstanceof2(L = null, R) {
    // Return false if the left argument is non-object
    if (Object(L) ! == L)return false
    // The arguments on the right can be considered functions only and cannot have a Prototype attribute
    if (typeofR ! = ='function'| |! R.prototype)throw new TypeError('Right-hand side of 'instanceof' is not an object')
    // Declare a variable to get the __proto__ of the object
    let link = L.__proto__
    // Loop (when link finally points to null, return false if null is not found)
    while(link ! = =null) {
        // Return true if r.protoType is found on the prototype chain of L
        if(link === R.prototype) return true
        // Step down
        link = link.__proto__
    }
    return false
}

/ / test

function Car(make, model, year) {
  this.make = make;
  this.model = model;
  this.year = year;
}
const auto = new Car('Honda'.'Accord'.1998);

console.log(myInstanceof2(1, Car)); // false
console.log(myInstanceof2(' ', Car)); // false
console.log(myInstanceof2(true, Car)); // false
console.log(myInstanceof2(null, Car)); // false
console.log(myInstanceof2(undefined, Car)); // false
console.log(myInstanceof2(0, Car)); // false

console.log(myInstanceof2(auto, 1)); // Uncaught TypeError: Right-hand side of 'instanceof' is not an object
console.log(myInstanceof2(auto, ' ')); // Uncaught TypeError: Right-hand side of 'instanceof' is not an object
console.log(myInstanceof2(auto, true)); // Uncaught TypeError: Right-hand side of 'instanceof' is not an object
console.log(myInstanceof2(auto, null)); // Uncaught TypeError: Right-hand side of 'instanceof' is not an object
console.log(myInstanceof2(auto, undefined)); // Uncaught TypeError: Right-hand side of 'instanceof' is not an object
console.log(myInstanceof2(auto, 0)); // Uncaught TypeError: Right-hand side of 'instanceof' is not an object
console.log(myInstanceof2(auto, {})); // Uncaught TypeError: Right-hand side of 'instanceof' is not an object


console.log(myInstanceof2(auto, Car));
// expected output: true
console.log(myInstanceof2(auto, Object));
// expected output: true

console.log(auto instanceof Car);
// expected output: true
console.log(auto instanceof Object);
// expected output: true

Copy the code

So let’s see what happensThe instanceof operatorFeedback results are consistent, so far aboutThe instanceof operatorThe end of the

3. Final version

function myInstanceof(L = null, R) {
    // Return false if the left argument is non-object
    if (Object(L) ! == L)return false
    // The arguments on the right can be considered functions only and cannot have a Prototype attribute
    if (typeofR ! = ='function'| |! R.prototype)throw new TypeError('Right-hand side of 'instanceof' is not an object')
    // Declare a variable to get the __proto__ of the object
    let link = L.__proto__
    // Loop (when link finally points to null, return false if null is not found)
    while(link ! = =null) {
        // Return true if r.protoType is found on the prototype chain of L
        if(link === R.prototype) return true
        // Step down
        link = link.__proto__
    }
    return false
}
Copy the code

Related knowledge:

  • Prototype, prototype chain correlation
  • The while loop
  • Es6 default parameter

The last

If do not understand, there is a question of welcome clap brick! (ఠ e ఠ) Blue!!