跳转到内容

l-js-fnv3.1.0

常用的 js 函数

安装

bash
npm install l-js-fn

引入

支持import,require导入,同时也支持方法按需引入

js
// 全量引入
// const L = require("l-js-fn");
import * as L from "l-js-fn";

// 按需引入
// const {arrayFill} = require("l-js-fn");
import { arrayFill, ... } from "l-js-fn";

CDN引入

浏览器原生 ES Module 模式下(即 <script type="module">)无法识别 npm 包名式导入路径。这时候如果需要在原生html使用 npm包则需要 cdn

text
https://esm.run/l-js-fn

类型补充

一、实现 vue2 挂载原型链声明,创建types/global.d.ts

ts
import Vue from 'vue';
import * as L from 'l-js-fn';

declare module 'vue/types/vue' {
	interface Vue {
		$L: typeof L;
	}
}

declare module 'l-js-fn';
js
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"],
      "@pages/*": ["pages/*"]
    }
  },
  "checkJs": true,
  "allowJs": true,
  "types": ["node", "l-js-fn"],
  "exclude": [
    "node_modules",
    "dist",
    "uni_modules"
  ]
}

模块使用

Constant 常量

支持一些正则匹配,状态码常量,时间格式化常量

  • REGEXP 正则
    • 手机号(大陆)
    • 座机号码
    • 邮箱
    • 密码(长度 8-16,包含大小写字母、数字、特殊字符,不允许空格)
    • URL(支持协议、用户名密码、域名/IP、端口、路径,不支持 IPv6)
    • 身份证(15 位或 18 位,18 位最后一位可能为 X/x)
    • 只允许中文
    • 只允许英文
    • 只允许数字
    • 英文 + 数字(常用账号规则)
    • 英文 + 数字 + 下划线
    • 不包含特殊字符(仅中英文、数字)
  • HTTP_STATUS 状态码
    • 200 操作成功
    • 401 未授权
    • 403 无权限
    • 404 未找到
    • 500 服务器错误
    • 503 服务器不可用
  • DATE_FORMAT 时间格式 跳转查看
js
import { HTTP_STATUS } from 'l-js-fn';
// =====HTTP_STATUS 状态码常量=====
const status = 200;

if (status === HTTP_STATUS.OK) {
	// 200
	console.log('200 操作成功');
} else if (status === HTTP_STATUS.UNAUTHORIZED) {
	// 401
	console.log('401 未授权');
} else if (status === HTTP_STATUS.FORBIDDEN) {
	// 403
	console.log('403 无权限');
} else if (status === HTTP_STATUS.NOT_FOUND) {
	// 404
	console.log('404 未找到');
} else if (status === HTTP_STATUS.SERVER_ERROR) {
	// 500
	console.log('500 服务器错误');
} else if (status === HTTP_STATUS.SERVER_UNAVAILABLE) {
	// 503
	console.log('503 服务器不可用');
}
js
import { REGEXP } from 'l-js-fn';
// =====REGEXP 正则常量=====
// 1. 手机号
if (!REGEXP.PHONE.test('12345678901')) {
	console.log('手机号格式不正确');
}
if (REGEXP.PHONE.test('15770822110')) {
	console.log('手机号格式正确');
}

// 2. 座机号码
if (!REGEXP.LAND_LINE.test('0123456789')) {
	console.log('座机格式不正确');
}
if (REGEXP.LAND_LINE.test('010-12345678')) {
	console.log('座机格式正确');
}

// 3. 邮箱
if (!REGEXP.EMAIL.test('user@@example..com')) {
	console.log('邮箱格式不正确');
}
if (REGEXP.EMAIL.test('user@example.com')) {
	console.log('邮箱格式正确');
}

// 4. 密码
if (!REGEXP.PASSWORD.test('abc12345')) {
	console.log('密码格式不正确');
}
if (REGEXP.PASSWORD.test('Abc123!@#')) {
	console.log('密码格式正确');
}

// 5. URL
if (!REGEXP.URL.test('htp://example')) {
	console.log('URL格式不正确');
}
if (REGEXP.URL.test('https://www.example.com')) {
	console.log('URL格式正确');
}

