本人在制作金额输入框时,由于数字数字框的右侧按钮难处理,所以使用文本输入框接收金额数字,这个函数是用来格式化与校验金额输入.
代码还不够优雅,望指点
/**
* 将字符串格式为一个合规的字符串数字
* @param {string} value 字符串大概率是数字字符串
* @param {boolean} negative 是否允许负数
* @return {string} "999999999.99"
*/
export function strFormatStrNum(value, negative = false) {
// 初始检测最容易出错的值
if (negative) {
// 初始输入有可能输入0-或者符号需要初始化
if (value === '0-' || value === '-') {
// 归零 注意js中有负数零存在
return '-0'
}
}
// -9代表数字上限为亿位数,-8代表数字上限为千万位数,-2代表数字上限为十位数,想要加大上限就加深负数
const accuracy_upper_limit = -9
// 2代表数字只保留小数点后两位
const accuracy_lower_limit = 2
// 需要返回的是负数
const if_negative = negative && value.charAt(0) === '-'
// 声明切割值保存的数组
let parts = []
/*
* 将value切割成指定格式的字符串数组
* 有可能输入的值不是字符串形式所以需要toString
* e也会被判断为数字所以需要删除e
* 0b判断为二进制数字删除b
* 0o判断为八进制数字删除o
* 0x判断为十六进制数字删除x
* 默认清除负数所以也要删除-
* split('.')切割为数组
*/
parts = value
.toString()
.replace(/e/g, '')
.replace(/b/g, '')
.replace(/o/g, '')
.replace(/x/g, '')
.replace(/-/g, '')
.split('.')
// 内部函数定义数值初始化
function strInit() {
if (if_negative) {
// -0 === 0 返回 true
return '-0'
} else {
return '0'
}
}
// 进行上限切割后数字化转化
const int = Number(parts[0].slice(accuracy_upper_limit))
// 获取整形部分
function getStrInt() {
// 需要返回负数的话,需要加回负号
return if_negative ? '-' + String(int) : String(int)
}
// 是否有小数,小数数组长度为2,如果不需要小数那就只对整数判断
if (parts.length === 1 || accuracy_lower_limit === 0) {
// 整数情况
// 数字化的结果有可能是非数值
if (Number.isNaN(int)) {
// 初始化
return strInit()
} else {
// 数字化后不是NaN转回字符串
return getStrInt()
}
} else {
// 有小数情况
// 切割出指定位数小数
const decimal = parts[1].slice(0, accuracy_lower_limit)
// 小数单独进行数字化
// const double = Number(decimal)
const regex = /^\d+$/
// 判断是否有一边数字为NaN
// !Number.isNaN(int) && !Number.isNaN(double)
if (!Number.isNaN(int) && regex.test(decimal)) {
// 两边的数字都不为NaN
// 右边不使用double是要考虑到.01的这种情况,.01会转为1
// 2024-06-13修改,由于之前没有考虑到小数后输入字母现在加上正则,regex只允许0-9
return getStrInt() + '.' + decimal
} else if (!Number.isNaN(int)) {
// 只有整数部分是正常的话,不加.会导致用户无法输入小数
// 2024-06-13修改,之前的三元表达式由于字符串连接 (+) 运算符的优先级高于比较运算符导致没有正确执行,现在加上括号提权
return getStrInt() + (accuracy_lower_limit > 0 ? '.0' : '')
} else {
// 初始化
return strInit()
}
}
}
2024-06-13修复小数部分格式化与代码
旧代码
} else {
// 有小数情况
// 切割出指定位数小数
const decimal = parts[1].slice(0, accuracy_lower_limit)
// 小数单独进行数字化
const double = Number(decimal)
// 判断是否有一边数字为NaN
if (!Number.isNaN(int) && !Number.isNaN(double)) {
// 两边的数字都不为NaN
// 右边不使用double是要考虑到.01的这种情况,.01会转为1
return getStrInt() + '.' + decimal
} else if (!Number.isNaN(int)) {
// 只有整数部分是正常的话,不加.会导致用户无法输入小数
return getStrInt() + accuracy_lower_limit > 0 ? '.0' : ''
} else {
// 初始化
return strInit()
}
}
新代码
} else {
// 有小数情况
// 切割出指定位数小数
const decimal = parts[1].slice(0, accuracy_lower_limit)
// 小数单独进行数字化
// const double = Number(decimal)
const regex = /^\d+$/
// 判断是否有一边数字为NaN
// !Number.isNaN(int) && !Number.isNaN(double)
if (!Number.isNaN(int) && regex.test(decimal)) {
// 两边的数字都不为NaN
// 右边不使用double是要考虑到.01的这种情况,.01会转为1
// 2024-06-13修改,由于之前没有考虑到小数后输入字母现在加上正则,regex只允许0-9
return getStrInt() + '.' + decimal
} else if (!Number.isNaN(int)) {
// 只有整数部分是正常的话,不加.会导致用户无法输入小数
// 2024-06-13修改,之前的三元表达式由于字符串连接 (+) 运算符的优先级高于比较运算符导致没有正确执行,现在加上括号提权
return getStrInt() + (accuracy_lower_limit > 0 ? '.0' : '')
} else {
// 初始化
return strInit()
}
}
标签:isNaN,return,const,Number,js,int,字符串,格式化,小数
From: https://www.cnblogs.com/xd422/p/18245329