【JavaScript】封装自己的JavaScript公共工具函数,并上传到npm中 进行下载

js公共方法封装方式都有哪些

全局函数

function greet(name) {console.log("Hello, " + name + "!");
}greet("Alice"); // 调用全局函数

对象字面量

var utils = {add: function(a, b) {return a + b;},subtract: function(a, b) {return a - b;}
};console.log(utils.add(5, 3)); // 调用对象字面量中的方法

命名空间

var myApp = {};myApp.utils = {multiply: function(a, b) {return a * b;},divide: function(a, b) {return a / b;}
};console.log(myApp.utils.multiply(4, 2)); // 调用命名空间下的方法

模块化(使用 ES6 的模块化语法)

// math.js
export function square(x) {return x * x;
}export function cube(x) {return x * x * x;
}// main.js
import { square, cube } from './math.js';console.log(square(5)); // 调用模块中的方法

上述四种有什么区别

全局函数:定义一个全局函数,可以在任何地方直接调用。这种方式最为简单,但是容易导致命名冲突,影响代码的可维护性

对象字面量:使用对象字面量(或称“JSON”)来封装公共方法,可以将多个方法组织在同一个对象中,便于管理和调用。这种方式相对于全局函数更为可维护,但是仍然存在命名冲突的问题

命名空间:使用命名空间来避免命名冲突。将所有相关的方法都放在同一个命名空间下,可以有效地减少全局变量的数量

模块化:使用模块化的方式来封装公共方法,可以将代码划分为多个模块,每个模块都有自己的作用域,可以避免命名冲突

JavaScript公共工具函数

