检查是否是类的对象实例

42 阅读1分钟

请你编写一个函数,检查给定的值是否是给定类或超类的实例。

可以传递给函数的数据类型没有限制。例如,值或类可能是  undefined 。

示例 1:

输入: func = () => checkIfInstance(new Date(), Date)
输出: true
解释: 根据定义,Date 构造函数返回的对象是 Date 的一个实例。

示例 2:

输入: func = () => { class Animal {}; class Dog extends Animal {}; return checkIfInstance(new Dog(), Animal); }
输出: true
解释:
class Animal {};
class Dog extends Animal {};
checkIfInstanceOf(new Dog(), Animal); // true

DogAnimal 的子类。因此,Dog 对象同时是 DogAnimal 的实例。

示例 3:

输入: func = () => checkIfInstance(Date, Date)
输出: false
解释: 日期的构造函数在逻辑上不能是其自身的实例。

示例 4:

输入: func = () => checkIfInstance(5, Number)
输出: true
解释: 5 是一个 Number。注意,"instanceof" 关键字将返回 false

简单解答

var checkIfInstanceOf = ()=>{
    if (obj === null || obj === undefined || !(classFunction instanceof Function)) {
        return false;
    }
    return Object(obj) instanceof classFunction
}

标准解答

不使用instanceof,或者变一个问法:如何手写一个instanceof 函数?

/**
 * @param {*} obj
 * @param {*} classFunction
 * @return {boolean}
 */
var checkIfInstanceOf = function (obj, classFunction) {
    // 检测构造函数的类型
    if (typeof classFunction !== 'function') {
        return false;
    }
    // 检测对象的类型:不能为空
    if (obj === null || obj === undefined) {
        return false;
    }
    // 拿到当前构造函数的原型
    let proto = Object.getPrototypeOf(obj);
    // 原型不为空
    while (proto !== null) {
        // 根据原型链关系进行对比
        if (proto === classFunction.prototype) {
            // 符合则返回true
            return true;
        }
        // 不符合则继续获取原型
        proto = Object.getPrototypeOf(proto);
    }
    // 最终不符合返回false
    return false;
};

/**
 * checkIfInstanceOf(new Date(), Date); // true
 */