每天上一当,当当不一样。前端菜鸡的踩坑日记!
tofixed()是采用的一种四舍六入五成双的‘银行家算法’,并不是我们以为的那种四舍五入
银行家算法:
对于位数很多的近似数,当有效位数确定后,其后面多余的数字应该舍去,只保留有效数字最末一位,这种修约(舍入)规则是“四舍六入五成双”,也即“4舍6入5凑偶”这里“四”是指≤4 时舍去,"六"是指≥6时进上,"五"指的是根据5后面的数字来定,当5后有数时,舍5入1;当5后无有效数字时,需要分两种情况来讲:①5前为奇数,舍5入1;②5前为偶数,舍5不进。(0是偶数)
但实际在浏览器中发现又不是这个样子,秘制玄学
(谷歌浏览器) (搜狐浏览器)
已经在js中踩过很多坑,所以前端最好不做任何运算,因为计算机浮点数的问题,逢运算必有坑!!!!,都给后端算最省事,但这样无疑就会增加服务器压力,所以不涉及关键环节的运算和处理前端还是可以做的。
所以要不就是在项目开始初期就引入第三方运算库,所有的加减乘除都使用第三方解决,这样最稳妥,简单暴力见效快!!
如果已经使用了,那就好好看接下来的分享吧
Vue项目
先创建一个js文件,用来存放写好的方法进行导出
export default {
install() {
Number.prototype.toFixed = function (n) {
if (n > 20 || n < 0) {
throw new RangeError('toFixed() digits argument must be between 0 and 20');
}
const number = this;
if (isNaN(number) || number >= Math.pow(10, 21)) {
return number.toString();
}
if (typeof (n) == 'undefined' || n == 0) {
return (Math.round(number)).toString();
}
let result = number.toString();
const arr = result.split('.');
// 整数的情况
if (arr.length < 2) {
result += '.';
for (let i = 0; i < n; i += 1) {
result += '0';
}
return result;
}
const integer = arr[0];
const decimal = arr[1];
if (decimal.length == n) {
return result;
}
if (decimal.length < n) {
for (let i = 0; i < n - decimal.length; i += 1) {
result += '0';
}
return result;
}
result = integer + '.' + decimal.substr(0, n);
const last = decimal.substr(n, 1);
// 四舍五入,转换为整数再处理,避免浮点数精度的损失 正数+1 负数-1
if (parseInt(last, 10) >= 5) {
const x = Math.pow(10, n);
result = (Math.round((parseFloat(result) * x)) + (parseFloat(result) > 0 ? 1 : -1)) / x;
result = result.toFixed(n);
}
return result;
};
}
}
然后在入口的js文件,也就是main.js中进行引入
import tofixed from './utils/tofixed';
Vue.use(tofixed);
然后你就会发现呕吼,问题解决了!
Layui项目
在layui这里真是卡了好久,为什么呢,因为layui没有main.js ! ! ! 所以不能像vue一样来一套丝滑的小连招。
然后我就开始尝试在app.js里挂载,不出意外的果然不行。
然后又尝试在index.html中引入的方式,发现这种方式只有在刚进入项目的页面中能够生效,在各个功能页面中,tofixed方法又变回了原来的。
好吧,到这里游戏就卡关了,可恶,难道只能一个个页面去单独引入吗?
虽然只有八十个文件,并不是很多,但咱们本着能省就省的办法,肯定不会这样干啊。
然后就开始各种查找方法,都知道当你越想找东西的时候越是找不到,找了好久没找到任何有效的办法。
但是遇到问题不要慌,来跟棒棒糖接着想,这时一个大神给了我思路,我们的目的是什么?
当然是在一个地方写了这个方法之后所有的页面都能用啊,那什么样的页面能实现这个效果呢。于是我就开始尝试在index这个文件中直接加入这个方法,果果果然然然,又失败了,碰一鼻子灰的我又去找大神,大神说要不试试在每个页面都会引的js文件里写,项目里每个页面都会用到的只有jQ和layui这两个js文件,死马当活马医,怼,然后我就在layui的源文件里加入了重写之后的Number.prototype.toFixed代码,当我用颤抖的手打开网页调试的时候,呕吼!生效了!直接获取这个方法得到的也是重写之后的新代码。OK问题完美解决,效果完美实现!
学艺不精,总是踩坑。看似平静的js,实则波涛汹涌,处处是雷。真好,又是知识满满的一天!