Instanceof的使用与重写

241 阅读2分钟

引子

通过本文你可以学习到instanceof的基本使用与方法重写

首先我们先来了解JS中的确定类型方法

确定类型

在JavaScript中,确定一个值的类型有好几种方法;

本篇文章主要讲述js给出的两种关键字确定类型的方法:typeofinstanceof

typeof 与 instanceof 的区别

虽然 typeof 好用,但它也有一个弊端,对于精准的确定类型来说不够严谨;如果值是对象或 null,那么 typeof 会返回 object(当然,这是一个历史遗留问题),如果是NaN则会返回number等等

但是instanceof就不同了,他可以根据变量是否是给定引用类型的实例进行判断,并在其原型链上查找;

原理是如果在检测的值在指定类型的原型链上存在,instanceof 操作符返回 true,否则为false

 console.log(obj instanceof Object); // true
 console.log(obj instanceof Array); // false
 console.log(typeof null === "object"); // true
 console.log(null instanceof Object); // false

按照定义,所有引用值都是 Object 的实例,因此通过 instanceof 操作符检测任何引用值和Object 构造函数都会返回 true。类似地,如果用 instanceof 检测原始值,则始终会返回 false,因为原始值不是对象 ( ̄▽ ̄)"

重写Instanceof

思路: 让值顺着原型链去找类型的原型,如果匹配成功就返回true,否则为false;

/**
 * @param {*} left  要检测的值
 * @param {*} right  要检测的类型
 * @returns {Boolean} 返回布尔值
 */

function Instanceof(left, right) {
    // 循环执行left的原型链上的每个属性,如果找到right,则返回true,否则返回false
    while (true) {
        // 如果left的原型链上没有属性,则返回false
        if (left == null) {
        return false;
        }
        // 如果left的原型链上的属性和right相同,则返回true
        if (left.__proto__ === right.prototype) {
            return true;
        }
        // 否则,继续循环执行left的原型链上的每个属性
        left = left.__proto__;
    }
}

ps: 遍历的过程莫名跟遍历链表下一个结点有异曲同工之妙

最后如果本文对于本文有疑惑,还请指导勘正 (●'◡'●)