- 题目链接:
https://leetcode.cn/problems/check-if-object-instance-of-class/description/ - 难度:简单
- 类型:JavaScript/原型链/类型判断
题目要点
- 给定
value与classFn,判断value是否是classFn或其超类的实例。 - 需要考虑
undefined、null、非函数的classFn。 - 对原始类型与其包装类(如
5与Number)要正确处理。
解法一:instanceof + 原始类型映射(推荐)
- 思路:
- 优先用
instanceof判断对象与原型链关系(内部会调用Symbol.hasInstance)。 - 对原始类型做特判,使
number → Number、string → String、boolean → Boolean、bigint → BigInt、symbol → Symbol返回true。 - 非法输入(
classFn非函数或任一为null/undefined)返回false。
- 优先用
js
/**
* 检查值是否为给定类或其超类的实例
* @param {*} value - 任意值
* @param {*} classFn - 目标类(构造函数)
* @returns {boolean} - 是否为实例
*/
const checkIfInstance = (value, classFn) => {
if (classFn == null || value == null || typeof classFn !== 'function') return false
if (value instanceof classFn) return true
const t = typeof value
if (classFn === Number) return t === 'number'
if (classFn === String) return t === 'string'
if (classFn === Boolean) return t === 'boolean'
if (classFn === BigInt) return t === 'bigint'
if (classFn === Symbol) return t === 'symbol'
return false
}
-
复杂度:
instanceof的原型链检查为O(h)(h为原型链高度)。- 原始类型映射为
O(1)。
-
边界说明:
checkIfInstance(Date, Date) → false(Date是Function的实例)。checkIfInstance(5, Number) → true(与题目示例一致)。checkIfInstance(5, Object) → false(不把原始值视作Object的实例)。checkIfInstance(null, Object) → false。
解法二:手写原型链遍历 + 原始类型特判
- 思路:
- 对对象与函数:沿
Object.getPrototypeOf逐层向上,判断是否等于classFn.prototype。 - 对原始类型:做与解法一相同的映射特判。
- 对对象与函数:沿
js
/**
* 通过手写原型链判断实例关系
* @param {*} value - 任意值
* @param {*} classFn - 目标类(构造函数)
* @returns {boolean} - 是否为实例
*/
const checkIfInstanceByProto = (value, classFn) => {
if (classFn == null || typeof classFn !== 'function') return false
if (value == null) return false
const t = typeof value
if (classFn === Number) return t === 'number'
if (classFn === String) return t === 'string'
if (classFn === Boolean) return t === 'boolean'
if (classFn === BigInt) return t === 'bigint'
if (classFn === Symbol) return t === 'symbol'
let proto = Object.getPrototypeOf(value)
const target = classFn.prototype
while (proto) {
if (proto === target) return true
proto = Object.getPrototypeOf(proto)
}
return false
}
- 说明:与
instanceof等价于遍历原型链的判断,但仍需对原始类型做特判。
解法三:利用 Symbol.hasInstance(了解)
- 思路:
instanceof内部会调用classFn[Symbol.hasInstance](value),可显式使用以获得可定制的实例判断行为。- 对多数内置类型,直接用
instanceof即可;手动调用一般用于定制类。
js
/**
* 基于 Symbol.hasInstance 的实例判断
* @param {*} value - 任意值
* @param {*} classFn - 目标类(构造函数)
* @returns {boolean} - 是否为实例
*/
const checkIfInstanceByHasInstance = (value, classFn) => {
if (classFn == null || value == null || typeof classFn !== 'function') return false
const hasInst = classFn[Symbol.hasInstance]
if (typeof hasInst === 'function' && hasInst.call(classFn, value)) return true
const t = typeof value
if (classFn === Number) return t === 'number'
if (classFn === String) return t === 'string'
if (classFn === Boolean) return t === 'boolean'
if (classFn === BigInt) return t === 'bigint'
if (classFn === Symbol) return t === 'symbol'
return false
}
示例与验证
js
class Animal {}
class Dog extends Animal {}
console.log('1:', checkIfInstance(new Date(), Date)) // true
console.log('2:', checkIfInstance(new Dog(), Animal)) // true
console.log('3:', checkIfInstance(Date, Date)) // false
console.log('4:', checkIfInstance(5, Number)) // true
console.log('5:', checkIfInstance(() => {}, Function)) // true
console.log('6:', checkIfInstance(5, Object)) // false
console.log('7:', checkIfInstance(null, Object)) // false
console.log('8:', checkIfInstance(undefined, Number)) // false
总结
- 推荐以
instanceof为主,原始类型补充为辅,满足题目示例与语义直觉。 - 若需要可定制的行为,可考虑
Symbol.hasInstance,但一般场景不必复杂化。