// 6. 身份证
if (!REGEXP.ID_CARD.test('1234567890')) {
	console.log('身份证格式不正确');
}
if (REGEXP.ID_CARD.test('11010519491231002X')) {
	console.log('身份证格式正确');
}
if (REGEXP.ID_CARD.test('123456789012345')) {
	console.log('身份证15位格式正确');
}

// 7. 只允许中文
if (!REGEXP.CHINESE.test('Hello')) {
	console.log('中文格式不正确');
}
if (REGEXP.CHINESE.test('你好')) {
	console.log('中文格式正确');
}

// 8. 只允许英文
if (!REGEXP.ENGLISH.test('你好')) {
	console.log('英文格式不正确');
}
if (REGEXP.ENGLISH.test('Hello')) {
	console.log('英文格式正确');
}

// 9. 只允许数字
if (!REGEXP.NUMBER.test('123abc')) {
	console.log('数字格式不正确');
}
if (REGEXP.NUMBER.test('123456')) {
	console.log('数字格式正确');
}

// 10. 英文+数字
if (!REGEXP.EN_OR_NUM.test('abc123!')) {
	console.log('英文+数字格式不正确');
}
if (REGEXP.EN_OR_NUM.test('abc123')) {
	console.log('英文+数字格式正确');
}

// 11. 英文+数字+下划线
if (!REGEXP.EN_NUM_UNDER_LINE.test('abc-123')) {
	console.log('英文+数字+下划线格式不正确');
}
if (REGEXP.EN_NUM_UNDER_LINE.test('abc_123')) {
	console.log('英文+数字+下划线格式正确');
}

// 12. 不包含特殊字符(仅中英文、数字)
if (!REGEXP.NO_SPECIAL.test('abc123!@#')) {
	console.log('不包含特殊字符格式不正确');
}
if (REGEXP.NO_SPECIAL.test('abc123中文')) {
	console.log('不包含特殊字符格式正确');
}

is 校验

提供常用校验方法

  • isEmpty 是否为空
  • isNotEmpty 否不为空
  • isArray 是否为数组
  • isString 是否为字符串
  • isEmail 是否为合法邮箱
  • isURL 是否为合法地址
  • isIdCard 是否为合法中国大陆身份证
  • isEqual 是否相等
  • isImage 是否为图片
js
import * as L from 'l-js-fn';

console.log('============ isKit ============');
console.log('-- isEmpty 是否空 --');
console.log(L.isEmpty(null)); // true
console.log(L.isEmpty('233')); // false

console.log('-- isNotEmpty 是否不为空 --');
console.log(L.isNotEmpty(undefined)); // false
console.log(L.isNotEmpty('2333')); // true

console.log('-- isArray 是否数组 --');
console.log(L.isArray([1, 2, 3, 4])); // true
console.log(L.isArray('123')); // false

console.log('-- isString 是否字符串 --');
console.log(L.isString([1, 2, 3, 4])); // false
console.log(L.isString('123')); // true

console.log('-- isEmail 是否合法邮箱 --');
console.log(L.isEmail('youyanping@example.com')); // true
console.log(L.isEmail('123')); // false

console.log('-- isURL 是否合法地址 --');
console.log(L.isURL('https://www.baidu.com')); // true
console.log(L.isURL('123')); // false

console.log('-- isIdCard 是否合法中国大陆身份证 --');
console.log(L.isIdCard('')); // true
console.log(L.isIdCard('123')); // false

console.log('-- isEqual 是否相等 --');
console.log(L.isEqual('12', '12')); // true
console.log(L.isEqual({ age: 20, name: 'zs' }, { age: 21, name: 'zs' })); // false

console.log('-- isImage 是否为图片 --');
console.log(L.isImage('')); // false
console.log(L.isImage('test.png')); // true

array 数组

  • arrayFill 数组填充
  • arrayUnique 去重
  • arrayPaginate 分页
  • arrayDelEl 删除
js
import * as L from 'l-js-fn';

console.log('============ arrKit ============');
console.log('-- arrayFill 数组填充 --');
const arrayFill = L.arrayFill([1, 2, 3], 10, null);
console.log(JSON.stringify(arrayFill)); // [1,2,3,null,null,null,null,null,null,null]

console.log('-- arrayUnique 去重 --');
const arrayUnique = L.arrayUnique([1, 2, 3, 4, 5, 5, 5, 55, 5, 5]);
console.log(arrayUnique); //[ 1, 2, 3, 4, 5, 55 ]

