likes
comments
collection
share

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

作者站长头像
站长
· 阅读数 9

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

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

typeof的神秘面纱

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

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

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

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

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

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

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

我们可以看到,除了可以准确的判断出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 它的返回值为布尔值。 让我们来测试一下

揭开typeof和instanceof类型判断的面纱,让你了解它们的真面目 我们可以看到instanceof可以准确的判断出引用类型,那能否判断出原始类型呢?答案是否定的

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

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

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

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

手写instanceof

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的神秘面纱了,判断左边的隐式原型是否等于右边的显示原型。 我们来看一下效果。

//收写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));

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

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

总结

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

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

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

转载自:https://juejin.cn/post/7345774436703158335
评论
请登录