自定义instanceof运算符行为API: Symbol.hasInstance

作者:桜吹雪日期:2025/11/8

今天翻zod的源码,发现有个之前没见过的,应该也没听说的API:Symbol.hasInstance

1export /*@__NO_SIDE_EFFECTS__*/ function $constructor<T extends ZodTrait, D = T["_zod"]["def"]>(
2  name: string,
3  initializer: (inst: T, def: D) => void,
4  params?: { Parent?: typeof Class }
5): $constructor<T, D> {
6  // ...
7  // 
8  Object.defineProperty(_, Symbol.hasInstance, {
9    value: (inst: any) => {
10      if (params?.Parent && inst instanceof params.Parent) return true;
11      return inst?._zod?.traits?.has(name);
12    },
13  });
14}
15

发现有个写了几年代码都没发现的API,就拿去问ai了。


Symbol.hasInstance是 JavaScript 的一个内置 Symbol,用于自定义 instanceof运算符的行为

基本用法

默认情况下,instanceof检查对象的原型链:

1class Animal {}
2class Dog extends Animal {}
3
4const dog = new Dog();
5console.log(dog instanceof Dog);     // true
6console.log(dog instanceof Animal);   // true
7console.log(dog instanceof Object);   // true
8

使用 Symbol.hasInstance 自定义行为

你可以通过定义静态的 Symbol.hasInstance方法来改变 instanceof的行为:

1class MyClass {
2    static [Symbol.hasInstance](instance) {
3        // 自定义判断逻辑
4        return typeof instance === 'object' && 
5               instance !== null && 
6               instance.value === 42;
7    }
8}
9
10const obj1 = { value: 42 };
11const obj2 = { value: 100 };
12const obj3 = null;
13
14console.log(obj1 instanceof MyClass); // true
15console.log(obj2 instanceof MyClass); // false
16console.log(obj3 instanceof MyClass); // false
17

实际应用场景

1. 基于属性的实例检查

1class Validator {
2    static [Symbol.hasInstance](obj) {
3        return typeof obj === 'object' && 
4               obj !== null && 
5               typeof obj.validate === 'function';
6    }
7}
8
9const validObj = {
10    validate() { return true; }
11};
12
13const invalidObj = { name: "test" };
14
15console.log(validObj instanceof Validator);   // true
16console.log(invalidObj instanceof Validator);  // false
17

2. 数字范围检查

1class PrimeNumber {
2    static isPrime(num) {
3        if (num <= 1) return false;
4        for (let i = 2; i <= Math.sqrt(num); i++) {
5            if (num % i === 0) return false;
6        }
7        return true;
8    }
9    
10    static [Symbol.hasInstance](num) {
11        return Number.isInteger(num) && this.isPrime(num);
12    }
13}
14
15console.log(2 instanceof PrimeNumber);    // true
16console.log(7 instanceof PrimeNumber);    // true
17console.log(4 instanceof PrimeNumber);    // false
18console.log(9 instanceof PrimeNumber);    // false
19

3. 数组内容检查

1class NumericArray {
2    static [Symbol.hasInstance](arr) {
3        return Array.isArray(arr) && 
4               arr.every(item => typeof item === 'number');
5    }
6}
7
8console.log([1, 2, 3] instanceof NumericArray);     // true
9console.log([1, '2', 3] instanceof NumericArray);   // false
10

注意事项

  1. 1.必须是静态方法Symbol.hasInstance必须定义为类的静态方法
  2. 2.影响所有 instanceof 检查:会改变该类的所有实例检查行为
  3. 3.谨慎使用:过度使用可能使代码难以理解
1class CustomClass {
2    // 正确:静态方法
3    static [Symbol.hasInstance](instance) {
4        return true; // 所有对象都是实例
5    }
6    
7    // 错误:实例方法(不会生效)
8    [Symbol.hasInstance](instance) {
9        return false;
10    }
11}
12
13console.log({} instanceof CustomClass); // true(总是返回 true)
14

