手撕Js中的instanceof【真的不要太简单】

简介: 引子首先,在我们手撕instanceof的时候,我们先来看看他都有什么用处?

引子

首先,在我们手撕instanceof的时候,我们先来看看他都有什么用处?

let arr = []
let fn = function fn() {}
let obj = {}
let num = 2020
console.log(arr instanceof Array) //true
console.log(arr instanceof Object) //true
console.log(arr instanceof Function) //false
console.log(arr instanceof Number) //false
console.log(fn instanceof Array) //false
console.log(fn instanceof Object) //true
console.log(fn instanceof Function) //true
console.log(fn instanceof Number) //false
console.log(obj instanceof Array) //false
console.log(obj instanceof Object) //true
console.log(obj instanceof Function) //false
console.log(obj instanceof Number) //false
console.log(num instanceof Array) //false
console.log(num instanceof Object) //false
console.log(num instanceof Function) //fasle
console.log(num instanceof Number) //fasle

instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。 —MDN

上面这段话来自MDN,可以说是很形象了,检测构造函数的原型是否出现在某个实例的原型链上,

i.e. & e.g.

instanceof 运算符用于检测Array.prototype属性是否出现在 arr._proto.__proto…上

正文

instanceof的原理

  • 内置类的Symbol.hasInstance属性方法
  • 检测构造函数的prototype是否出现在实例的__proto__上
  • 不能检测基本数据类型
function instance_of(example, classFunc) {
  // 检测classFunc必须是个函数
  if( typeof classFunc !== function ) throw new TypeError('')
  // 先看看浏览器支持不支持Symbol,此处延伸:Symbol的作用?Symbol兼容哪些浏览器?
  if( typeof Symbol !== 'undefined' ) {
    //支持的话先看看classFunc有没有 Symbol.hasInstance这个属性,一般情况下,内置类都会有,可以直接用来检测一个实例,并且他是一个函数,接受一个参数
    var hasInstance = classFunc[Symbol.hasInstance]
    if( typeof hasInstance === 'function' ) {
      //此处用call改变一下this指向,延伸:为甚么此处hasInstance不能直接调用?this指向了谁?
      return hasInstance.call(classFunc, example)
    }
  }
  var proto = example.__proto__, 
    prototype = classFunc.prototype
  if( proto && prototype) {
    // 实例必须有__proto__ && 函数必须有 prototype
    // 基本数据类型没有 __proto__ 箭头函数没有 prototype, class类里的fn(){}这种函数也没有 prototype
    while(true){
      if( proto === null ) return false //找到头了
      if( proto === prototype ) return true // 找到了
      proto = proto.__proto__
    }
  } else {
    return false
  }
}
instance_of([], Array) // true
目录
相关文章
|
3月前
|
JavaScript 前端开发
js确定数据类型typeof与instanceof
js确定数据类型typeof与instanceof
31 0
|
4月前
|
JavaScript
js【详解】instance of
js【详解】instance of
43 0
|
6月前
|
前端开发 JavaScript
前端 JS 经典:typeof 和 instanceof 区别
前端 JS 经典:typeof 和 instanceof 区别
116 0
|
6月前
|
JavaScript 前端开发
JavaScript中Object.prototype.toString.call()、instanceOf和Array.isArray()的区别
JavaScript中Object.prototype.toString.call()、instanceOf和Array.isArray()的区别
79 1
|
6月前
|
JavaScript 前端开发 测试技术
探究 JavaScript 类型检查的利器:typeof 和 instanceof
探究 JavaScript 类型检查的利器:typeof 和 instanceof
|
6月前
|
JavaScript 前端开发
JavaScript中Object.prototype.toString.call()、instanceOf和Array.isArray()的区别
JavaScript中Object.prototype.toString.call()、instanceOf和Array.isArray()的区别
|
11月前
|
JavaScript 前端开发
JavaScript学习(六十三)—typeof和instanceof检测数据类型的异同
JavaScript学习(六十三)—typeof和instanceof检测数据类型的异同
|
JavaScript
js基础笔记学习121-instanceOf
js基础笔记学习121-instanceOf
54 0
js基础笔记学习121-instanceOf
|
JavaScript 前端开发
JavaScript总结:typeof与instanceof的区别,及Object.prototype.toString()方法
JavaScript总结:typeof与instanceof的区别,及Object.prototype.toString()方法
183 0
JavaScript总结:typeof与instanceof的区别,及Object.prototype.toString()方法
|
JavaScript
扒下JS的“底裤”之 instanceof 运算符详解
扒下JS的“底裤”之 instanceof 运算符详解
130 0