mm_expand
mm_expand 是一个功能丰富的 JavaScript 工具库,为原生类型(String、Array、Number、Date 等)提供全面的原型函数扩展,帮助开发者简化数据操作,提高代码效率和可维护性。
项目介绍
这个库通过扩展 JavaScript 原生对象的原型链,提供了丰富的数据操作方法,使开发者能够用更简洁的代码处理常见的数据操作任务。同时,它还包含了强大的事件系统、文件操作工具和对象处理功能,适用于各种 JavaScript 应用场景。
最新功能更新(v1.9.9)
ECS架构支持
- 组件操作增强:新增
add、set、del、get方法,专门为游戏ECS(Entity Component System)架构设计 - 路径支持:支持点分隔符和数组路径访问嵌套属性
- 覆盖控制:所有方法支持
overwrite参数,控制是否修改原对象 - 默认值补全:
get方法支持对象默认值补全,确保组件属性完整性
对象操作增强
- Object.prototype扩展:为所有对象添加原型方法,包括
keys、getInfo、add、del、set、get等 - 类型安全:所有方法都包含严格的参数校验和错误处理
- 深度操作:支持深层嵌套对象的操作和遍历
代码质量提升
- ESLint合规:所有代码符合ESLint规范,确保代码质量
- 函数优化:重构长函数,降低复杂度,提高可维护性
- 测试覆盖:完整的测试套件,确保功能稳定性
特点
- 原生类型扩展:为 String、Array、Number、Date 等原生类型提供丰富的原型方法
- 对象操作增强:提供深度拷贝、对象合并、属性遍历等实用功能
- 对象验证系统:提供完整的对象属性验证功能,支持类型、必填、格式等验证规则
- 文件系统简化:直观的文件读写、复制、删除等操作方法
- 灵活事件系统:支持命名空间、优先级、中间件、节流防抖等高级特性
- 数据转换工具:JSON、XML、URL 参数等格式转换功能
- 轻量高效:核心功能轻量,性能优化良好
- 跨平台兼容:支持 Node.js 和现代浏览器环境
安装
# 使用 npm
npm install mm_expand --save
# 使用 yarn
yarn add mm_expand
# 使用 pnpm
pnpm add mm_expand快速开始
// 引入模块(CommonJS)
const $ = require('mm_expand');
// 基本用法示例
// 字符串扩展方法
const fullPath = 'test.json'.fullname(); // 获取完整路径
const isFile = 'test.json'.isFile(); // 检查是否为文件
// 数组扩展方法
const newArray = [1, 2, 3].copy(); // 复制数组
const hasValue = [1, 2, 3].has(2); // 检查数组是否包含值
// 数字扩展方法
const roundedNum = 3.14159.toRound(2); // 四舍五入到2位小数
// 日期扩展方法
const date = '2024-01-01'.toTime(); // 转换为Date对象
const formattedDate = new Date().toStr('yyyy-MM-dd hh:mm:ss'); // 格式化日期
// 对象操作
const copiedObj = $.copy({ a: 1, b: { c: 2 } }); // 深度拷贝对象
// 对象验证
const user = { name: '张三', age: 25, email: 'zhangsan@example.com' };
// 批量验证
user.check({
name: { required: true, type: 'string', min: 2, max: 20 },
age: { required: true, type: 'number', min: 18, max: 100 },
email: { required: true, type: 'email' }
});
// 链式验证
user.checkVal('name', { required: true, type: 'string', min: 2, max: 20 })
.checkVal('age', { required: true, type: 'number', min: 18, max: 100 })
.checkVal('email', { required: true, type: 'email' });
// 事件系统使用
// 注册事件
$.eventer.on('user:login', (userData) => {
console.log('User logged in:', userData);
});
// 触发事件
const result = $.eventer.emit('user:login', { id: 1, name: '张三' });
// 一次性事件
$.eventer.once('app:init', () => {
console.log('Application initialized');
});
// 并行触发事件
$.eventer.runParallel('data:process', { items: [...] });
// 暂停和恢复事件
$.eventer.pause('user:*'); // 暂停所有用户相关事件
$.eventer.resume('user:*'); // 恢复所有用户相关事件
// ECS架构组件操作示例
const entity = { position: { x: 0, y: 0 }, health: 100 };
// 添加组件属性
entity.add({ velocity: { x: 1, y: 0 } });
// 设置组件值(类型转换)
entity.set({ health: '150' }); // 自动转换为数字类型
// 删除组件属性
entity.del('velocity.x');
// 获取组件(支持默认值补全)
const position = entity.get('position', { x: 0, y: 0, z: 0 });
// 返回 { x: 0, y: 0, z: 0 },补全了缺失的z属性
// 使用路径访问嵌套属性
const x = entity.get('position.x'); // 返回 0模块导出
本库提供多种导出方式,支持按需导入和使用:
全局对象方式(推荐)
const $ = require('mm_expand');
// 使用全局对象调用所有功能
$.copy({ a: 1 }); // 对象深拷贝
$.eventer.on('event', handler); // 事件监听按需导入方式
// 导入核心类
const { Event, Eventer, Lang, Base, File, Dir } = require('mm_expand');
// 导入对象操作函数
const { as, push, clear, toJson, copy, get, set } = require('mm_expand/lib/object.js');
// 导入数组构造函数
const { Array } = require('mm_expand/lib/array.js');
// 导入其他功能模块
const { Log } = require('mm_expand/lib/log.js');
const { Timer } = require('mm_expand/lib/timer.js');主要导出模块
核心类(index.js导出)
- Event: 事件类,用于创建和管理事件实例
- Eventer: 事件驱动类,提供完整的事件系统功能
- Lang: 语言包类,支持多语言国际化
- Base: 基础类,提供类创建和继承功能
- File: 文件操作类,提供文件读写功能
- Dir: 目录操作类,提供目录管理功能
对象操作函数(object.js导出)
- as: 判断对象是否相似
- push: 合并对象属性
- clear: 清空对象值
- toJson: 对象转JSON字符串
- toXml: 对象转XML字符串
- toUrl: 对象转URL参数字符串
- saveJson: 对象保存为JSON文件
- saveXml: 对象保存为XML文件
- copy: 深度拷贝对象
- keys: 获取对象属性名
- getInfo: 获取对象详细信息
- add: 添加对象属性
- del: 删除对象属性
- set: 修改对象属性
- get: 查询对象属性
- prop: 遍历读写对象属性
- arrToObj: 数组转对象
数组构造函数(array.js导出)
- Array: 增强的数组构造函数,包含所有数组原型扩展方法
其他功能模块
- Log: 日志类,提供日志记录功能
- Timer: 定时器类,提供定时任务功能
API文档
全局工具函数
$.info(obj)
- 描述:获取函数或对象的详细信息,用于调试和开发
- 参数:
- obj: 要查看的函数或对象
- 返回值:返回对象的详细字符串表示
$.sleep(milliSeconds, obj, key)
- 描述:延迟执行(休眠)函数,返回Promise
- 参数:
- milliSeconds: 休眠的毫秒数
- obj: 判断对象或函数(可选)
- key: 判断的对象属性(可选)
- 示例:
`javascript // 简单休眠 await $.sleep(2000);
// 带条件的休眠 var obj = {ok: false}; await $.sleep(2000, obj, 'ok');
#### $.as(obj, defaultValue)
- 描述:当对象为null或undefined时返回默认值,否则返回原对象
- 参数:
- obj: 要检查的对象
- defaultValue: 当obj为null或undefined时的默认返回值
- 返回值:obj不为null/undefined时返回obj,否则返回defaultValue
#### $.speed(func, times)
- 描述:测试函数执行速度性能
- 参数:
- func: 要测试的函数
- times: 测试次数,默认1000000次
### 对象操作
#### $.push(objA, objB, bl)
- 描述:合并对象属性
- 参数:
- objA: 被添加的对象
- objB: 用作添加的对象
- bl: 是否补充没有的对象
- 返回值:合并后的新对象
#### $.clear(obj)
- 描述:清空对象值
- 参数:
- obj: 要清空的对象
- 返回值:返回清空后的对象
#### $.copy(obj, has)
- 描述:深度拷贝对象
- 参数:
- obj: 被拷贝的对象
- has: 是否只拷贝非空值
- 返回值:新的拷贝对象
#### $.keys(obj, file)
- 描述:获取对象所有属性名
- 参数:
- obj: 要查看的对象
- file: 保存结果的文件路径(可选)
### 对象验证
#### Object.prototype.check(rules)
- 描述:检查对象是否符合指定规则
- 参数:
- rules: 验证规则对象
- 返回值:验证通过返回原始对象,失败抛出TypeError
- 示例:
```javascript
const user = { name: '张三', age: 25, email: 'zhangsan@example.com' };
user.check({
name: { required: true, type: 'string', min: 2, max: 20 },
age: { required: true, type: 'number', min: 18, max: 100 },
email: { required: true, type: 'email' }
});Object.prototype.checkVal(key, rule)
- 描述:检查对象属性值是否符合指定规则
- 参数:
- key: 属性名
- rule: 验证规则
- 返回值:验证通过返回原始对象,失败抛出TypeError
- 示例:
const user = { name: '张三', age: 25, email: 'zhangsan@example.com' }; user.checkVal('name', { required: true, type: 'string', min: 2, max: 20 }) .checkVal('age', { required: true, type: 'number', min: 18, max: 100 }) .checkVal('email', { required: true, type: 'email' });
数据转换
$.toJson(obj, format)
- 描述:将对象转换为JSON字符串
- 参数:
- obj: 要转换的对象
- format: 是否格式化输出(缩进美化)
- 返回值:JSON格式字符串
$.toXml(obj, format, mode)
- 描述:将对象转换为XML字符串
- 参数:
- obj: 要转换的对象
- format: 是否格式化输出(缩进美化)
- mode: 是否使用属性格式
- 返回值:XML格式字符串
$.toUrl(obj, url)
- 描述:将对象转换为URL参数字符串
- 参数:
- obj: 要转换的对象
- url: 基础URL地址(可选)
- 返回值:URL参数格式字符串
String原型拓展
String.prototype.fullname()
- 描述:获取文件的完整路径
- 返回值:完整的文件路径字符串
String.prototype.isFile()
- 描述:检查路径是否为文件
- 返回值:是文件返回true,否则返回false
String.prototype.isDir()
- 描述:检查路径是否为目录
- 返回值:是目录返回true,否则返回false
String.prototype.saveText(data, encode)
- 描述:将字符串保存为文本文件
- 参数:
- data: 要保存的数据
- encode: 编码格式,默认'utf8'
- 返回值:保存成功返回true,失败返回false
String.prototype.loadText(encode)
- 描述:读取文件内容为字符串
- 参数:
- encode: 编码格式,默认'utf8'
- 返回值:文件内容字符串
String.prototype.saveJson(data, encode)
- 描述:将JSON对象保存为文件
- 参数:
- data: 要保存的JSON数据
- encode: 编码格式,默认'utf8'
- 返回值:保存成功返回true,失败返回false
String.prototype.loadJson(encode)
- 描述:读取JSON文件内容
- 参数:
- encode: 编码格式,默认'utf8'
- 返回值:解析后的JSON对象
String.prototype.checkFormat(type)
- 描述:检查字符串格式
- 参数:
- type: 格式类型,如'idcard'(身份证)、'phone'(手机号)等
- 返回值:格式正确返回true,否则返回false
String.prototype.toTime(format)
- 描述:将字符串转换为Date对象
- 参数:
- format: 日期格式(可选)
- 返回值:Date对象
String.prototype.toTimestamp()
- 描述:将日期字符串转换为时间戳
- 返回值:时间戳数字
Array原型拓展
Array.prototype.copy()
- 描述:复制数组
- 返回值:新的数组实例
Array.prototype.clear()
- 描述:清空数组内容
- 返回值:空数组
Array.prototype.to2D(cols)
- 描述:将一维数组转换为二维数组
- 参数:
- cols: 每行的列数
- 返回值:二维数组
Array.prototype.addVal(val)
- 描述:向数组添加值(如果不存在)
- 参数:
- val: 要添加的值
- 返回值:添加后的数组
Array.prototype.delVal(val)
- 描述:从数组中删除指定值
- 参数:
- val: 要删除的值
- 返回值:删除后的数组
Array.prototype.has(val)
- 描述:检查数组是否包含指定值
- 参数:
- val: 要检查的值
- 返回值:包含返回true,否则返回false
Number原型拓展
Number.prototype.toFloor(digits)
- 描述:向下取整
- 参数:
- digits: 小数位数(可选)
- 返回值:取整后的数字
Number.prototype.toCeil(digits)
- 描述:向上取整
- 参数:
- digits: 小数位数(可选)
- 返回值:取整后的数字
Number.prototype.toRound(digits)
- 描述:四舍五入
- 参数:
- digits: 小数位数(可选)
- 返回值:四舍五入后的数字
Number.prototype.toTime()
- 描述:将时间戳转换为Date对象
- 返回值:Date对象
Number.prototype.toTimestamp()
- 描述:将时间戳转换为时间戳(兼容性方法)
- 返回值:时间戳数字
Number.prototype.toTimeStr(format)
- 描述:将时间戳格式化为时间字符串
- 参数:
- format: 时间格式字符串,默认'yyyy-MM-dd hh:mm:ss'
- 返回值:格式化后的时间字符串
Number.prototype.random(min)
- 描述:生成随机数
- 参数:
- min: 最小值,默认1
- 返回值:随机数
Number.prototype.randomRange(margin)
- 描述:生成指定范围内的随机数
- 参数:
- margin: 上下幅度,默认5
- 返回值:范围内的随机数
Date原型拓展
Date.prototype.toStr(format)
- 描述:将Date对象格式化为字符串
- 参数:
- format: 日期格式字符串,如'yyyy-MM-dd hh:mm:ss'
- 返回值:格式化后的日期字符串
文件操作
File 类
File.prototype.getAll(dir, keyword, keyword_dir)
- 描述:递归搜索目录下所有文件
- 参数:
- dir: 目录地址
- keyword: 文件搜索关键词(可选)
- keyword_dir: 目录搜索关键词(可选)
- 返回值:文件路径数组
File.prototype.get(dir, keyword)
- 描述:获取当前目录下所有文件(不递归)
- 参数:
- dir: 目录地址
- keyword: 搜索关键词(可选)
- 返回值:文件路径数组
File.prototype.load(file, encode)
- 描述:加载文件内容
- 参数:
- file: 文件路径
- encode: 编码方式,默认'utf8'
- 返回值:文件内容字符串
File.prototype.save(file, data, encode)
- 描述:保存文件内容
- 参数:
- file: 文件路径
- data: 要保存的数据内容
- encode: 编码方式,默认'utf8'
- 返回值:保存成功返回true,否则返回false
File.prototype.copy(sourcePath, targetPath)
- 描述:复制文件
- 参数:
- sourcePath: 源文件路径
- targetPath: 目标路径
File.prototype.delete(file)
- 描述:删除文件
- 参数:
- file: 要删除的文件路径
事件系统
$.eventer
- 描述:功能强大的事件管理器实例,支持命名空间、优先级、中间件等高级特性
事件注册与移除
$.eventer.on(eventName, handler, options)
- 描述:注册事件监听器
- 参数:
- eventName: 事件名称(支持命名空间格式:namespace:event)
- handler: 事件处理函数
- options: 配置选项(可选)
- key: 事件处理器标识
- priority: 优先级(数字,默认0,值越大优先级越高)
- 返回值:当前Eventer实例(支持链式调用)
$.eventer.once(eventName, handler, options)
- 描述:注册一次性事件监听器(只触发一次后自动移除)
- 参数:同$.eventer.on
- 返回值:当前Eventer实例
$.eventer.off(eventName, key)
- 描述:移除事件监听器
- 参数:
- eventName: 事件名称
- key: 要移除的处理器标识(可选,不提供则移除指定事件的所有处理器)
- 返回值:当前Eventer实例
事件触发
$.eventer.run(eventName, ...args)
- 描述:触发事件(同步执行)
- 参数:
- eventName: 事件名称
- ...args: 传递给事件处理器的参数
- 返回值:包含执行结果和取消方法的对象 { results: [...], cancel: Function }
$.eventer.runParallel(eventName, ...args)
- 描述:并行触发事件
- 参数:同$.eventer.run
- 返回值:包含执行结果和取消方法的对象 { results: [...], cancel: Function }
$.eventer.emit(eventName, ...args)
- 描述:触发事件(别名,同run)
- 参数:同$.eventer.run
- 返回值:包含执行结果和取消方法的对象
$.eventer.emitParallel(eventName, ...args)
- 描述:并行触发事件(别名,同runParallel)
- 参数:同$.eventer.runParallel
- 返回值:包含执行结果和取消方法的对象
异步事件触发
$.eventer.emitWait(eventName, ...args)
- 描述:异步触发事件,按顺序执行等待完成
- 参数:
- eventName: 事件名称(支持命名空间格式:namespace:event)
- ...args: 传递给事件处理器的参数
- 返回值:Promise,按优先级顺序执行所有监听器
- 示例:
// 顺序执行用户登录事件的所有监听器 await $.eventer.emitWait('user:login', { id: 1, name: '张三' });
$.eventer.emitAsync(eventName, ...args)
- 描述:异步触发事件,并发执行不等待
- 参数:
- eventName: 事件名称(支持命名空间格式:namespace:event)
- ...args: 传递给事件处理器的参数
- 返回值:布尔值,表示是否有监听器被触发
- 示例:
// 异步触发数据更新事件,不等待执行结果 $.eventer.emitAsync('data:update', { timestamp: Date.now() });
$.eventer.emitAll(eventName, ...args)
- 描述:异步触发事件,并发执行等待完成
- 参数:
- eventName: 事件名称(支持命名空间格式:namespace:event)
- ...args: 传递给事件处理器的参数
- 返回值:Promise<Array>,包含所有监听器的执行结果
- 示例:
// 并发执行所有数据处理监听器,等待全部完成 const results = await $.eventer.emitAll('data:process', { items: [...] });
$.eventer.emitRace(eventName, ...args)
- 描述:异步触发事件,竞争执行(第一个完成即返回)
- 参数:
- eventName: 事件名称(支持命名空间格式:namespace:event)
- ...args: 传递给事件处理器的参数
- 返回值:Promise,第一个完成的监听器结果
- 示例:
// 竞争执行多个缓存策略,使用第一个返回的结果 const fastestResult = await $.eventer.emitRace('cache:get', { key: 'user_data' });
$.eventer.emitWaterfall(eventName, initialValue, ...args)
- 描述:异步触发事件,瀑布流执行(前一个结果传递给下一个)
- 参数:
- eventName: 事件名称(支持命名空间格式:namespace:event)
- initialValue: 初始值
- ...args: 传递给事件处理器的参数
- 返回值:Promise,最后一个监听器的执行结果
- 示例:
// 瀑布流处理数据,每个处理器接收前一个的结果 const finalResult = await $.eventer.emitWaterfall('data:pipeline', initialData, { stage: 'processing' });
事件控制
$.eventer.pause(key)
- 描述:暂停指定事件
- 参数:
- key: 事件名称(可选,不提供则暂停所有事件)
- 返回值:当前Eventer实例
$.eventer.resume(key)
- 描述:恢复指定事件
- 参数:
- key: 事件名称(可选,不提供则恢复所有事件)
- 返回值:当前Eventer实例
$.eventer.pauseAll()
- 描述:全局暂停所有事件
- 返回值:当前Eventer实例
$.eventer.resumeAll()
- 描述:全局恢复所有事件
- 返回值:当前Eventer实例
$.eventer.isPaused(key)
- 描述:检查事件是否被暂停
- 参数:
- key: 事件名称(可选,不提供则检查全局暂停状态)
- 返回值:布尔值
事件管理
$.eventer.clear(keepNamespaces)
- 描述:清空所有事件监听器
- 参数:
- keepNamespaces: 是否保留命名空间结构(布尔值,默认false)
- 返回值:当前Eventer实例
$.eventer.getMemoryReport()
- 描述:获取内存使用报告
- 返回值:包含事件统计信息的对象
$.eventer.setMaxListeners(max)
- 描述:设置最大监听器数量(防止内存泄漏警告)
- 参数:
- max: 最大监听器数量
代码执行
$.runCode(code, cm, em, qm, rm)
- 描述:执行动态代码
- 参数:
- code: 要执行的代码字符串
- cm: 上下文参数
- em: 额外参数
- qm: 查询参数
- rm: 结果参数
- 返回值:执行结果
模块加载与管理
$.load(id, module)
- 描述:加载模块
- 参数:
- id: 模块ID
- module: 模块对象
$.unload(id)
- 描述:卸载模块
- 参数:
- id: 模块ID
$.reload(id)
- 描述:重新加载模块
- 参数:
- id: 模块ID
最佳实践
- 文件路径处理:始终使用
String.prototype.fullname()获取完整路径,确保跨平台兼容性 - 错误处理:检查所有文件操作(saveText、saveJson等)的返回值,它们都返回布尔值表示成功/失败
- 异步操作:对于需要等待的操作,如sleep、事件触发等,使用await/async语法
- 对象深拷贝:使用
$.copy()进行对象深拷贝,避免引用问题 - 事件管理:
- 使用命名空间组织相关事件(如
user:login,user:logout) - 为长时间运行的事件处理添加取消机制
- 使用中间件进行事件处理前的通用逻辑
- 使用命名空间组织相关事件(如
- 内存管理:在不再需要时使用
off()方法移除事件监听器,避免内存泄漏 - 性能优化:
- 处理大量数据时,优先使用异步方法避免阻塞主线程
- 对频繁触发的事件使用节流或防抖功能
- 代码组织:按功能模块组织代码,合理使用库的不同功能模块
使用提示
- 原型扩展说明:该库通过扩展原生对象的原型链提供功能,在某些严格模式或特殊环境中可能需要特别注意
- 模块导入:在需要树摇(tree-shaking)的环境中,可以考虑导入特定的功能模块
- 版本兼容:每次更新版本前,请查看更新日志了解可能的API变化
- 浏览器环境:在浏览器环境中使用时,建议通过webpack、rollup等打包工具引入
常见问题
Q: 原型扩展会影响其他库吗? A: 我们的扩展方法都经过精心设计,避免与原生方法和常见库冲突。如果发现冲突,请及时提交Issue。
Q: 如何在浏览器中使用? A: 通过打包工具(如webpack)打包后引入,或使用CDN服务(未来将支持)。
Q: 支持TypeScript吗? A: 目前提供基本的JavaScript支持,TypeScript类型定义正在规划中。
兼容性
- Node.js 12.x及以上版本(推荐使用LTS版本)
- 支持所有现代浏览器(Chrome、Firefox、Safari、Edge等,需通过webpack、rollup等打包工具使用)
- 与CommonJS和ESM模块系统兼容
贡献指南
欢迎提交Issue和Pull Request!请确保您的代码遵循以下规范:
- 代码风格与现有项目保持一致
- 添加适当的注释和文档
- 编写测试用例确保功能正常
- 提交前运行测试确保没有引入新的问题
更新日志
详细的更新日志请查看项目的Release页面。
许可证
本项目采用 ISC License 开源许可。
联系作者
- 作者:邱文武
- Gitee: https://gitee.com/qiuwenwu91/mm_expand
- 项目Issues: https://gitee.com/qiuwenwu91/mm_expand/issues
鸣谢
感谢所有为该项目做出贡献的开发者和用户!
npm发布信息
发布状态
- 当前版本: 1.9.9
- npm包名: mm_expand
- 发布状态: 已准备发布
发布前检查清单
- ✅ 所有测试通过(87/87,100%通过率)
- ✅ 文档已更新
- ✅ 依赖项已正确配置
- ✅ 包信息完整
- ✅ 许可证文件存在
- ✅ 事件系统性能优化完成
发布命令
# 登录npm(如果尚未登录)
npm login
# 发布到npm
npm publish
# 如果发布后需要更新版本
npm version patch # 小版本更新
npm version minor # 次版本更新
npm version major # 主版本更新
npm publish # 发布新版本版本管理
- 遵循语义化版本控制(Semantic Versioning)
- 主版本号:不兼容的API修改
- 次版本号:向下兼容的功能性新增
- 修订号:向下兼容的问题修正
维护指南
- 每次修改后运行测试确保功能正常
- 更新文档反映API变化
- 提交代码前检查代码质量
- 定期更新依赖项确保安全性
支持与反馈
如果您在使用过程中遇到问题或有改进建议,欢迎通过以下方式联系我们:
- Gitee Issues: https://gitee.com/qiuwenwu91/mm_expand/issues
- Email: 项目维护者邮箱
我们致力于持续改进这个库,您的反馈对我们非常重要!