前言
列举一下在实际开发项目中,应该注意的点
问题点
精度问题
与大部分现代编程语言一样(几乎所有的脚本语言),JavaScript中的数字类型是基于IEEE754标准来实现的,该标准通常被称为浮点数,JavaScript采用的是双精度格式,即64位二进制
而二进制浮点数存在最大的问题就是数字并不是完全精确的,我们来看一个例子
var a = 0.1;
var b = 0.2;
a + b === 0.3; // false
为什么会出现这样的情况? 简单来说就是二进制浮点数中的0.1和0.2并不是十分精确,它们相加的结果并非刚好等于0.3,而是一个比较接近0.3的数字:0.30000000000000004,故判断条件为false
那么我们应该怎么来正确判断0.1 + 0.2 和0.3相等呢?
常见的解决方法是设置一个误差范围值,通常把这个误差范围叫做机器精度,对JavaScript来说,这个值通常为:2^-52(2.220446049250313e-16)
只要我们比较两个值的差值范围在该机器精度之内,就认为这两个值是相等的
ES6开始,将该机器精度定义在了Number.EPSILON中,可以直接拿来用
// 定义一个比较两个值相等的函数
function enoughToEqual(n1, n2) {
return Math.abs(n1 - n2) < Number.EPSILON;
}
var a = 0.1 + 0.2;
var b = 0.3;
enoughToEqual(a, b);// true
还有一个合理的建议是尽量不要再前端进行数值运算,以避免出现由于二进制浮点数精度出现的误差
值与引用传递
-
简单值:总是通过值复制的方式来赋值/传递,包括null,undefined,字符串,数字,布尔和ES6中的symbol
-
复合值:总是通过引用复制的方式来复制/传递,包括对象(数组和封装对象)和函数
直接看代码
var a = 2;
var b = a;
b ++;
console.log(b);// 3
console.log(a);// 2
以上是基本类型的复制过程,可以看出是对基本类型的一个复制进行赋值的,即b是a的值得一个复本,各自值变化不影响各自
再看一个复合类型值的赋值过程
var a = [1, 2, 3];
var b = a;// b是[1, 2, 3]的一个引用
b.push(4);
console.log(b);// [1, 2, 3, 4]
console.log(a);[1, 2, 3, 4]
可以看出的是,当值为复合类型的值时,赋值操作是复制的值得引用地址,而引用地址指向的是值本身而非指向的是变量
关于复合类型的值复制,我自己本人也在开发过程中遇到过一次bug,也是排查了很久,当时用了饿了么的一个日期组件,由于要给后端传递两个日期区间内的所有日期数组,故对原先的日期数组对象进行了一次处理以得到该日期区间内的每一天,在处理函数内不小心对原日期区间数组对象做了一次改变,导致日期组件渲染的时候出现了bug
建议:在实际开发过程中,用到复合类型值传递时候需要小心对待,防止出现因为修改了传入的复合值导致的bug
&& 和 ||
很多人以为&& 和 || 不就是与、或逻辑运算符嘛,实际上准确的叫法应该是选择运算符
在JavaScript中,和其他语言不同的是,它们的返回值并不是布尔值,它们的返回值是两个操作数中的一个(且仅一个),即选择两个操作数中的一个,再返回选中的数的值
不妨看以下示例代码
var a = 42;
var b = "abc";
var c = null;
a || b;// 42
a && b; // "abc"
c || b; // "abc"
c && b; // null
-
对于 || 来说,如果条件判断结果为true,就返回第一个操作数的值,如果为false就返回第二个操作数的值
-
对于&& 来说,正好相反,如果条件判断结果为true,就返回第二个操作数的值,如果为false,就返回第一个操作数的值
而具体的返回以后,进行if判断时会进行强制类型转换
总结
以上就是实际项目开发中需要注意的几点,每天进步一点点
网友评论