// 命名空间封装法
var ACutils = {}
ACutils.verify = {/** 验证手机号是否合格* true--说明合格*/verifyPhoneNumber: function (phoneStr) {let myreg = /^[1][3,4,5,7,8,9][0-9]{9}$/if (!myreg.test(phoneStr)) {return false} else {return true}},/** 验证身份证号是否合格* true--说明合格*/verifyIdCard: function (idCardStr) {let idcardReg =/^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$|^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/if (idcardReg.test(idCardStr)) {return true} else {return false}},/** 验证邮箱是否合格* true--说明合格*/verifyEmail: function (isEmailStr) {let isEmailReg = /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/if (isEmailReg.test(isEmailStr)) {return true} else {return false}},/** 验证密码格式是否符合规范* 密码由大小写字母 数字组成*/verifyPassword: function (password) {const reg = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d]+$/return reg.test(password)},/** 验证用户名格式是否符合规范 规避敏感字* 可以由大小写字母 数字 汉字组成* sensitiveWords 是敏感字数组*/verifyUsername: function (username, sensitiveWords) {const reg = /^[a-zA-Z0-9\u4e00-\u9fa5]+$/if (!reg.test(username)) {return false}for (let i = 0; i < sensitiveWords.length; i++) {if (username.includes(sensitiveWords[i])) {return false}}return true},/**手机号码中间4位隐藏花号(*)显示* @param mobile 要处理的点好,字符串*/hideMiddlePhone: function (mobile) {return mobile.replace(/^(\d{3})\d{4}(\d{4})$/, '$1****$2')}
}
ACutils.number = {/** 数字四舍五入(保留n位小数)* @param number 要处理的数字* @param n 保留位数*/roundNumber: function (number, n) {n = n ? parseInt(n) : 0if (n <= 0) return Math.round(number)number = Math.round(number * Math.pow(10, n)) / Math.pow(10, n)return number}
}
ACutils.string = {/** 去除字符串空格* @param str 要处理的字符串* @param type 1:所有空格 2:前后空格 3:前空格 4:后空格*/removeStrSpaces: function (str, type) {switch (type) {case 1:return str.replace(/\s+/g, '')case 2:return str.replace(/(^\s*)|(\s*$)/g, '')case 3:return str.replace(/(^\s*)/g, '')case 4:return str.replace(/(\s*$)/g, '')default:return str}}
}
ACutils.dom = {/** 滚动到页面顶部**/scrollToTop: function () {const height = document.documentElement.scrollTop || document.body.scrollTopif (height > 0) {window.requestAnimationFrame(scrollToTop)window.scrollTo(0, height - height / 8)}}
}
ACutils.array = {/** 数组去重**/removeDuplicates: function (arr) {let uniqueArr = []for (let i = 0; i < arr.length; i++) {if (uniqueArr.indexOf(arr[i]) === -1) {uniqueArr.push(arr[i])}}return uniqueArr},/** 多维数组扁平化**/flattenArray: function (arr) {let flattened = []let _this = thisfor (let i = 0; i < arr.length; i++) {if (Array.isArray(arr[i])) {flattened = flattened.concat(_this.flattenArray(arr[i]))} else {flattened.push(arr[i])}}return flattened}
}
ACutils.obj = {/** 引用类型深拷贝* 没有返回null*/deepCopy: function (obj) {let _this = thisif (obj === null || typeof obj !== 'object') {return obj}let copy = Array.isArray(obj) ? [] : {}for (let key in obj) {if (obj.hasOwnProperty(key)) {copy[key] = _this.deepCopy(obj[key])}}return copy},/** 将数组对象中的某一项属性提取出来,以数组展示* @param data 数组对象* @param propertyName 需要提取的属性*/extractProperty: function (data, propertyName) {var propertyValues = []for (var i = 0; i < data.length; i++) {propertyValues.push(data[i][propertyName])}return propertyValues},/** 将多个一维数组合并为数组对象* @param keys 包含属性键名的数组* @param propertyName 多个一维数组* @return 返回数组对象,如果空缺地方显示undefined*/mergeArraysToObject: function (keys, ...arrays) {const length = Math.max(...arrays.map((arr) => arr.length))const result = []for (let i = 0; i < length; i++) {const obj = {}for (let j = 0; j < keys.length; j++) {obj[keys[j]] = arrays[j][i]}result.push(obj)}return result},/** 根据数组对象的 number 类型属性进行排序* @property  排序的 number 类型属性名* @sortOrder 排序顺序,可选参数,默认为 'asc'(升序),可以设置为 'desc'(降序)*/sortByNumberProperty: function (arr, property, sortOrder = 'asc') {if (sortOrder === 'asc') {arr.sort((a, b) => a[property] - b[property])} else if (sortOrder === 'desc') {arr.sort((a, b) => b[property] - a[property])}return arr},/** 根据对象的日期属性进行排序* @property  排序的 number 类型属性名* @sortOrder 排序顺序,可选参数,默认为 'asc'(升序),可以设置为 'desc'(降序)*/sortByDateProperty: function (arr, property, sortOrder = 'asc') {if (sortOrder === 'asc') {arr.sort((a, b) => new Date(a[property]) - new Date(b[property]))} else if (sortOrder === 'desc') {arr.sort((a, b) => new Date(b[property]) - new Date(a[property]))}return arr}
}
ACutils.time = {/**获取当前时间,并根据传参“yy-mm-dd HH:MM:SS” 来确定返回时间格式* @param format 返回时间格式*/getCurrentTime: function (format) {let currentDate = new Date()let year = currentDate.getFullYear()let month = (currentDate.getMonth() + 1).toString().padStart(2, '0')let day = currentDate.getDate().toString().padStart(2, '0')let hours = currentDate.getHours().toString().padStart(2, '0')let minutes = currentDate.getMinutes().toString().padStart(2, '0')let seconds = currentDate.getSeconds().toString().padStart(2, '0')let formattedTime = format.replace('yy', year).replace('mm', month).replace('dd', day).replace('HH', hours).replace('MM', minutes).replace('SS', seconds)return formattedTime},/**传入时间戳,并根据传参“yy-mm-dd HH:MM:SS 来确定返回时间格式* @param timestamp 时间戳* @param format 返回时间格式*/formatTimestamp: function (timestamp, format) {let date = new Date(timestamp)let year = date.getFullYear()let month = (date.getMonth() + 1).toString().padStart(2, '0')let day = date.getDate().toString().padStart(2, '0')let hours = date.getHours().toString().padStart(2, '0')let minutes = date.getMinutes().toString().padStart(2, '0')let seconds = date.getSeconds().toString().padStart(2, '0')let formattedTime = format.replace('yy', year).replace('mm', month).replace('dd', day).replace('HH', hours).replace('MM', minutes).replace('SS', seconds)return formattedTime},/** 传入出生年月,返回年龄、并精准到月份**/computeAge_Month: function (birthDate) {let today = new Date()let birth = new Date(birthDate)let age = today.getFullYear() - birth.getFullYear()let monthDiff = today.getMonth() - birth.getMonth()if (monthDiff < 0 ||(monthDiff === 0 && today.getDate() < birth.getDate())) {age--monthDiff = 12 - birth.getMonth() + today.getMonth()}let accurateAge = {years: age,months: monthDiff}return accurateAge},/*** 计算未来某一时间现在距的剩余时间**/formatRemainTime: function (endTime) {var startDate = new Date()var endDate = new Date(endTime)var t = endDate.getTime() - startDate.getTime()var d = 0,h = 0,m = 0,s = 0if (t >= 0) {d = Math.floor(t / 1000 / 3600 / 24)h = Math.floor((t / 1000 / 60 / 60) % 24)m = Math.floor((t / 1000 / 60) % 60)s = Math.floor((t / 1000) % 60)}return d + '天 ' + h + '小时 ' + m + '分钟 ' + s + '秒'}
}
ACutils.url = {/** 获取url参数中的参数* @param url 要处理的字符串,../index.html?projId=xx&deviceId=xxx* 没有返回null*/parseUrlParams: function (url) {let params = {}let urlParts = url.split('?')if (urlParts.length > 1) {let query = urlParts[1]let pairs = query.split('&')pairs.forEach(function (pair) {let keyValue = pair.split('=')let key = decodeURIComponent(keyValue[0])let value = decodeURIComponent(keyValue[1] || '')params[key] = value})}return params}
}
ACutils.ui = {/** 弹窗提示框  水平垂直居中提示*/showAlert: function (message, backgroundColor, textColor) {var alertBox = document.createElement('div')alertBox.textContent = messagealertBox.style.position = 'fixed'alertBox.style.top = '50%'alertBox.style.left = '50%'alertBox.style.transform = 'translate(-50%, -50%)'alertBox.style.padding = '10px 20px'alertBox.style.borderRadius = '5px'alertBox.style.opacity = 0alertBox.style.transition = 'opacity 0.3s ease-in-out'alertBox.style.backgroundColor = backgroundColoralertBox.style.color = textColordocument.body.appendChild(alertBox)setTimeout(function () {alertBox.style.opacity = 1}, 10)setTimeout(function () {alertBox.style.opacity = 0setTimeout(function () {alertBox.parentNode.removeChild(alertBox)}, 300)}, 2000)},/** 确认框  水平垂直居中提示* callback执行的函数,传递true与false*/showConfirm: function (message, backgroundColor, textColor, callback) {let confirmBox = document.createElement('div')confirmBox.className = 'confirm-box'confirmBox.style.backgroundColor = backgroundColorconfirmBox.style.color = textColorconfirmBox.style.position = 'fixed'confirmBox.style.top = '50%'confirmBox.style.left = '50%'confirmBox.style.transform = 'translate(-50%, -50%)'confirmBox.style.padding = '10px 20px'confirmBox.style.borderRadius = '5px'confirmBox.style.opacity = 0confirmBox.style.transition = 'opacity 0.3s ease-in-out'let messageElement = document.createElement('p')messageElement.textContent = messageconfirmBox.appendChild(messageElement)let confirmDiv = document.createElement('div')confirmDiv.style.display = 'flex'confirmDiv.style.justifyContent = 'space-around'let confirmButton = document.createElement('button')confirmButton.textContent = '确认'confirmButton.style.border = `1px solid ${textColor}`confirmButton.style.cursor = 'pointer'confirmButton.onclick = function () {hideConfirm(confirmBox)if (typeof callback === 'function') {callback(true)}}confirmDiv.appendChild(confirmButton)let cancelButton = document.createElement('button')cancelButton.textContent = '取消'cancelButton.style.border = `1px solid ${textColor}`cancelButton.style.cursor = 'pointer'cancelButton.onclick = function () {hideConfirm(confirmBox)if (typeof callback === 'function') {callback(false)}}confirmDiv.appendChild(cancelButton)confirmBox.appendChild(confirmDiv)document.body.appendChild(confirmBox)setTimeout(function () {confirmBox.style.opacity = 1}, 10)function hideConfirm(confirmBox) {confirmBox.style.opacity = 0setTimeout(function () {confirmBox.parentNode.removeChild(confirmBox)}, 300)}}
}

