instanceof和typeof判断类型
typeof操作符
Ecmascript 2021 - the typeof operator
对于typeof操作符,它主要用在判断数据类型,而不是像instanceof判断原型对象等等。它是一个一元表达式,typeof target就用来得到target的类型结果,结果如下面的返回值表。
返回值表
| Type of val | Result |
|---|---|
| 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]]这个标记来决定是否是function或object。那么区分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的一些操作方法和结果
- If Type(target) is not Object, throw a TypeError exception.
- Let instOfHandler be ? GetMethod(target, @@hasInstance).
- If instOfHandler is not undefined, then a. Return ! ToBoolean(? Call(instOfHandler, target, « V »)).
- If IsCallable(target) is false, throw a TypeError exception.
- Return ? OrdinaryHasInstance(target, V).
报错条件
- 根据第一条,如果target不是一个对象,那么会抛出
TypeError的异常。 - 根据第4条,如果target不是IsCallable,也会抛出
TypeError异常。- 关于这个
isCallable,也就是是否可调用。像js中的Object和Function等等,实际上都是一个函数,而函数本质上也是一个对象,在对象上面有一些属性,那么在这些属性里面会有一个call可以标志它们是可调用的。所以Object,String等等以及自定义的函数都可以作为这里的target。
- 关于这个
返回值结果
- 根据第2点可以知道如果 @@hasInstance 为undefined则直接返回false,判断是否有这样的一个
@@hasInstance属性,这是一个符号对应的是Symbol.hasInstance的属性,那么需要访问这个@@hasInstance属性可以使用下面的方式。
const target = new Function;
console.log(target[Symbol.hasInstance])
//输出f(...)
- 根据第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者是等价的