揭开typeof和instanceof类型判断的面纱,让你了解它们的真面目

揭开 typeof和instanceof都为类型判断的面纱,了解它们本质的区别

哈喽哈喽,我是你们的金樽清酒,说到类型判断我们脑海里就会想起typeof和instanceof。但是每次都会分不清楚什么时候用typeof和intanceof。说到这里有小伙伴说这个我知道呀,原始类型的判断用typeof,引用类型用instanceof。但是这么判断的实质是什么呢?接下来就让我们一起来揭秘吧。

typeof的神秘面纱

typeof可以清楚的判断原始除null之外的原始类型

  • 原始类型的种类: number string boolean Symbol null undefined bigint 我们分别用typeof来给它们进行类型判断

可以看到除了null之外都准确的进行了类型判断,emmmm,这个null有点奇怪。为什么会被判断为object呢?再让我们看看typeof 能不能判断引用类型。

  • 常见的引用类型 object、Array、RegExp、Date、Function、特殊的基本包装类型 (String、Number、Boolean)以及单体内置对象 (Global、Math)。

那让我们实验一下typeof能不能对它们进行类型判断呢?

我们可以看到,除了可以准确的判断出function以外,所有的引用类型都会被判断成object。

从typeof的结果来看,它只能判断除null以外的原始类型和function这个引用类型。 为什么null会被判断为object,这是一个历史遗留问题,从js诞生开始null就会被typeof识别为objec,因为不同的数据类型在js中都有一个标识符,前三个字符为零则会被typeof识别为object,而null的标识符全为零,自然会被识别为object。

所以我们可以揭开typeof的神秘面纱,typeof是根据那个标识符来进行类型判断的的,所以可以判断出原始类型,而不能判断出引用类型。而null会被这个机制错误的判断成object,这是一个历史遗留问题,虽然这个问题能够被解决,但是js已经被广泛使用,进行重构可能会导致很多的程序崩塌,所以这个遗留问题最好是不去解决。

instanceof的神秘面纱

我们知道,instanceof是被用来判断引用数据类型的。原始数据类型不能够进行判断。

  • 语法 object instanceof constructor 它的返回值为布尔值。 让我们来测试一下

我们可以看到instanceof可以准确的判断出引用类型,那能否判断出原始类型呢?答案是否定的

那为什么只能判断出引用类型而不能判断原始类型呢?因为instanceof的原理是进行原型链判断,而原始类型不存在原型链所以不能进行判断。

我们可以看到两个构造函数,a为A构造函数的实例对象,也就a继承了A的原型,所以用instanceof进行判断就会是true,而a没有B的原型所以为false。但是都会被判断为Object,因为会顺着原型链往下找,看能不能找到Object原型。

手写instanceof

js 复制代码
function myInstanceof(L, R) {
    L = L.__proto__
    R = R.prototype
    while (L !== R) {
        L = L.__proto__
        if (L === null) return false
    }
    return true
}//这就是自己打造的一个instanceof

我们没有办法和官方一样打造成关键字,所以只能写成一个函数,里面有两个参数。左边是隐式原型,右边是构造函数的显示原型,当没有找到该原型的时候就顺着原型链往上找,直到找到null为止。引用类型的原型链都有一个Object,所以引用类型一定可以判断为Obeject。这也就是instancof的神秘面纱了,判断左边的隐式原型是否等于右边的显示原型。 我们来看一下效果。

js 复制代码
//收写instanceof
function A() {
    a = 1
}
function B() {
    b = 1
}

a = new A()
function myInstanceof(L, R) {
    L = L.__proto__
    R = R.prototype
    while (L !== R) {
        L = L.__proto__//顺着原型链往上找
        if (L === null) return false
    }
    return true
}//这就是自己打造的一个instanceof
console.log(myInstanceof(a, B));
console.log(myInstanceof(a, A));
console.log(myInstanceof(a, Object));

可以看到达到了我们想要的效果。简简单单手撕instanceof。

总结

typeof是根据数据类型中某一个标识符的前三位进行判断的,而null和引用类型都为0,所以引用类型和null都为Object。

instanof是根据原型链进行判断的,左边的隐式原型顺着原型链找能不能找到一个和右边形式原型相等的值,能则返回true,不能返回false。

凄风冷雨满江城,志士仁人在山峰。 纵使前路风雨阻,不到黄河不死心。

相关推荐
大怪v33 分钟前
【Virtual World 04】我们的目标,无限宇宙!!
前端·javascript·代码规范
努力学算法的蒟蒻36 分钟前
day27(12.7)——leetcode面试经典150
算法·leetcode·面试
狂炫冰美式1 小时前
不谈技术,搞点文化 🧀 —— 从复活一句明代残诗破局产品迭代
前端·人工智能·后端
xw52 小时前
npm几个实用命令
前端·npm
!win !2 小时前
npm几个实用命令
前端·npm
代码狂想家2 小时前
使用openEuler从零构建用户管理系统Web应用平台
前端
dorisrv3 小时前
优雅的React表单状态管理
前端
蓝瑟3 小时前
告别重复造轮子!业务组件多场景复用实战指南
前端·javascript·设计模式
dorisrv4 小时前
高性能的懒加载与无限滚动实现
前端
韭菜炒大葱4 小时前
别等了!用 Vue 3 让 AI 边想边说,字字蹦到你脸上
前端·vue.js·aigc