前端包常用包管理工具

npm 是 Node.js 官方提供的包管理工具,也是前端开发中最常用的包管理工具之一

cnpm 是对 npm 的一个淘宝镜像,旨在提供更快速、稳定的国内访问速度

nvm 是一个用于管理多个 Node.js 版本的工具。它允许开发人员在同一台计算机上安装和切换不同版本的 Node.js

上传到npm中

编写公共函数代码

确保公共函数已经封装好,并且在本地能够正常使用

创建 npm 账号

如果你还没有 npm 账号,需要先在 https://www.npmjs.com 上注册一个账号

初始化 npm 项目

在命令行中进入你的项目目录,运行以下命令来初始化 npm 项目:npm init

  • package name: 包名,你的包要发布的名称,通常是小写字母,不含空格。如果不想改变包名,直接按回车键即可
  • version: 初始版本号
  • description: 描述
  • entry point: 入口文件,该包的主文件名,即其他开发者通过 require 引入时加载的文件,默认为 index.js
  • test command: 测试命令,用于运行测试脚本的命令,没有回车就好
  • git repository: Git 仓库地址,没有回车就好
  • keywords: 关键词,用于描述该包的一些关键词,方便其他开发者搜索和发现你的包
  • author: 作者,你的名字或者你的公司名称
  • license: 许可证,授权许可证,标明你的包使用的开源许可证,回车就好

