Maybe you and I have never met, but we may not have met. I am a head fish
Asked hemp
I believe my friends have been asked to realize XXX by hand more than once in the interview, and batehead fish has also been asked similar questions for n times. There is one topic which has profound reflection, instanceof implementation principle. In this article, I would like to try to realize XXX in at least three ways with everyone.
Bighead handwriting realization Warehouse (350 STAR), you need handwriting, welcome to click to have a look
Github.com/qianlongo/f…
Usage review
The instanceof operator is used to check whether the constructor’s prototype property appears on the prototype chain of an instance object. On the MDN
function Car(make, model, year) {
this.make = make;
this.model = model;
this.year = year;
}
const auto = new Car('Honda'.'Accord'.1998);
console.log(auto instanceof Car);
// expected output: true
console.log(auto instanceof Object);
// expected output: true
Copy the code
Prototype chain Review
Prototype and prototype chain are the most important knowledge points to implement instanceof. Here is a brief review and recommend two well-written articles.
- You need to know about prototypes and prototype chains
- This is probably the best nuggets talk about “prototype chain”, the most easy to understand, with exercises
See figure:
1.F is an instance object of Fo, and it will have a __proto__ attribute pointing to the prototype of Fo2.Fo inherits from Foo, whose prototype is an instance of Foo, and has a __proto__ attribute pointing to Foo's prototype3.Foo inherits from the top-level objectObjectAnd the prototype isObjectWill have a __proto__ attribute to point toObject.prototype
4. ObjectPrototype is already the top-level object to which its __proto__ attribute pointsnull
Copy the code
Code sample
const Foo = function (name, sex) {
this.name = name
this.sex = sex
}
Foo.prototype.showName = function () {
console.log(this.name)
}
const Fo = function (name) {
Foo.call(this, name)
}
Fo.prototype = Object.create(Foo.prototype)
const f = new Fo('Front End Bighead')
f.showName() // Front end bighead fish
Copy the code
Three implementations
To implement instanceof, you essentially just iterate through the prototype chain of the instance Object, looking up one by one to see if there is any prototype equal to Fn’s prototype, until the topmost Object is not found, then return false, otherwise return true
Key points:
- The constructor
The prototype of Fn
- The prototype chain of instance objects
Recursive implementation (Approach 1)
/ * * * *@param {*} Obj instance object *@param {*} Func constructor *@returns true false
*/
const instanceOf1 = (obj, func) = > {
// Must be an object or a function
if(! (obj && ['object'.'function'].includes(typeof obj))) {
return false
}
let proto = Object.getPrototypeOf(obj)
if (proto === func.prototype) {
return true
} else if (proto === null) {
return false
} else {
return instanceOf1(proto, func)
}
}
/ / test
let Fn = function () {}let p1 = new Fn()
console.log(instanceOf1({}, Object)) // true
console.log(instanceOf1(p1, Fn)) // true
console.log(instanceOf1({}, Fn)) // false
console.log(instanceOf1(null, Fn)) // false
console.log(instanceOf1(1, Fn)) // false
Copy the code
Traversal implementation (Approach 2)
/ * * * *@param {*} Obj instance object *@param {*} Func constructor *@returns true false
*/
const instanceOf2 = (obj, func) = > {
// Must be an object or a function
if(! (obj && ['object'.'function'].includes(typeof obj))) {
return false
}
let proto = obj
while (proto = Object.getPrototypeOf(proto)) {
if (proto === func.prototype) {
return true}}return false
}
/ / test
let Fn = function () {}let p1 = new Fn()
console.log(instanceOf2({}, Object)) // true
console.log(instanceOf2(p1, Fn)) // true
console.log(instanceOf2({}, Fn)) // false
console.log(instanceOf2(null, Fn)) // false
console.log(instanceOf2(1, Fn)) // false
Copy the code
Traversal implementation (Approach 3)
/ * * * *@param {*} Obj instance object *@param {*} Func constructor *@returns true false
*/
const instanceOf3 = (obj, func) = > {
// Must be an object or a function
if(! (obj && ['object'.'function'].includes(typeof obj))) {
return false
}
let proto = Object.getPrototypeOf(obj)
// Because there must be an end (topmost Object), it is not an infinite loop
while (true) {
if (proto === null) {
return false
} else if (proto === func.prototype) {
return true
} else {
proto = Object.getPrototypeOf(proto)
}
}
}
/ / test
let Fn = function () {}let p1 = new Fn()
console.log(instanceOf3({}, Object)) // true
console.log(instanceOf3(p1, Fn)) // true
console.log(instanceOf3({}, Fn)) // false
console.log(instanceOf3(null, Fn)) // false
console.log(instanceOf3(1, Fn)) // false
Copy the code
The last
I hope I can share practical, basic and advanced knowledge points with you all the time.
I look forward to your attention in nuggets: front end bighead fish, you can also find me in the public number: front end bighead fish.