跳到主要内容

instanceof和typeof判断类型

typeof操作符

Ecmascript 2021 - the typeof operator

对于typeof操作符,它主要用在判断数据类型,而不是像instanceof判断原型对象等等。它是一个一元表达式,typeof target就用来得到target的类型结果,结果如下面的返回值表。

返回值表

Type of valResult
Undefined"undefined"
Null"object"
Boolean"boolean"
Number"number"
String"string"
Symbol"symbol"
BigInt"bigint"
Object (does not implement [[Call]])"object"
Object (implements [[Call]])"function"

对于引用数据类型,js只会通过判断它的原型链上是否实现了[[Call]]这个标记来决定是否是functionobject。那么区分call的方法就是是否有call这个函数(或者可以用()来进行调用)

instanceof操作符

Ecmascript 2021 - the instanceof operator

根据规范中的instanceof的描述,instanceof接收2个参数,一个是V,一个是Target,(an EcmaScript Launguage value,也就是js中的一个值)。 instanceof的使用方法是 T instanceof Target,得到一个返回值为true或者false

下面是instanceof的一些操作方法和结果

  1. If Type(target) is not Object, throw a TypeError exception.
  2. Let instOfHandler be ? GetMethod(target, @@hasInstance).
  3. If instOfHandler is not undefined, then a. Return ! ToBoolean(? Call(instOfHandler, target, « V »)).
  4. If IsCallable(target) is false, throw a TypeError exception.
  5. Return ? OrdinaryHasInstance(target, V).

报错条件

  1. 根据第一条,如果target不是一个对象,那么会抛出TypeError的异常。
  2. 根据第4条,如果target不是IsCallable,也会抛出TypeError异常
    1. 关于这个isCallable,也就是是否可调用。像js中的ObjectFunction等等,实际上都是一个函数,而函数本质上也是一个对象,在对象上面有一些属性,那么在这些属性里面会有一个call可以标志它们是可调用的。所以 ObjectString等等以及自定义的函数都可以作为这里的target。

返回值结果

  1. 根据第2点可以知道如果 @@hasInstance 为undefined则直接返回false,判断是否有这样的一个@@hasInstance属性,这是一个符号对应的是Symbol.hasInstance的属性,那么需要访问这个@@hasInstance属性可以使用下面的方式。
const target = new Function;
console.log(target[Symbol.hasInstance])
//输出f(...)
  1. 根据第3点知道,如果 @@hasInstance不为undefined,则将V的值传入Target中的@@hasInstance来调用,将结果返回。那么就有下面的代码
//创建一个函数名字为func,那么在这里我们知道这个func肯定是instanceof Function为true的,那么现在通过@@hasInstance来得到结果。
function func(){}

console.log(Function[Symbol.hasInstance](func))
//输出true
console.log(func instanceof Function)
//输出true,这2者是等价的