编写 README 文件

编写一个清晰明了的 README 文件,描述你的函数是做什么的,如何安装和使用。README 文件通常以 Markdown 格式编写

发布到 npm

npm login  // 如果之前没有登录过
npm publish

遇到的问题 

npm ERR! 403 403 Forbidden - PUT https://registry.npmmirror.com/-/user/org.couchdb.user:ac_from_hu_nan - [FORBIDDEN] Public registration is not allowedCjs>npm login

原因:是因为用的淘宝镜像,切换到官方的就行

解决:运行

npm config set registry https://registry.npmjs.org/

发布成功

下载自己的包

在目录中运行npm i xxx即可

更新自己的包 

npm login  
npm publish

每次修改后,记得更新 package.json 中的版本号,否则 npm publish 命令会失败

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/175586.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python爬虫进阶篇(异步)

学习完前面的基础知识后&#xff0c;我们会发现这些爬虫的效率实在是太低了。那么我们需要学习一些新的爬虫方式来进行信息的获取。 异步 使用python3.7后的版本中的异步进行爬取&#xff0c;多线程虽然快&#xff0c;但是异步才是爬虫真爱。 基本概念讲解 1.什么是异步&…

智能优化算法应用:基于郊狼算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于郊狼算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于郊狼算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.郊狼算法4.实验参数设定5.算法结果6.参考文献7.MATLAB…

第13周 预习、实验与作业:Java网络编程

目录 1 课前问题列表 1.编写一个网络程序&#xff0c;为了与其他网络程序通信&#xff0c;至少要知道对方的什么信息&#xff1f; 2.TCP与UDP协议有什么不同的呢&#xff1f;什么时候该选择哪种协议&#xff1f;HTTP使用的是TCP还是UDP&#xff1f;不重要的短信息传送之类的功能…

销售漏斗是什么?

销售漏斗是一个重要的销售管理工具&#xff0c;它可以帮助销售人员更好地管理和跟踪潜在客户。销售漏斗模型通常被广泛应用于B2B销售中&#xff0c;它可以将销售过程细分为多个阶段&#xff0c;例如潜在客户、初步沟通、方案报价、谈判和签约等。 销售漏斗有以下作用&#xff…

java继承和多态之接口

Java 中的继承和多态是非常重要的概念&#xff0c;它们是 Java 面向对象编程的核心特性。在 Java 中&#xff0c;继承是指一个类&#xff08;子类&#xff09;可以继承另一个类&#xff08;父类&#xff09;的属性和方法。多态是指一个接口或类的多种实现方式&#xff0c;它允许…

静态方法和属性的经典使用-单例设计模式

单例设计模式 一、设计模式二、单例模式1、饿汉式2、懒汉式3、区别 单例设计模式是静态方法和属性的经典使用。 一、设计模式 设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格、以及解决问题的思考方式。设计模式就像是经典的棋谱&#xff0c;不同的棋局&…

基于C#实现梳排序

为什么取名为梳&#xff0c;可能每个梳都有自己的 gap 吧&#xff0c;大梳子 gap 大一点&#xff0c;小梳子 gap 小一点。上一篇我们看到鸡尾酒排序是在冒泡排序上做了一些优化&#xff0c;将单向的比较变成了双向&#xff0c;同样这里的梳排序也是在冒泡排序上做了一些优化。 …

基于注解配置的AOP

注解方式AOP基本使用 Spring的AOP也提供了注解方式配置&#xff0c;使用相应的注解代替之前的xml配置。 xml配置&#xff1a; <aop:config> <!-- 配置切入点 目的是指定哪些方法增强--><aop:pointcut id"myPointCut1" expression"execu…

[Linux] 正则表达式及grep和awk