总结

Symbol.hasInstance的主要用途是让开发者能够自定义 instanceof运算符的逻辑,实现更灵活的类型检查机制。这在创建验证器、特殊数据类型的类或者需要复杂实例检查的场景中非常有用。

为什么这样设计

  • 灵活性:允许对象通过特征标记而非严格的类继承来表示类型
  • 组合优于继承:支持特征组合,一个对象可以有多个特征
  • 运行时类型检查:可以在运行时动态添加/移除类型特征

这种模式在需要灵活类型系统的库中很常见,特别是那些需要支持动态类型或混合类型的场景。


自定义instanceof运算符行为API: Symbol.hasInstance》 是转载文章,点击查看原文


相关推荐


Bash 的 md5sum 命令
hubenchang05152025/11/6

#Bash 的 md5sum 命令 md5sum [OPTION]... [FILE]... 功能 计算或校验 MD5 值。 类型 可执行文件(/usr/bin/md5sum),属于 coreutils。 参数 OPTION 选项: -b, --binary - 以二进制模式读取文件;类 UNIX 系统下始终是二进制模式 -c, --check - 从文件中读取 MD5 值进行校验 --tag- 生成 BSD 风格的输出 -t, --text - 以文本模式读取文件;类 UNIX 系统下不


虚拟机的未来:云计算与边缘计算的核心引擎(一)
jiushun_suanli2025/11/1

