神奇魔法类:使用 createMagicClass 增强你的 JavaScript/Typescript 类

什么是神奇魔法类?

神奇魔法类(Magic Class)是一种特殊的类包装器,它通过createMagicClass函数创建,能够赋予普通 JavaScript/TypeScript 类超能力。这个工具让你的类既可以作为构造函数使用,又可以作为函数调用来配置选项,大大增强了类的灵活性和可用性。

神奇特性

1. 双重身份

魔法类具有双重身份,可以:

  • 作为普通类使用用于继承:class MyClass extends MagicClass
  • 作为函数调用来传入选项用于构建类:class MyClass extends MagicClass({<options>})

2. 生命周期钩子

提供完整的生命周期钩子,让你能够精确控制实例的创建过程:

  • onBeforeInstance: 实例创建前触发,可以阻止实例创建或修改类
  • onAfterInstance: 实例创建后触发,可以对实例进行后处理
  • onErrorInstance: 实例创建出错时触发,可以进行错误处理

使用示例

基本用法

typescript 复制代码
import { createMagicClass } from "flex-tools/classs";
type UserCreateOptions = {
  prefix?: string;
  x?: number;
};
// 定义一个普通类
class User {
  name: string;
  prefix: string = "";
  constructor(name: string) {
    this.name = name;
    this.prefix = getMagicClassOptions<UserCreateOptions>(this)?.prefix!;
  }
  get title() {
    return `${this.prefix}${this.name}`;
  }
  toString() {
    return `${this.constructor.name}<${this.name}>`;
  }
}

// 创建魔术类
const MagicUser = createMagicClass<typeof User, UserCreateOptions>(User, {
  prefix: "Hi,", // 默认配置
  x: 1,
  onBeforeInstance: (cls, args, _options) => {},
  onAfterInstance: (inst, _options) => {},
});
//  直接作为类使用
class Admin extends MagicUser {}
class Guest extends MagicUser({ x: 2, prefix: "欢迎," }) {}
class Customer extends MagicUser({ prefix: "尊贵的" }) {}

const user = new User("用户");
const admin = new Admin("管理员");
const guest = new Guest("访客");
const customer = new Customer("客户");

高级用法:拦截实例创建

typescript 复制代码
const ValidatedPerson = createMagicClass(Person, {
  onBeforeInstance: (cls, args, options) => {
    const name = args[0];

    // 验证名称
    if (!name || name.length < 2) {
      throw new Error("Name must be at least 2 characters long");
    }

    // 可以修改参数
    args[0] = name.charAt(0).toUpperCase() + name.slice(1);

    // 返回false会阻止实例创建
    // 返回一个对象会使用该对象作为实例
    // 返回一个类会使用该类创建实例
  },
  onErrorInstance: (error, cls, options) => {
    console.error("Failed to create person:", error.message);
  },
});

class SitePerson extends ValidatedPerson {}

// 这将抛出错误,因为名称太短
try {
  const invalid = new SitePerson("A");
} catch (e) {
  console.log(e.message); // "Name must be at least 2 characters long"
}

// 这将成功,并且名称首字母会被自动大写
const valid = new SitePerson("bob"); // 实际名称将是 "Bob"

获取实例配置

你可以使用getMagicClassOptions函数获取实例的配置选项:

typescript 复制代码
import { createMagicClass, getMagicClassOptions } from "flex-tools/classs";

const MagicPerson = createMagicClass(Person, { version: "1.0" });
const ConfiguredPerson = MagicPerson({ theme: "dark" });
const person = new ConfiguredPerson("Alice");

const options = getMagicClassOptions(person);
console.log(options); // { version: '1.0', theme: 'dark' }

总结

神奇魔法类通过createMagicClass函数提供了一种优雅而强大的方式来增强 JavaScript/TypeScript 类的能力。它不仅保留了原始类的所有功能,还添加了配置选项、生命周期钩子和灵活的实例化方式,使你的代码更加灵活、可配置且易于维护。

无论你是构建复杂的 UI 组件、可配置的工具类,还是需要精细控制实例创建过程的系统,神奇魔法类都能为你提供强大而灵活的解决方案。

详见flex-tools

相关推荐
Mintopia9 分钟前
Next.js 全栈开发基础:在 pages/api/*.ts 中创建接口的艺术
前端·javascript·next.js
小妖66612 分钟前
react-router 怎么设置 basepath 设置网站基础路径
前端·react.js·前端框架
xvmingjiang18 分钟前
Element Plus 中 el-input 限制为数值输入的方法
前端·javascript·vue.js
XboxYan35 分钟前
借助CSS实现自适应屏幕边缘的tooltip
前端·css
极客小俊36 分钟前
iconfont 阿里巴巴免费矢量图标库超级好用!
前端
小杨 想拼43 分钟前
使用js完成抽奖项目 效果和内容自定义,可以模仿游戏抽奖页面
前端·游戏
yvvvy1 小时前
🐙 Git 从入门到面试能吹的那些事
前端·trae
狂炫一碗大米饭1 小时前
事件委托的深层逻辑:当冒泡不够时⁉️
javascript·面试
张柏慈1 小时前
JavaScript性能优化30招
开发语言·javascript·性能优化
EmmaGuo20151 小时前
flutter3.7.12版本设置TextField的contextMenuBuilder的文字颜色
前端·flutter