console.log('-- arrayPaginate 分页 --');
const paginate = L.arrayPaginate(arrayFill, 1, 3);
console.log(paginate); // [ 1, 2, 3 ]

console.log('-- arrayDelEl 删除 --');
const delElement = L.arrayDelEl([1, 2, 3, 4, 5, 6], 2);
console.log(delElement); // [ 1, 3, 4, 5, 6 ]
const arr = [
	{
		id: 1,
		name: 'zs',
	},
	{
		id: 2,
		name: 'xs',
	},
	{
		id: 3,
		name: 'ls',
	},
];
// 按照相同的属性进行删除
const delElement1 = L.arrayDelEl(arr, { id: 1, name: 'zs' });
console.log(delElement1); // [ { id: 2, name: 'xs' }, { id: 3, name: 'ls' } ]
// 按指定key的值进行匹配删除
const delElement2 = L.arrayDelEl(arr, { name: 'ls' }, 'name');
console.log(delElement2); // [ { id: 1, name: 'zs' }, { id: 2, name: 'xs' } ]

url 地址

  • getUrlParams 获取所有地址参数
  • getUrlParam 获取指定地址参数
  • appendUrlParam 地址添加参数
  • transUrlParams 对象转换参数
  • getFileInfoToUrl url 获取文件信息
js
import * as L from 'l-js-fn';

console.log('============ urlKit ============');
console.log('-- getUrlParams 获取所有地址参数 --');
const url_01 = 'https://www.baidu.com?name=zs&age=20&hobbies[]=reading&hobbies[]=sports';
const params = L.getUrlParams(url_01);
console.log(params); // { name: 'zs', age: '20', hobbies: [ 'reading', 'sports' ] }

console.log('-- getUrlParam 获取指定地址参数 --');
const name = L.getUrlParam(url_01, 'name');
console.log(name); // zs

console.log('-- appendUrlParam 地址添加参数 --');
const appendUrl = L.appendUrlParam(url_01, 'test', 'value');
console.log(appendUrl); // https://www.baidu.com?name=zs&age=20&hobbies[]=reading&hobbies[]=sports&test=value

console.log('-- transUrlParams 对象转换参数 --');
const transParams = {
	name: 'zs',
	age: 20,
	sex: 0,
};
const transUrl = L.transUrlParams(transParams);
console.log(transUrl); //name=zs&age=20&sex=0

const fileInfo = L.getFileInfoToUrl('https://www.baidu.com/img/bd_logo1.png');
/*
{
 fileName: 'bd_logo1.png',
 extension: '.png',
}
*/

obj 对象

  • objMerge 对象合并
  • objFilterProp 属性过滤
  • objFilterNull 过滤空值
js
import * as L from 'l-js-fn';

console.log('============ object ============');
console.log('-- objMerge 对象合并 --');
const target = {
	a: 1,
	b: 2,
	c: 3,
};
const source = {
	c: 4,
	d: 5,
	e: null,
};
const obj = L.objMerge(target, source);
const obj02 = L.objMerge(target, source, 'soft');
console.log(obj); // { a: 1, b: 2, c: 4, d: 5 }
console.log(obj02); //{ a: 1, b: 2, c: 4 }

console.log('-- objFilterProp 属性过滤 --');
console.log(L.objFilterProp(obj, ['a'])); //{ b: 2, c: 4, d: 5 }

console.log('-- objFilterNull 过滤空值 --');
console.log(L.objFilterNull(source)); // { c: 4, d: 5 }

number 数值

  • formatNumber 数字格式化
  • numberToPercent 数字转百分比
  • random 随机整数(支持负数)
js
import * as L from 'l-js-fn';
L.numberToPercent(0.123456); // "12.35%"
L.numberToPercent(0.5, 0); // "50%"

L.formatNumber(1234567); // "1,234,567"
formatNumber('1234567'); // "1,234,567"
formatNumber(1234567, true); // "123万"

L.random(10); // 0~10

string 字符串

  • desensitization 字符串脱敏
  • trim 字符串去空格
  • getMobile 获取随机手机号
  • getUuid 获取随机 uuid
js
import * as L from 'l-js-fn';

