工具函数
数字操作
1、数字千分位分隔
js
function separator(n){
let num = n.toString();
let len = num.length;
if (len <= 3) {
return num;
} else {
let temp = '';
let remainder = len % 3;
if (remainder > 0) { // 不是3的整数倍
return num.slice(0, remainder) + ',' + num.slice(remainder, len).match(/\d{3}/g).join(',') + temp;
} else { // 3的整数倍
return num.slice(0, len).match(/\d{3}/g).join(',') + temp;
}
}
}
数组操作
1、数组乱序
js
function arrScrambling(arr) {
for (let i = 0; i < arr.length; i++) {
const randomIndex = Math.round(Math.random() * (arr.length - 1 - i)) + i;
[arr[i], arr[randomIndex]] = [arr[randomIndex], arr[i]];
}
return arr;
}
2、数组扁平化
js
function flatten (arr) {
let result = [];
for(let i = 0; i < arr.length; i++) {
const data = arr[i];
if(Array.isArray(data)) {
result = result.concat(flatten(data));
} else if (Object.prototype.toString.call(data) === '[object Object]') {
for (const key in data) {
if (Object.hasOwnProperty.call(arr[i], key)) {
if (Array.isArray(data[key])) {
data[key] = result.concat(flatten(data[key]));
}
}
}
result.push(arr[i]);
} else {
result.push(arr[i]);
}
}
return result;
}
3、数组中获取随机数
js
function sample (arr) {
return arr[Math.floor(Math.random() * arr.length)];
}
4、字符串操作
js
function randomString (len) {
let chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz123456789';
let strLen = chars.length;
let randomStr = '';
for (let i = 0; i < len; i++) {
randomStr += chars.charAt(Math.floor(Math.random() * strLen));
}
return randomStr;
};
5、字符串首字母大写
js
function fistLetterUpper (str) {
return str.charAt(0).toUpperCase() + str.slice(1);
};
6、手机号中间四位变成*
js
function telFormat(tel) {
tel = String(tel);
return tel.substr(0,3) + "****" + tel.substr(7);
};
7、驼峰命名转换成短横线命名
js
function getKebabCase(str) {
return str.replace(/[A-Z]/g, (item) => '-' + item.toLowerCase())
}
8、短横线命名转换成驼峰命名
js
function getCamelCase(str) {
return str.replace( /-([a-z])/g, (i, item) => item.toUpperCase())
}
格式转化
1、数字转化为大写金额
js
function digitUppercase(n) {
const fraction = ['角', '分'];
const digit = [
'零', '壹', '贰', '叁', '肆',
'伍', '陆', '柒', '捌', '玖'
];
const unit = [
['元', '万', '亿'],
['', '拾', '佰', '仟']
];
n = Math.abs(n);
let s = '';
for (let i = 0; i < fraction.length; i++) {
s += (digit[Math.floor(n * 10 * Math.pow(10, i)) % 10] + fraction[i]).replace(/零./, '');
}
s = s || '整';
n = Math.floor(n);
for (let i = 0; i < unit[0].length && n > 0; i++) {
let p = '';
for (let j = 0; j < unit[1].length && n > 0; j++) {
p = digit[n % 10] + unit[1][j] + p;
n = Math.floor(n / 10);
}
s = p.replace(/(零.)*零$/, '').replace(/^$/, '零') + unit[0][i] + s;
}
return s.replace(/(零.)*零元/, '元')
.replace(/(零.)+/g, '零')
.replace(/^整$/, '零元整');
};
2、数字转化为中文数字
js
function intToChinese(value) {
const str = String(value);
const len = str.length-1;
const idxs = ['','十','百','千','万','十','百','千','亿','十','百','千','万','十','百','千','亿'];
const num = ['零','一','二','三','四','五','六','七','八','九'];
return str.replace(/([1-9]|0+)/g, ( $, $1, idx, full) => {
let pos = 0;
if($1[0] !== '0'){
pos = len-idx;
if(idx == 0 && $1[0] == 1 && idxs[len-idx] == '十'){
return idxs[len-idx];
}
return num[$1[0]] + idxs[len-idx];
} else {
let left = len - idx;
let right = len - idx + $1.length;
if(Math.floor(right / 4) - Math.floor(left / 4) > 0){
pos = left - left % 4;
}
if( pos ){
return idxs[pos] + num[$1[0]];
} else if( idx + $1.length >= len ){
return '';
}else {
return num[$1[0]]
}
}
});
}
操作存储
1、存储loalStorage
js
function setStorage(key, value) {
if (!key) return;
if (typeof value !== 'string') {
value = JSON.stringify(value);
}
window.localStorage.setItem(key, value);
};
2、获取loalStorage
js
function getStorage(key) {
if (!key) return '';
const value = window.localStorage.getItem(key);
return value ? JSON.parse(value) : value;
};
3、删除localStorage
js
function removeStorage(key) {
if (!key) return;
window.localStorage.removeItem(key);
};
4、存储sessionStorage
js
function setSession(key, value) {
if (!key) return;
if (typeof value !== 'string') {
value = JSON.stringify(value);
}
window.sessionStorage.setItem(key, value)
};
5、获取sessionStorage
js
function getSession(key) {
if (!key) return;
const value = window.sessionStorage.getItem(key);
return value ? JSON.parse(value) : value;
};
6、删除sessionStorage
js
function removeSession(key) {
if (!key) return;
window.sessionStorage.removeItem(key)
};
操作cookie
1、设置cookie
js
function setCookie(key, value, expire) {
const d = new Date();
d.setDate(d.getDate() + expire);
document.cookie = `${key}=${value};expires=${d.toUTCString()}`;
};
2、读取cookie
js
function getCookie(key){
const cookieStr = unescape(document.cookie);
const arr = cookieStr.split('; ');
let cookieValue = '';
for (let i = 0; i < arr.length; i++) {
const temp = arr[i].split('=');
if (temp[0] === key) {
cookieValue = temp[1];
break
}
}
return cookieValue
};
3、删除cookie
js
function delCookie(key) {
document.cookie = `${encodeURIComponent(key)}=;expires=${new Date()}`
};
格式校验
1、校验身份证号码
js
function checkCardNo(value) {
let reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/;
return reg.test(value);
};
2、校验是否包含中文
js
function haveCNChars(value) {
return /[\u4e00-\u9fa5]/.test(value);
}
3、校验是否为中国大陆的邮政编码
js
function isPostCode(value) {
return /^[1-9][0-9]{5}$/.test(value.toString());
}
4、校验是否为IPv6地址
js
function isIPv6(str) {
return Boolean(str.match(/:/g)?str.match(/:/g).length<=7:false && /::/.test(str)?/^([\da-f]{1,4}(:|::)){1,6}[\da-f]{1,4}$/i.test(str):/^([\da-f]{1,4}:){7}[\da-f]{1,4}$/i.test(str));
}
5、校验是否为邮箱地址
js
function isEmail(value) {
return /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/.test(value);
}
6、校验是否为中国大陆手机号
js
function isTel(value) {
return /^1[3,4,5,6,7,8,9][0-9]{9}$/.test(value.toString());
}
7、校验是否包含emoji表情
js
function isEmojiCharacter(value) {
value = String(value);
for (let i = 0; i < value.length; i++) {
const hs = value.charCodeAt(i);
if (0xd800 <= hs && hs <= 0xdbff) {
if (value.length > 1) {
const ls = value.charCodeAt(i + 1);
const uc = ((hs - 0xd800) * 0x400) + (ls - 0xdc00) + 0x10000;
if (0x1d000 <= uc && uc <= 0x1f77f) {
return true;
}
}
} else if (value.length > 1) {
const ls = value.charCodeAt(i + 1);
if (ls == 0x20e3) {
return true;
}
} else {
if (0x2100 <= hs && hs <= 0x27ff) {
return true;
} else if (0x2B05 <= hs && hs <= 0x2b07) {
return true;
} else if (0x2934 <= hs && hs <= 0x2935) {
return true;
} else if (0x3297 <= hs && hs <= 0x3299) {
return true;
} else if (hs == 0xa9 || hs == 0xae || hs == 0x303d || hs == 0x3030
|| hs == 0x2b55 || hs == 0x2b1c || hs == 0x2b1b
|| hs == 0x2b50) {
return true;
}
}
}
return false;
}
操作URL
1、获取URL参数列表
js
function getQueryVariable(url, attribute) {
if (!url) return '';
const paramsStr = /.+\?(.+)$/.exec(url)[1]; // 将 ? 后面的字符串取出来
const paramsArr = paramsStr.split('&'); // 将字符串以 & 分割后存到数组中
let paramsObj = {};
for (let i = 0; i < paramsArr.length; i++) {
const param = paramsArr[i];
if (/=/.test(param)) { // 处理有 value 的参数
let [key, val] = param.split('='); // 分割 key 和 value
val = decodeURIComponent(val); // 解码
val = /^\d+$/.test(val) ? parseFloat(val) : val; // 判断是否转为数字
if (key === attribute) return val;
if (paramsObj.hasOwnProperty(key)) { // 如果对象有 key,则添加一个值
paramsObj[key] = [].concat(paramsObj[key], val);
} else { // 如果对象没有这个 key,创建 key 并设置值
paramsObj[key] = val;
}
} else { // 处理没有 value 的参数
paramsObj[param] = true;
}
}
if(attribute) return '';
return paramsObj;
};
2、检测URL是否有效
js
function getUrlState(URL) {
let xmlhttp = new ActiveXObject("microsoft.xmlhttp");
xmlhttp.Open("GET", URL, false);
try {
xmlhttp.Send();
} catch (e) {
} finally {
let result = xmlhttp.responseText;
if (result) {
if (xmlhttp.Status == 200) {
return true;
} else {
return false;
}
} else {
return false;
}
}
}
3、键值对拼接成URL参数
js
function params2Url(obj) {
let params = []
for (let key in obj) {
params.push(`${key}=${obj[key]}`);
}
return encodeURIComponent(params.join('&'))
}
4、修改URL中的参数
js
function replaceParamVal(paramName, replaceWith) {
const oUrl = location.href.toString();
const re = eval('/('+ paramName+'=)([^&]*)/gi');
location.href = oUrl.replace(re,paramName+'='+replaceWith);
return location.href;
}
5、删除URL中指定参数
js
function funcUrlDel(name) {
const baseUrl = location.origin + location.pathname + "?";
const query = location.search.substr(1);
if (query.indexOf(name) > -1) {
const obj = {};
const arr = query.split("&");
for (let i = 0; i < arr.length; i++) {
arr[i] = arr[i].split("=");
obj[arr[i][0]] = arr[i][1];
}
delete obj[name];
return baseUrl + JSON.stringify(obj).replace(/[\"\{\}]/g, "").replace(/\:/g, "=").replace(/\,/g, "&");
}
}
设备判断
1、判断是移动还是PC设备
js
function isMobile() {
if ((navigator.userAgent.match(/(iPhone|iPod|Android|ios|iOS|iPad|Backerry|WebOS|Symbian|Windows Phone|Phone)/i))) {
return 'mobile';
}
return 'desktop';
}
2、判断是否是苹果还是安卓移动设备
js
function isAppleMobileDevice() {
let reg = /iphone|ipod|ipad|Macintosh/i;
return reg.test(navigator.userAgent.toLowerCase());
}
3、判断是否是安卓移动设备
js
function isAndroidMobileDevice() {
return /android/i.test(navigator.userAgent.toLowerCase());
}
4、判断是Windows还是Mac系统
js
function osType() {
const agent = navigator.userAgent.toLowerCase();
const isMac = /macintosh|mac os x/i.test(navigator.userAgent);
const isWindows = agent.indexOf("win64") >= 0 || agent.indexOf("wow64") >= 0 || agent.indexOf("win32") >= 0 || agent.indexOf("wow32") >= 0;
if (isWindows) {
return "windows";
}
if(isMac){
return "mac";
}
}
5、判断是否是微信/QQ内置浏览器
js
function broswer() {
const ua = navigator.userAgent.toLowerCase();
if (ua.match(/MicroMessenger/i) == "micromessenger") {
return "weixin";
} else if (ua.match(/QQ/i) == "qq") {
return "QQ";
}
return false;
}
6、浏览器型号和版本
js
function getExplorerInfo() {
let t = navigator.userAgent.toLowerCase();
return 0 <= t.indexOf("msie") ? { //ie < 11
type: "IE",
version: Number(t.match(/msie ([\d]+)/)[1])
} : !!t.match(/trident\/.+?rv:(([\d.]+))/) ? { // ie 11
type: "IE",
version: 11
} : 0 <= t.indexOf("edge") ? {
type: "Edge",
version: Number(t.match(/edge\/([\d]+)/)[1])
} : 0 <= t.indexOf("firefox") ? {
type: "Firefox",
version: Number(t.match(/firefox\/([\d]+)/)[1])
} : 0 <= t.indexOf("chrome") ? {
type: "Chrome",
version: Number(t.match(/chrome\/([\d]+)/)[1])
} : 0 <= t.indexOf("opera") ? {
type: "Opera",
version: Number(t.match(/opera.([\d]+)/)[1])
} : 0 <= t.indexOf("Safari") ? {
type: "Safari",
version: Number(t.match(/version\/([\d]+)/)[1])
} : {
type: t,
version: -1
}
}
浏览器操作
1、滚动到页面顶部
js
function scrollToTop() {
const height = document.documentElement.scrollTop || document.body.scrollTop;
if (height > 0) {
window.requestAnimationFrame(scrollToTop);
window.scrollTo(0, height - height / 8);
}
}
2、滚动到页面底部
js
function scrollToBottom() {
window.scrollTo(0, document.documentElement.clientHeight);
}
3、滚动到指定元素区域
js
function smoothScroll(element) {
document.querySelector(element).scrollIntoView({
behavior: 'smooth'
});
};
4、获取可视窗口高度
js
function getClientHeight() {
let clientHeight = 0;
if (document.body.clientHeight && document.documentElement.clientHeight) {
clientHeight = (document.body.clientHeight < document.documentElement.clientHeight) ? document.body.clientHeight : document.documentElement.clientHeight;
}
else {
clientHeight = (document.body.clientHeight > document.documentElement.clientHeight) ? document.body.clientHeight : document.documentElement.clientHeight;
}
return clientHeight;
}
5、获取可视窗口宽度
js
function getPageViewWidth() {
return (document.compatMode == "BackCompat" ? document.body : document.documentElement).clientWidth;
}
6、打开浏览器全屏
js
function toFullScreen() {
let element = document.body;
if (element.requestFullscreen) {
element.requestFullscreen()
} else if (element.mozRequestFullScreen) {
element.mozRequestFullScreen()
} else if (element.msRequestFullscreen) {
element.msRequestFullscreen()
} else if (element.webkitRequestFullscreen) {
element.webkitRequestFullScreen()
}
}
7、退出浏览器全屏
js
function exitFullscreen() {
if (document.exitFullscreen) {
document.exitFullscreen()
} else if (document.msExitFullscreen) {
document.msExitFullscreen()
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen()
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen()
}
}
8、浏览器是否全屏
js
function isFullscreen() {
return document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement || false;
}
时间操作
1、当前时间
js
function format(n) {
return n < 10 ? '0' + n : n;
}
function nowTime() {
const now = new Date();
const year = now.getFullYear();
const month = format(now.getMonth()+1);
const date = format(now.getDate());
const hour = format(now.getHours());
const miu = format(now.getMinutes());
const sec = format(now.getSeconds());
return +year + "年" + (month + 1) + "月" + date + "日 " + hour + ":" + miu + ":" + sec;
}
2、格式化时间
js
function format(n) {
return n < 10 ? '0' + n : n;
}
function dateFormater(time, formater) {
let date = time ? new Date(time) : new Date(),
Y = date.getFullYear() + '',
M = format(date.getMonth()+1),
D = format(date.getDate()),
H = format(date.getHours()),
m = format(date.getMinutes()),
s = format(date.getSeconds());
return formater.replace(/YYYY|yyyy/g, Y)
.replace(/YY|yy/g, Y.substr(2, 2))
.replace(/MM/g,(M<10 ? '0' : '') + M)
.replace(/DD/g,(D<10 ? '0' : '') + D)
.replace(/HH|hh/g,(H<10 ? '0' : '') + H)
.replace(/mm/g,(m<10 ? '0' : '') + m)
.replace(/ss/g,(s<10 ? '0' : '') + s)
}
// dateFormater('YYYY-MM-DD HH:mm:ss')
// dateFormater('YYYYMMDDHHmmss')
JavaScript操作
1、阻止冒泡事件
js
function stopPropagation(e) {
e = e || window.event;
if(e.stopPropagation) { // W3C阻止冒泡方法
e.stopPropagation();
} else {
e.cancelBubble = true; // IE阻止冒泡方法
}
}
2、防抖函数
防抖通过设置setTimeout定时器的方式延迟执行,当快速多次点击的时候,每一次都会重置定时器,只有你一段时间都不点击时定时器才能到达条件并执行事件函数。即如果触发事件后在 n 秒内又触发了事件,则会重新计算函数延执行时间。
js
//防抖函数
function debounce(fn,delay){
//设置time为定时器
var time = null;
//闭包原理,返回一个函数
return function (e){
//如果定时器存在则清空定时器
if(time){
clearTimeout(time);
}
//设置定时器,规定时间后执行真实要执行的函数
time = setTimeout(() => {//此箭头函数里的this指向btn这个按钮
fn.call(this,arguments);//改变真实要执行函数的this指向,原submit函数里面的this指向window
},delay);
}
}
3、节流函数
节流其实就很好理解了,减少一段时间的触发频率。简单来说,就是你一直狂点不停的话,它会每隔一定时间就执行一次。它与防抖最大的区别就是,无论事件触发多么频繁,都可以保证在规定时间内可以执行一次执行函数
js
function throttle(fn,interval = 0) {
var _self = fn; // 保存需要延迟执行函数的引用
var timer = null;
var firstTime = true; // 是否第一次调用
return function() {
var args = arguments;
var _me = this;
// 第一次不需要延迟
if (firstTime) {
_self.apply(_me,args)
return firstTime = false;
}
// 定时器还在,说明延迟执行还没完成
if (timer) {
return false;
}
timer = setTimeout(() => {
clearTimeout(timer)
timer = null;
_self.apply(_me,args)
}, interval);
}
}
4、数据类型判断
js
function getDataType(value) {
if (value === null) {
return value + "";
}
// 判断数据是引用类型的情况
if (typeof value === "object") {
let valueClass = Object.prototype.toString.call(value),
type = valueClass.split(" ")[1].split("");
type.pop();
return type.join("").toLowerCase();
} else {
// 判断数据是基本数据类型的情况和函数的情况
return typeof value;
}
}
5、对象深拷贝
js
function deepClone(obj, hash = new WeakMap()) {
// 日期对象直接返回一个新的日期对象
if (obj instanceof Date){
return new Date(obj);
}
//正则对象直接返回一个新的正则对象
if (obj instanceof RegExp){
return new RegExp(obj);
}
//如果循环引用,就用 weakMap 来解决
if (hash.has(obj)){
return hash.get(obj);
}
// 获取对象所有自身属性的描述
let allDesc = Object.getOwnPropertyDescriptors(obj);
// 遍历传入参数所有键的特性
let cloneObj = Object.create(Object.getPrototypeOf(obj), allDesc)
hash.set(obj, cloneObj)
for (let key of Reflect.ownKeys(obj)) {
if(typeof obj[key] === 'object' && obj[key] !== null){
cloneObj[key] = deepClone(obj[key], hash);
} else {
cloneObj[key] = obj[key];
}
}
return cloneObj
}
6、转义html标签
js
function htmlEncode(text) {
return text.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>')
}
7、跨浏览器绑定事件
js
function addEvent(element, event, fn) {
if(!element) return;
if(element.addEventListener) {
element.addEventListener(event, fn, false)
} else if(element.attachEvent) { // 兼容IE
element.attachEvent('on' + event, fn)
} else {
element['on' + event] = fn;
}
}
8、加入收藏夹
js
function addFavorite(sUrl, sTitle) {
try {
window.external.addFavorite(sUrl, sTitle)
} catch(e) {
try {
window.sidebar.addPanel(sTitle, sUrl, '')
} catch(e) {
alert('收入收藏夹失败,请使用Ctrl + D进行添加')
}
}
}
9、动态添加脚本
js
function importScript(url, loadSuccess, loadError) {
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
if (loadSuccess && typeof loadSuccess === 'function') {
script.onload = fOnload;
}
if (loadError && typeof loadError === 'function') {
script.onerror = loadError;
}
head.appendChild(script);
}
10、Base64 和 File、Blob 相互转换
Base64 转 File
js
function base64ToFile(base64, mime, filename) {
let arr = base64.split(',')
let type = mime || arr[0].match(/:(.*?);/)[1]
let suffix = mine.split('/')[1]
let fileName = filename || `未命名.${suffix}`
let bstr = atob(arr[1])
let n = bstr.length
let u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new File([u8arr], fileName, { type })
}
File 转 Base64
js
function fileToBase64(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
reader.onerror = error => reject(error);
});
}
Base64 转 Blob
js
function base64ToBlob(dataurl) {
let arr = dataurl.split(',')
let mime = arr[0].match(/:(.*?);/)[1]
let bstr = atob(arr[1])
let n = bstr.length
let u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new Blob([u8arr], { type: mime })
}
Blob 转 Base64
js
function blobToBase64(blob) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(blob);
reader.onloadend = () => {
resolve(reader.result);
};
reader.onerror = (e) => {
reject(e);
};
});
}
Blob 和 File 相互转换
js
const file = new File([/* data */], "filename.txt", { type: "text/plain" });
const blob = new Blob([file]);
const blob = new Blob([/* data */], { type: "text/plain" });
const file = new File([blob], "filename.txt", { type: blob.type, lastModified: Date.now() });
11、Base64 编码和解码
Base64 编码
js
// btoa() 相当于 window.btoa(),encodeURIComponent 同理
const str = 'test'
const encode = btoa(encodeURIComponent(str))
console.log(encode) // dGVzdA==
Base64 解码
js
// atob() 相当于 window.atob(),decodeURIComponent 同理
const str = 'dGVzdA=='
const decode = decodeURIComponent(atob(str))
console.log(decode) // test
中文乱码处理方法
js
const Base64 = {
encode(str) {
// 首先,我们使用 encodeURIComponent 来获得百分比编码的UTF-8,然后我们将百分比编码转换为原始字节,最后存储到btoa里面
return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g,
function toSolidBytes(match, p1) {
return String.fromCharCode(Number('0x' + p1));
}));
},
decode(str) {
// 过程:从字节流到百分比编码,再到原始字符串
return decodeURIComponent(atob(str).split('').map(function (c) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join(''));
}
}
let encoded = Base64.encode("一颗不甘坠落的流星"); // "5LiA6aKX5LiN55SY5Z2g6JC955qE5rWB5pif"
let decoded = Base64.decode(encoded); // "一颗不甘坠落的流星"
11、版本号对比
js
function equalVersion(curV,reqV){
var arr1=curV.split('.');
var arr2=reqV.split('.');
if(arr1.length !== arr2.length) return {
equal: 0,
pos: 0,
}
//将两个版本号拆成数字
var minL= Math.min(arr1.length,arr2.length);
var pos=0; //当前比较位
var diff=0; //当前为位比较是否相等
//逐个比较如果当前位相等则继续比较下一位
while(pos<minL){
diff=parseInt(arr1[pos])-parseInt(arr2[pos]);
if(diff!=0){
break;
}
pos++;
}
if (diff>0) {
console.log('新版本')
}else if (diff==0) {
console.log('稳定版')
}else{
console.log('旧版本')
}
return {
equal: diff==0,
pos: pos, // 差异位置决定更新方式
}
}
12、精度计算
js
class PrecisionCalculator {
constructor(num) {
this.value = num;
this.result = num;
}
// 私有方法,用于获取数字的小数位数
#getDecimalDigits(num) {
return (num.toString().split('.')[1] || "").length;
}
// 私有方法,用于根据两个数字的小数位数计算放大倍数(base)
#calculateBase(num1, num2) {
return Math.pow(10, Math.max(this.#getDecimalDigits(num1), this.#getDecimalDigits(num2)));
}
add(num) {
const base = this.#calculateBase(this.result, num);
this.result = (this.result * base + num * base) / base;
return this;
}
subtract(num) {
const base = this.#calculateBase(this.result, num);
this.result = (this.result * base - num * base) / base;
return this;
}
multiply(num) {
const base = this.#calculateBase(this.result, num);
this.result = (this.result * num * base) / base;
return this;
}
divide(num) {
if (num === 0) {
throw new Error("除数不能为0");
}
const base1 = Math.pow(10, this.#getDecimalDigits(this.result));
const base2 = Math.pow(10, this.#getDecimalDigits(num));
this.result = (this.result * base2) / (num * base1);
return this;
}
getValue() {
return this.result;
}
}
// 使用示例
const result = new PrecisionCalculator(0.1)
.add(0.2)
.subtract(0.05)
.multiply(2)
.divide(0.5)
.getValue();
console.log(result);