==运算符,在比较之前,会自动转换数据类型,结果会比较诡异,不推荐使用。
===运算符,不会自动转换数据类型,先比较数据类型,如果不一致返回 fasle ,如果一致再继续比较。
NaN这个特殊的number类型与所有其他值都不相等,包括他自己:
NaN === NaN; //false
唯一能判断NaN的方法是通过isNaN()函数:
isNaN(NaN); //true
需要注意的是浮点数的相等比较:
1/3 === (1-2/3); //false
因为浮点数在计算过程中产生误差,因此计算机无法精确表示无限循环小数。要比较浮点数的是否相等,要比较他们之差的绝对值是否小于某个阈值:
Math.abs(1/3-(1-2/3)<0.0000001; //true
由此问题我想到之前在项目中遇到的问题,由于某些小数用二进制来表示是无穷的,所以某些精度会丢失:
7*0.8=5.6000000000000005
所以在网络上寻找到一些解决方法,都使用了Math.pow()函数:
pow()方法的定义是返回x的y次幂的值,语法是:
Math.pow(x,y);
思路是判断小数部分的长度,通过pow()方法,将小数转换为整数,进行运算后再转换回小数,转载其中一位大神的代码,地址:https://blog.csdn.net/qinshenxue/article/details/43671763,代码如下:
//加法
function add(a, b) {
var c, d, e;
try {
c = a.toString().split(".")[1].length;
} catch (f) {
c = 0;
}
try {
d = b.toString().split(".")[1].length;
} catch (f) {
d = 0;
}
return e = Math.pow(10, Math.max(c, d)), (mul(a, e) + mul(b, e)) / e;
}
//减法
function sub(a, b) {
var c, d, e;
try {
c = a.toString().split(".")[1].length;
} catch (f) {
c = 0;
}
try {
d = b.toString().split(".")[1].length;
} catch (f) {
d = 0;
}
return e = Math.pow(10, Math.max(c, d)), (mul(a, e) - mul(b, e)) / e;
}
//乘法
function mul(a, b) {
var c = 0,
d = a.toString(),
e = b.toString();
try {
c += d.split(".")[1].length;
} catch (f) {}
try {
c += e.split(".")[1].length;
} catch (f) {}
return Number(d.replace(".", "")) * Number(e.replace(".", "")) / Math.pow(10, c);
}
//除法
function div(a, b) {
var c, d, e = 0,
f = 0;
try {
e = a.toString().split(".")[1].length;
} catch (g) {}
try {
f = b.toString().split(".")[1].length;
} catch (g) {}
return c = Number(a.toString().replace(".", "")), d = Number(b.toString().replace(".", "")), mul(c / d, Math.pow(10, f - e));
}
null和undefined
null表示一个"空"的值,与0还有空字符串''不同,0是一个数值,''是一个长度为0的字符串。
undefined表示值未定义,但是两者区别不大,多数情况下都应该用null,undefined仅在判断函数参数是否传递时用到。
数组
JavaScript的数组可以包括任意数据类型。
var arr = [1,2,3.14,null,"Hello",true];
对象
JavaScript的对象是一组由键-值组成的无序集合:
var person = {
name: 'Bob',
age: 20,
tags: ['js', 'web', 'mobile'],
city: 'Beijing',
hasCar: true,
zipcode: null
};
获取一个对象的属性用对象变量.属性名,例如:
person.name; // 'Bob'
person.zipcode; // null