本地开发,热更新经常出现内存溢出问题,导致项目挂了
修改内容后保存热更新,由于内容涉及很多,导致内存溢出,尤其在低配置笔记本电脑上,严重影响开发效率
-
解决方法:使用 increase-memory-limit
// 全局安装
npm install -g increase-memory-limit
// 如果没有安装 cross-env, 需要安装 cross-env
npm install --save cross-env
// 修改 package.json 如下:[ LIMIT大小自己设置 ] ...
"scripts": {
"fix-memory-limit": "cross-env LIMIT=2048 increase-memory-limit"
},
//(只需执行一次即可)
npm run fix-memory-limit
ios input唤起键盘上🔑密码如何取消。
-
bug重现
-
原因分析:ios系统检测到当前
input输入框的下一个相邻输入框为password密码类型时,输入了唤起的键盘就如上图所示。 -
解决方法:在
password输入框的上方添加一个text输入框,并从视觉上隐藏掉即可。
<input type='text' placeholder=‘唤起的键盘中间是空的,可以正常显示短信验证码’ />
<input type='text' placeholder='视觉隐藏的输入框,实际点击唤起的键盘会带有🔑密码' />
<input type='password' />
Safari不支持零宽断言报错白屏
-
bug 重现
正则匹配时,使用了 零宽断言。导致页面直接空白,控制台报错。
-
解决方案
Safari 和 IOS 均不支持零宽断言的正则。常用 零宽断言:?=、?!、?<=、?<!
谷歌翻译导致文案异常
-
bug 重现
-
解决方案
1、关闭 Google 翻译软件
2、避免用户下次还会自动翻译 出错,代码先加上 translate="no" 属性,禁止用户自动去翻译我们页面。
stackoverflow.com/questions/1…
<html translate="no">
异步新窗口打开被浏览器拦截
-
bug重现
浏览器环境:火狐、搜狗、QQ浏览器等。
原因分析:浏览器之所以拦截新开窗口是因为该操作并不是用户主动触发的,所以它认为这是不安全的就拦截了(不过如果是 _self 的话就不会有这个限制),即使 ajax 回调函数中模拟执行 click 或者 submit 等用户行为(trigger('click')),浏览器也会认为不是由用户主动触发的,因此不能被安全执行,所以被拦截。
-
解决方案
1、异步请求之前先打开一个空白窗口,然后在返回成功后给空白窗口一个指定url
let win = window.open('about: blank');
request().then(res => {
if (res.status === 1) {
const URL = '要跳转得链接';
win.location.href = URL;
} else {
win.close();
}
})
2、换浏览器,使用兼容模式或者谷歌
js 数字精度问题
-
原因分析
number类型相当于其他强类型语言中的double类型(双精度浮点型),不区分浮点型和整数型。由于Js的所有数字类型都是双精度浮点型(64位)采用 IEEE754 标准:也就是是用64位二进制数表示一个number数字,其中 64位 = 1位符号位 + 11位指数位 + 52位小数位;
符号位:用来表示数字的正负,-1^符号位数值,0为正数,1为负数
指数位:一般都用科学计数法表示数值大小,但是这里一般都是2进制的科学计数法,表示2的多少次方
小数位:科学计数法前面的数值,IEEE745标准,默认所有的该数值都转为1.xxxxx这种格式,优点是可以省略一位小数位,可以存储更多的数字内容,缺点是丢失精度
浮点数的运算精度丢失问题就是因为,浮点数转化为该标准的二进制的过程中出现的丢失
- 整数转二进制除二取余法,7表示为 111 = 7%2 , 3%2 + 1
- 小数转二进制!!由于也需要转化为指数形式,例如 1/2 = 1 * 2^-1, 1/4 = 1 * 2^-2,所以小数的转化二进制过程是通过判断小数是不是满 1/2,1/4,1/8以此类推,换成数学公式就是 乘二取整法
0.1的二进制
0.1*2=0.2======取出整数部分0
0.2*2=0.4======取出整数部分0
0.4*2=0.8======取出整数部分0
0.8*2=1.6======取出整数部分1
0.6*2=1.2======取出整数部分1
0.2*2=0.4======取出整数部分0
0.4*2=0.8======取出整数部分0
0.8*2=1.6======取出整数部分1
0.6*2=1.2======取出整数部分1
接下来会无限循环
0.2*2=0.4======取出整数部分0
0.4*2=0.8======取出整数部分0
0.8*2=1.6======取出整数部分1
0.6*2=1.2======取出整数部分1
所以0.1转化成二进制是:0.0001 1001 1001 1001…(无限循环)
0.1 => 0.0001 1001 1001 1001…(无限循环)
同理0.2的二进制是0.0011 0011 0011 0011…(无限循环)
计算机中的数字都是以二进制存储的,二进制浮点数表示法并不能精确的表示类似0.1这样 的简单的数字
如果要计算 0.1 + 0.2 的结果,计算机会先把 0.1 和 0.2 分别转化成二进制,然后相加,最后再把相加得到的结果转为十进制
但有一些浮点数在转化为二进制时,会出现无限循环 。比如, 十进制的 0.1 转化为二进制,会得到如下结果:0.1 => 0.0001 1001 1001 1001…(无限循环)
0.2 => 0.0011 0011 0011 0011…(无限循环)
而存储结构中的尾数部分最多只能表示 53 位。为了能表示 0.1,只能模仿十进制进行四舍五入了,但二进制只有 0 和 1 , 于是变为 0 舍 1 入 。 因此,0.1 在计算机里的二进制表示形式如下:
0.1 => 0.0001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 101
0.2 => 0.0011 0011 0011 0011 0011 0011 0011 0011 0011 0011 0011 0011 0011 001
在计算浮点数相加时,需要先进行 “对位”,将较小的指数化为较大的指数,并将小数部分相应右移:
最终,“0.1 + 0.2” 在计算机里的计算过程如下:
经过上面的计算过程,0.1 + 0.2 得到的结果也可以表示为:
(−1)0 × 2−2 × (1.0011001100110011001100110011001100110011001100110100)2=>.0.30000000000000004
通过 JS 将这个二进制结果转化为十进制表示:
(-1)0 * 2-2 * (0b10011001100110011001100110011001100110011001100110100 * 2**-52);//0.30000000000000004
console.log(0.1 + 0.2) ; // 0.30000000000000004
这是一个典型的精度丢失案例,从上面的计算过程可以看出,0.1 和 0.2 在转换为二进制时就发生了一次精度丢失,而对于计算后的二进制又有一次精度丢失 。因此,得到的结果是不准确的。
-
解决方案
1、因为小数精度过高的情况下可能出现无限循环,出现截断或者进位等情况,限制精度,只保留小数部分位数,减小精度出现的误差问题:Number.toFixed();
2、转换为整数再进行计算
//除法函数,用来得到精确的除法结果
//说明:javascript的除法结果会有误差,在两个浮点数相除的时候会比较明显。这个函数返回较为精确的除法结果。
//调用:accDiv(arg1,arg2)
//返回值:arg1除以arg2的精确结果
export function accDiv(arg1, arg2) {
var t1 = 0, t2 = 0, r1, r2;
try { t1 = arg1.toString().split(".")[1].length } catch (e) { }
try { t2 = arg2.toString().split(".")[1].length } catch (e) { }
if (Math) {
r1 = Number(arg1.toString().replace(".", ""))
r2 = Number(arg2.toString().replace(".", ""))
return (r1 / r2) * Math.pow(10, t2 - t1);
}
}
//乘法函数,用来得到精确的乘法结果
//说明:javascript的乘法结果会有误差,在两个浮点数相乘的时候会比较明显。这个函数返回较为精确的乘法结果。
//调用:accMul(arg1,arg2)
//返回值:arg1乘以arg2的精确结果
export function accMul(arg1, arg2) {
if (typeof (arg1) !== 'undefined' && typeof (arg2) !== 'undefined') {
var m = 0, s1 = arg1.toString(), s2 = arg2.toString();
try { m += s1.split(".")[1].length } catch (e) { }
try { m += s2.split(".")[1].length } catch (e) { }
return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m)
}
}
//加法函数,用来得到精确的加法结果
//说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的加法结果。
//调用:accAdd(arg1,arg2)
//返回值:arg1加上arg2的精确结果
export function accAdd(arg1, arg2) {
var r1, r2, m;
try { r1 = arg1.toString().split(".")[1].length } catch (e) { r1 = 0 }
try { r2 = arg2.toString().split(".")[1].length } catch (e) { r2 = 0 }
// 当 4个两位小数的的值相加时,仍然又精度问题,处理方式:讲数值先乘以 m,再除以m
m = Math.pow(10, Math.max(r1, r2) + 2)
console.log('selectedRowKeys changed: ', m)
return (arg1 * m + arg2 * m) / m
}
//减法函数,用来得到精确的减法结果
//说明:javascript的减法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的减法结果。
//调用:accSubtr(arg1,arg2)
//返回值:arg1减去arg2的精确结果
export function accSubtr(arg1, arg2) {
var r1, r2, m, n;
try { r1 = arg1.toString().split(".")[1].length } catch (e) { r1 = 0 }
try { r2 = arg2.toString().split(".")[1].length } catch (e) { r2 = 0 }
m = Math.pow(10, Math.max(r1, r2));
//动态控制精度长度
n = (r1 >= r2) ? r1 : r2;
return ((arg1 * m - arg2 * m) / m).toFixed(n);
}
3、引入第三方封装类库:math库,bignumber, big, decimal等