console.log('============ String ============');
console.log('-- desensitization 脱敏 --');
console.log(L.desensitization('123456789', 2, 4)); // 12****789

console.log('-- trim 去空格 --');
console.log(L.trim(' 123 ')); // 123
console.log(L.trim('12 345', 'all')); // 12345
console.log(L.trim(' 123124', 'left')); // 123124

console.log('-- getMobile 随机获取手机号 --');
console.log(L.getMobile()); // 13095692650

console.log('-- getUuid 随机uuid --');
console.log(L.getUuid()); //89ff8a90-98b6-469a-b511-8bc10db746da

date 日期

  • dateFormat 时间格式化
  • dateSecond 秒数转为时分秒
  • formatPassTime 时间差
  • diffDays 天数差
js
import { dateFormat, diffDays, formatPassTime, dateSecond, DATE_FORMAT } from 'l-js-fn';

// =====时间格式化及常量=====
const date_format_full = dateFormat(new Date(), DATE_FORMAT.FULL); // 2025-10-01 15:11:06
const date_format_date = dateFormat(new Date(), DATE_FORMAT.DATE); // 2025-10-01
const date_format_short = dateFormat(new Date(), DATE_FORMAT.SHORT); // 10-01
const date_format_time = dateFormat(new Date(), DATE_FORMAT.TIME); // 15:12:42
const date_format_year_month = dateFormat(new Date(), DATE_FORMAT.YEAR_MONTH); // 2025-10

// 秒数转为时分秒HH:mm:ss
const date_second = dateSecond(17520); // 04:52:00 转为4小时52分00秒

diffDays('2020-01-01 23:59', '2020-01-02 00:01'); // 1
diffDays(new Date(), Date.now());

formatPassTime(new Date()); // "刚刚"
formatPassTime(1577836800000); // "1年前"

Result 结果

提供结果类,用于返回结果.

js
import { Result } from 'l-js-fn';
// 用于请求捕获错误并返回结果,外部调用无需使用try catch
export const fetchData = async () => {
	try {
		const res = await axios.get('/api/data');
		if (res.status === 200) {
			return Result.success(res.data);
		} else {
			return Result.fail(res.data.message || '操作失败');
		}
	} catch (error) {
		return Result.fail(error.message || '操作失败');
	}
};

Polling 轮询

用于接口轮询,可用于多实例轮询

js
import { Polling } from 'l-js-fn';

const polling = new Polling();
const polling_2 = new Polling();

polling.start(() => {
	console.log('这是实例1');
});

setTimeout(() => {
	polling.stop();
}, 5000);

polling_2.start(() => {
	console.log('这是实例2');
});

setTimeout(() => {
	polling_2.stop();
}, 3000);

/*
这是实例1
这是实例2
这是实例1
这是实例2
这是实例1
这是实例2
Polling has been stopped.
这是实例1
这是实例1
Polling has been stopped.
*/

Websocket 即时消息

js
import { WebSocketManager } from 'l-js-fn';

let host = 'wss://echo.websocket.events/';
let socket = null;

const init = () => {
	socket = new WebSocketManager(host, handleMessage, handleError);
	socket.checkConnection({
		test: 0,
	});
};

const handleMessage = (msg) => {
	console.log(msg);
};

const handleError = (error) => {
	console.log(error, 'error');
	socket.close();
};

const close = () => {
	socket.close();
};

init();

IPC 双向通讯

实现h5与iframe的双向通讯

主应用

html
<!doctype html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0" />
		<meta http-equiv="X-UA-Compatible" content="ie=edge" />
		<title>H5</title>
		<style>
			body {
				margin: 0;
				padding: 0;
				padding: 0 20px 20px;
				height: calc(100vh - 20px);
				display: flex;
				flex-direction: column;
			}
			button {
				border: unset;
				padding: 10px 15px;
				border-radius: 5px;
				background-color: #538aff;
				color: #fff;
				cursor: pointer;
			}
			#iframeId {
				width: 100%;
				border: 1px solid #f1f1f1;
				height: 100%;
				background: rgba(0, 0, 0, 0.1);
				border-radius: 10px;
			}
		</style>
	</head>
	<body>
		<h1>主应用</h1>
		<div style="margin-bottom: 20px">
			<button onclick="openDialog()">打开子应用对话框</button>
			<div id="userId"></div>
		</div>
		<iframe id="iframeId" src="./iframe.html"></iframe>
		<script type="module" src="./h5.js"></script>
	</body>