一、正则表达式 1.1 什么是正则表达式 正则表达式是一种用于匹配和操作文本的强大工具&#xff0c;它是由一系列字符和特殊字符组成的模式&#xff0c;用于描述要匹配的文本模式。 正则表达式可以在文本中查找、替换、提取和验证特定的模式。 正则表达式和通配符的区别 正则…

Docker 概述与安装

文章目录 1. Docker简介2. 传统虚拟机和容器3. Docker运行速度快的原因4. Docker软件4.1 Docker镜像4.2 Docker容器4.3 Docker仓库 5. Docker架构6. CentOS安装Docker6.1 卸载旧版本6.2 配置yum资源库6.3 安装Docker引擎6.4 启动docker引擎6.5 设置开机自启 7. 卸载Docker8. 运…

OpenCV完结篇——计算机视觉(人脸识别 || 车牌识别)

文章目录 Haar人脸识别方法Haar识别眼鼻口HaarTesseract进行车牌识别深度学习基础知识dnn实现图像分类 Haar人脸识别方法 scaleFactor调整哈尔级联器的人脸选框使其能框住人脸 官方教程指路 每个特征都是通过从黑色矩形下的像素总和减去白色矩形下的像素总和获得的单个值 级…

代理IP可以用于哪些实际场景?遇到问题如何解决

随着互联网的普及和网络应用的广泛使用&#xff0c;代理IP已成为许多人工作和生活中不可或缺的一部分。代理IP可以用于多种实际场景&#xff0c;并在遇到问题时提供有效的解决方案。下面将详细介绍代理IP的实际应用场景及遇到问题时的解决方法。 一、代理IP的实际应用场景 1. 网…

开源运维监控系统-Nightingale(-夜莺)应用实践(未完)

一、前言 某业务系统因OS改造,原先的Zabbix监控系统推倒后未重建,本来计划用外部企业内其他监控系统接入,后又通知需要自建才能对接,考虑之前zabbix的一些不便,本次计划采用一个类Prometheus的监控系统,镜调研后发现Nightingale兼容Prometheus,又有一些其他功能增强,又…

Docker Compose;docker-compose;docker compose

(一) Docker Compose | 菜鸟教程 --> --> --> -->

ESP32-Web-Server编程-建立第一个网页

ESP32-Web-Server编程-建立第一个网页 HTTP 简述 可能你每天都要刷几个短视频&#xff0c;打开几个网页来娱乐一番。当你打开一个网络上的视频或者图片时&#xff0c;其实际发生了下面的流程&#xff1a; 其中客户端就是你的浏览器啦&#xff0c;服务器就是远程一个存放视频或…

【JAVA学习笔记】72 - 满汉楼 - 餐饮管理系统

项目代码 https://github.com/yinhai1114/Java_Learning_Code/tree/main/IDEA_Chapter26 一、需求说明 满汉楼项目功能多&#xff0c;界面复杂&#xff0c;涉及到复杂的awt和swing技术和事件编程&#xff0c;做如下调整: 1.去掉界面和事件处理(工作中使用很少)&#xff0c;使…

如何在VS2022上的MFC项目中操作Excel(VS2010、VS2012、VS2015、VS2017、VS2019使用方法一样)

先决条件 本机安装office2003、2007、2010、2016及以后版本&#xff0c;总之必须安装office导入Excel库文件&#xff0c;导入方式可参考&#xff1a; 如何在vs2017及以前版本(vs2010、vs2015)上添加 添加类型库中的MFC类如何在vs2019及以后版本(如vs2022)上添加 添加ActiveX控…

flutter布局详解及代码示例(上)

布局 基本布局 Row&#xff08;水平布局&#xff09;&#xff1a;在水平&#xff08;X轴&#xff09;方向上排列子widget的列表。Column&#xff08;垂直布局&#xff09;&#xff1a;在垂直&#xff08;Y轴&#xff09;方向上排列子widget的列表。Stack&#xff08;可重叠布…

有一种浪漫,叫接触Linux

大家好&#xff0c;我是五月。 嵌入式开发 嵌入式开发产品必须依赖硬件和软件。 硬件一般使用51单片机&#xff0c;STM32、ARM&#xff0c;做成的产品以平板&#xff0c;手机&#xff0c;智能机器人&#xff0c;智能小车居多。 软件用的当然是以linux系统为蓝本&#xff0c…

顺子日期(14)

顺着日期 public class Main {public static void main(String[] args) {int res 0;//2022年int[] days new int[] {31,28,31,30,31,30,31,31,30,31,30,31};//31,28,31,30,31,30,31,31,30,31,30,31//一三五七八十腊//构造2022年每一天的日期yyyymmddStringBuffer date new…