虚拟机定义与核心原理 虚拟机(VM)是指通过软件模拟实现的完整计算机系统,具有与物理计算机相同的功能。VM可以运行自己的操作系统和应用程序,就像独立的物理机器一样,但实际上是在共享的物理硬件资源上运行。 硬件虚拟化技术 硬件虚拟化是通过虚拟化层(hypervisor)在物理硬件和虚拟机之间建立抽象层,主要包括两种类型: 全虚拟化(Full Virtualization): 无需修改客户操作系统通过二进制翻译技术(如VMware的ESXi)或硬件辅助虚拟化(Intel VT-x/A


力扣热题100(前10道题目)
少年姜太公2025/10/30

前言 算法题几乎是面试必考的,许多同学一看到算法题就是一个头两个大,所以笔者这次准备把力扣热题100写成文章与jym一起学习,估计会分为10篇文章来写。在这个过程中会分享一些自己刷题的想法和思路,让大家能够轻松看懂,这些题目我会采用js来写,有看不懂js的同学可以看个思路然后换成自己熟悉的语言去写🔥 LeetCode 热题 HOT 100 在每道题目之前我都会把对应的题目链接贴出来,方便大家可以看完我的解法再去力扣上刷题,而且这些题目我会尽可能多种解法去写,大家可以参考一下。 160. 相交链


从原型到类:JavaScript面向对象编程的终极进化指南
良山有风来2025/10/27

你是不是也曾经被JavaScript的原型链绕得头晕眼花?每次看到__proto__和prototype就感觉在看天书?别担心,这几乎是每个前端开发者都会经历的阶段。 今天我要带你彻底搞懂JavaScript面向对象编程的进化之路。从令人困惑的原型到优雅的class语法,再到实际项目中的设计模式应用,读完本文,你不仅能理解JS面向对象的本质,还能写出更优雅、更易维护的代码。 原型时代:JavaScript的"上古时期" 在ES6之前,JavaScript面向对象编程全靠原型链。虽然语法看起来有点


Redis(81)Redis的缓存雪崩是什么?
Victor3562025/10/24

缓存雪崩的概念 缓存雪崩(Cache Avalanche)是指在某一时间段内,缓存中的大量数据同时过期,或者由于缓存服务器宕机导致大量请求直接打到数据库,导致数据库瞬时压力剧增,甚至可能导致数据库崩溃。 解决缓存雪崩的方法 为了解决缓存雪崩问题,可以采取以下几种策略: 缓存数据的过期时间设置为随机值:避免在同一时间大量缓存数据同时失效。 加锁或队列:在缓存失效时,通过机制控制对数据库的访问,避免大量请求同时打到数据库。 双写策略:更新缓存的同时也更新数据库,保证数据的一致性。 数据预热:在系统


KuiklyUI利用Kotlin Lambda函数实现声明式UI系统的深入分析
风冷2025/10/22

KuiklyUI利用Kotlin Lambda函数实现声明式UI系统的深入分析 KuiklyUI通过巧妙地利用Kotlin的lambda函数特性,构建了一套灵活、高效的声明式UI系统。本文将深入分析其实现机制和核心技术点。 一、Lambda函数在声明式UI中的核心应用 1. 接收器作用域函数的巧妙运用 KuiklyUI的声明式语法核心基于Kotlin的接收器作用域函数。在按钮组件ButtonView中,我们可以看到典型的实现: class ButtonView : ComposeView<But


面试问题—上家公司的离职原因
mapbar_front2025/10/21

面试结尾HR必问的问题,就是上一家公司的离职原因,作为多年的资深架构师,我做过多次终面,听到过千奇百怪的答案,有的真诚,有的官方,有的遮遮掩掩,有的情绪愤怒,这个问题是有正确答案的,今天就来和你分享一下。 1、真实的离职原因 其实离职无非就是两类原因,一类主动,一类被动。 主动,要么钱少,要么心累,但大多数情况都是钱少心又累。 被动,要么被行情拖累,要么末位淘汰,要么违纪被发现,这个问题只要不回答的稀碎,都不会影响你被录用。 2、避开下面两个错误答案 2.1、 破口大骂前公司前领导 有可能真的是


Redis(73)如何处理Redis分布式锁的死锁问题?
Victor3562025/10/20

处理Redis分布式锁的死锁问题,可以采取以下一些方法: 设置锁的自动过期时间: 使用EX和PX参数设置锁的超时时间,确保锁在持有过久后自动释放,避免死锁。 使用看门狗模式: 通过不断刷新锁的过期时间来维持锁的有效性,防止锁的持有者因为长时间操作而导致锁自动过期。 确保锁的唯一性和原子性: 使用具有唯一标识的锁值来确保释放锁时的准确性,避免因误删导致的死锁问题。 故障恢复机制: 在检测到锁持有者失效后,其他节点可以尝试获取锁,确保系统的高可用性。 下面是一个示


区块链技术的五大应用场景
终端域名2025/10/19

区块链技术凭借其去中心化、不可篡改和透明性等核心优势,已渗透至金融、供应链管理、医疗健康、知识产权保护及公共服务五大领域,成为重构信任机制与提升协作效率的关键技术。以下是对五大应用场景的详细阐述: 一、金融:重塑信任基石 跨境支付与清算 区块链通过分布式账本技术实现跨境交易的实时结算,显著降低传统SWIFT网络的中介成本和时间延迟。例如,Ripple、R3等区块链联盟已推动跨境汇款效率提升至分钟级,将跨国交易成本从每笔26美元降低至15美元。 数字货币与支付结算 央行数字货币(如中国


B站多模态精细画质分析模型在 ICCV2025 大赛获得佳绩
哔哩哔哩技术2025/10/17

前言 暑期,B站多媒体实验室带队参与了 ICCV MIPI (Mobile Intelligent Photography and Imaging) Workshop 的细粒度图像质量定位 (Detailed Image Quality Assessment Track) 国际挑战赛,提出创新的多模态训练策略,将综合指标提升了13.5%,最终获得了第二名的好成绩。本次参赛经历阶段性地验证了实验室在视频质量评价 (Video Quality Assessment,后文统称为 VQA) ,MLLM

首页编辑器站点地图

Copyright © 2025 聚合阅读

License: CC BY-SA 4.0