</html>
js
import { H5Bridge } from 'l-js-fn';
const userId = document.getElementById('userId');
const iframe = document.getElementById('iframeId');
const h5Bridge = new H5Bridge(iframe);
window.openDialog = () => {
	// 调用子应用方法
	h5Bridge.call('openDialog', 'hello world').then((res) => {
		userId.innerHTML = '打开弹窗成功' + res.data;
	});
};

// 监听子应用发布的事件
h5Bridge.off('getUserInfo');
h5Bridge.on('getUserInfo', (data) => {
	// 查询用户信息
	console.log(data, 'userId');
	userId.innerHTML = '用户ID: ' + data;
	h5Bridge.emit('getUserInfo', { id: 5, name: '张三', age: 23, sex: '男' });
});

// 页面卸载时清理
window.addEventListener('beforeunload', () => {
	h5Bridge.destroy();
});

子应用

html
<!doctype html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0" />
		<meta http-equiv="X-UA-Compatible" content="ie=edge" />
		<title>iframe</title>
		<style>
			body {
				margin: 0;
				padding: 0 20px 0;
				height: 100%;
			}

			button {
				border: unset;
				padding: 10px 15px;
				border-radius: 5px;
				background-color: #eda921;
				color: #fff;
				cursor: pointer;
			}
		</style>
	</head>

	<body>
		<h2>子应用</h2>
		<div style="margin-bottom: 20px">
			<button onclick="getUserInfo()">获取主应用用户信息</button>
			<span id="userInfo"></span>
		</div>
		<script type="module" src="./iframe.js"></script>
	</body>
</html>
js
import { IframeBridge } from 'l-js-fn';

const userInfoEl = document.getElementById('userInfo');
const iframeBridge = new IframeBridge();
// 注册事件提供调用
iframeBridge.register('openDialog', (data) => {
	alert('iframe: 打开弹窗' + data);
	return {
		code: 200,
		data: '这是弹窗返回的数据',
	};
});

window.getUserInfo = () => {
	// 传递事件以及参数给主应用
	iframeBridge.emit('getUserInfo', 5);
	// 确保未注册
	iframeBridge.off('getUserInfo');
	// 监听主应用传递的数据
	iframeBridge.on('getUserInfo', (data) => {
		console.log(data, '获取到用户信息');
		userInfoEl.innerHTML = '用户信息:' + JSON.stringify(data);
	});
};

// 页面卸载时清理
window.addEventListener('beforeunload', () => {
	h5Bridge.destroy();
});

通用函数

  • sleep 睡眠
  • deepClone 深拷贝
  • getType 获取数据类型
  • throttle 节流
  • debounce 防抖
  • syntaxHighlight 高亮对象,数组数据
  • loadResource 加载外部资源
  • getDevice 获取设备信息
js
import * as L from 'l-js-fn';

console.log('============ Common ============');
console.log('-- sleep 睡眠 --');
await L.sleep(1000);

console.log('-- deepClone --');
const obj1 = { a: 1, b: 2 };
const obj2 = L.deepClone(obj1);
console.log(obj1 === obj2);

console.log('-- getType --');
console.log(L.getType(1)); //number
console.log(L.getType('1')); //string
console.log(L.getType(true)); //boolean
console.log(L.getType(() => {})); // function
console.log(L.getType({ name: 'zs' })); // object

console.log('-- throttle --');
L.throttle(() => {
	console.log('233');
});

console.log('-- debounce --');
L.debounce(() => {
	console.log('233');
});

console.log('-- syntaxHighlight --');
L.syntaxHighlight({ name: 'zs', age: 18 }); // 高亮对象,数组数据

console.log('-- loadResource --');
L.loadResource('https://cdn.jsdelivr.net/npm/lodash/lodash.min.js', 'js')
	.then(() => {
		console.log('lodash loaded:', typeof _ !== 'undefined');
	})
	.catch((err) => console.error(err));

// "miniProgram" | "alipayMiniProgram" | "alipay" | "wechat" | "android" | "ios" | "harmony" | "windows" | "macos" | "linux" | "unknown"
const device = L.getDevice(); // 获取设备信息

Will Try My Best.