V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
riceball
V2EX  ›  Node.js

不用继承就能给类加事件系统?这波原型链操作我给满分

  •  
  •   riceball · 6 天前 · 1289 次点击

    long long ago,有这么一个事件库

    论如何优雅地给祖传代码拍个 eventable() 就能用

    💥 传统继承の痛,谁懂啊?

    当你想给一个 已经有 3 层继承的祖传 Class 加事件系统

    class 祖传 Class extends 爷爷 Class { /* ... */ }  
    
    // 传统方案:硬着头皮再继承一层  
    class 我的 Class extends 祖传 Class, EventEmitter { /* 多重继承?不存在的!直接报错! */ }  
    

    痛点暴击:

    • 🔨 破坏现有继承链
    • 🚫 无法注入到第三方库的 Class
    • 💣 污染原型链,所有实例都带上用不到的方法

    ✨ 事件系统的神之右手:eventable()

    现在只需一行魔法:

    import { eventable } from 'events-ex';  
    
    class 祖传 Java 风 Class extends 爷爷 Class { /* ... */ } // 保持原样
    
    // 注入事件能力,但只注入(暴露) on/emit 方法(深藏功与名)  
    eventable(祖传 Java 风 Class, {  
      include: ['on', 'emit'] // 像做外科手术一样精准  
    });  
    
    // 用法和 EventEmitter 一毛一样  
    const obj = new 祖传 Java 风 Class();  
    obj.on('data', handleData);  
    obj.emit('data', payload);  
    

    核心理念:

    • 🔌 非侵入式改造:不动原始类结构
    • 🎯 精准控制:按需暴露方法(比如屏蔽掉敏感的 off())
    • 🧩 兼容各种妖孽类:包括用 function 写的上古代码

    🤯 高级玩法:给方法加事件钩子

    更骚的是连方法都能挂事件:

    class 数据库 {  
      connect() {  
        // 原始方法保持纯洁  
        console.log('建立连接');  
      }  
    }  
    
    // 给 connect 方法加前置事件  
    eventable(数据库, {  
      methods: {  
        connect() {  
          this.emit('pre-connect'); // 触发事件  
          this.super(); // 调用原方法( this.super 是魔法关键字!)
        }  
      }  
    });  
    
    // 监听数据库连接事件  
    const db = new 数据库();  
    db.on('pre-connect', () => {  
      console.log('我要开始连接了,各组件注意!');  
    });  
    db.connect()
    

    输出结果:

    我要开始连接了,各组件注意!  
    建立连接  
    

    🛠 防翻车指南

    • 保留原始方法:通过 this.super() 调用原逻辑
    • 安全隔离:用 exclude: ['off'] 防止别人乱删监听器
    • 类型守护:配套的 TypeScript 类型扩展已就位

    灵魂发问:

    你们项目里有那种 不敢动又必须增强 的类吗?快来试试这套无痛事件注入方案!

    传送门:

    👉 GitHub 地址 | 📚 完整 API 文档

    投喂姿势:

    npm install events-ex
    

    讨论点:

    • 你们会在什么场景下用这种非继承方案?
    • 如果让你设计能力注入系统,会考虑哪些安全机制?
    14 条回复    2025-06-10 21:19:29 +08:00
    murmur
        1
    murmur  
       6 天前
    这什么推广

    个人理解,在 util 和轮子足够成熟的情况下,class 这个东西没那么信仰

    A.fuck(B)

    和 PersonUtil.fuck(A, B) 没有本质区别
    riceball
        2
    riceball  
    OP
       6 天前
    刚新增加一个功能:对事件监听器的参数增强(加了 index 参数),让 AI 给我写个关于这个功能点说明,结果,它写了这个。算了,也还不错,就放上了。

    BTW: 以后写文档真的太轻松了。
    riceball
        3
    riceball  
    OP
       6 天前
    @murmur 那要看类是你自己的,还是第三方的。
    k9982874
        4
    k9982874  
       6 天前 via Android
    看到 this 指针转头就走
    xiaoming1992
        5
    xiaoming1992  
       6 天前 via Android
    你这样子的使用方式 `eventable(数据库, {})`,真的能把 ts 类型挂到`数据库`类实例上吗?`db.on` 真的不会直接 ts 类型报错?
    jqtmviyu
        6
    jqtmviyu  
       6 天前
    非常反感用 ai 润色后的一堆 emoji 风格.

    虽然语气诙谐, 但不像人话, 缺乏重点
    riceball
        7
    riceball  
    OP
       6 天前
    @xiaoming1992 看仔细些,不是挂到实例上,而是挂到`数据库`这个类上!
    riceball
        8
    riceball  
    OP
       6 天前
    @jqtmviyu 错误,不是润色,而是全部都是 AI 根据我的 readme 自行创作。哪里缺乏重点? 我觉得它围绕它定义的标题“不用继承给类加事件系统”描述得全面,就是语言夸张,我个人不喜欢这个风格。但是这已经非常拟人话。
    kneo
        9
    kneo  
       5 天前 via Android
    @riceball 他说你这个是润色只是怕冒犯你。真实情况一看开头发现是 AI 写的侃大山不知所云,直接拉到最后看吐槽。
    lyxxxh2
        10
    lyxxxh2  
       5 天前
    我看文章就在想:
    谁继承这么多层??? 这么喜欢瞎用继承?
    从父类筛选方法来精准注入... 没那么多共用的,你用继承作甚?

    高级玩法:
    db._connect() = function() => {
    this.connect()
    this.emit
    }
    真有这种需求,还不如直接扩展直观。
    akirarika
        11
    akirarika  
       5 天前
    建议发到掘金
    soar0712
        12
    soar0712  
       5 天前
    哪儿搞这么多表情符号,跟小红书软广似的
    riceball
        13
    riceball  
    OP
       5 天前
    @kneo 为啥一个二个都这样抽象?不具体指出问题在那里,不知所云,具体哪里? 我虽然不喜欢这样的风格,但是我觉得它没有离题,都是围绕它的题目展开叙述。

    不过 AI 这样的确不行,吸引来的感觉大部分都是初学者。

    玩玩,玩玩别认真,AI 的例子,AI 的文稿。通篇 AI 大作,写得蛮好玩的,反正我自己是写不出这个调调,也许这是小红书体?
    kneo
        14
    kneo  
       5 天前   ❤️ 2
    @riceball 问题在哪里?不会吧,你用 AI 生成的垃圾,还要别人给你写读后感吗?自己看不出来吗?

    自己都不喜欢,为什么要发出来污染互联网?

    我最后再浪费一次时间,告诉你问题在哪里。

    标题加问号,多少年前的微信标题党了?
    操作满分,不觉得很土吗?
    还の痛,脑残后的遗风?
    痛点暴击,神之右手,给 AI 灌了多少垃圾 prompt 整出来的绝活?
    祖传,爷爷,觉得自己很幽默吗?

    这能叫技术文章?上来一堆垃圾文案,谁能看得进去?你的项目解决啥问题了?解决的真的是问题吗?

    我真的不感兴趣,但我还是皱着眉看了一眼。这项目是用 javascript 原型弄了个估计两百行的玩具 utility 吗?让 AI 写一个不也就一分钟的事吗?有什么理由让别人 install 你的库?

    是不是觉得 AI 时代,自己有了前所未有的机遇。

    以前自己不会写文章,现在可以用 AI 生成一篇文章,让别人来拜读了?
    以前自己不会写库,现在可以用 AI 生成一个项目,让别人来 install 了?
    以前自己不会做网站,现在可以用 AI 生成一个工具站点,让别人打开浏览器,敲着你新买的域名,来访问你的作品了?

    但你还是你啊。

    你用 AI 写的文章,只有百度的爬虫会读。
    你写的小工具库,别人用 AI 顺手就复刻了。甚至都没人会去搜这种功能。
    你做的网站无人问津。过了几年域名过期了。域名商是唯一的赢家。

    如果你觉得 AI 是你的武器,那你最好有点真材实料。否则 AI 只是你向互联网倾泻垃圾的下水道。

    我不再回复这个 AI 生成的帖子了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2753 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 20ms · UTC 00:32 · PVG 08:32 · LAX 17:32 · JFK 20:32
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.