关于instanceof和typeof区和与个人理解

91 阅读1分钟

instanceof运算符

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

object instanceof constructor => 某个实例 instanceof 某个构造函数。

instanceof用法:

function Parent() {
  this.name = 'parent';
}
const child = new Parent();
console.log(child instanceof Parent) // true
console.log(child instanceof Object) // true

关于instanceof的实现:

function Parent() {
  this.name = 'parent';
}
const child = new Parent();
const myInstanceofHandler = (left, right) => {
  let leftProto = Object.getPrototypeOf(left); // 获取实例的原型
  if (Object.prototype.toString.call(right) !== '[object Function]' && Object.prototype.toString.call(right) !== '[object Object]') {
    throw Error("Right-hand side of 'myInstanceofHandler' is not an object")
  }
  const rightProto = right.prototype; // 获取右边原型
  while(true) {
    if (!leftProto) return false; // 如果为null,说明原型链到尽头了
    if (leftProto === rightProto) {
      return true
    }
    leftProto = Object.getPrototypeOf(leftProto) // 继续向上查找原型
  }
}
console.log(myInstanceofHandler(child, Parent)) // true

想搞明白instanceof得先明白原型链,可以看一下这篇文章github.com/mqyqingfeng…

// 几个原型链相关的例子
console.log(Object instanceof Object) // true
console.log(Object instanceof Function) // true
console.log(Function instanceof Function) // true
console.log(Parent instanceof Object) // true

typeof

typeof一般用来判断基本数据类型,因为涉及到引用数据类型它就判断不出来了,引用数据类型都会判断成object,可以用来判断number,string,symbol,undefined,boolean

js 底层在机器吗的1-3位存放的是数据的类型
-   000:对象
-   010:浮点数
-   100:字符串
-   110:布尔
-   1:整数
// 还有异类
-   null的机器码全是0,这也是为什么typeof判断null会是一个对象
-   undefined的机器码是-2^30来表示
因为对象的机器吗都是000,js中数组,函数都认为是不同属性的对象

Object.protoType.toString.call

我比较喜欢用这个来判断引用数据类型,当然也能判断基本数据类型

Object.prototype.toString.call('string') // [object String]

Object.prototype.toString.call(1) // [object Number]

Object.prototype.toString.call(Symbol(1)) // [object Symbol]

Object.prototype.toString.call(true) // [object Boolean]

Object.prototype.toString.call(null) // [object Null]

Object.prototype.toString.call(undefined) // [object Undefined]

Object.prototype.toString.call({test:'test'}) // [object Object]

Object.prototype.toString.call([1, 2]) // [object Array]

Object.prototype.toString.call(() => {}) // [object Function]