比较关系
比较符
- ==(相等) 比较两个操作数的值是否相等。
- !=(不想等) 比较两个操作数的值是否不相等。
- ===(全等) 比较两个操作数的值是否相等,同时检测它们的类型是否相同。
- !==(不全等) 比较两个操作数的值是否不相等,同时检测它们的类型是否不相同。
宽松相对(==)和严格相等(===)
==允许在相等比较中进行强制类型转换,===却不允许。null == undefined比较相等,其中隐式强制类型转换利用 ToPrimitive(抽象操作)的所有特性。- 两边的值中有 true 或 false,最好不使用==。
- 两边的值中有[]、""或 0,尽量不要使用==。
ToPrimitive(抽象操作)
js 中,将对象转换成原始值时,会调用 toPrimitive()内部函数。
- 首先检查该值是否有 valueOf() 方法。如果有并且返回基本类型值,使用该值进行强制类型转换。
- 没有就使用 toString() 的返回值来进行强制类型转换。
- 如果 valueOf() 和 toString() 均不返回基本类型值,会产生 TypeError 错误。
const testObj = { value: 123 };
testObj.valueOf = function () {
console.log('get value');
return this.value;
};
console.log(testObj == 123); // true
const testArr = [1, 2, 3];
testArr.valueOf = null;
console.log(testObj == '1,2,3'); // true
const testData = [1, 2, 3];
testData.valueOf = function () {
return new String('1,2,3');
};
testData.toString = function () {
return new String('1,2,3');
};
console.log(testData == '1,2,3'); // TypeError
抽象比较关系
a > b,双方首先调用 ToPrimitive,如果结果出现非字符串,根据 Number 规则双方强制转换为数字类型。
// JS中 <= 是不大于的意思
const a = { b: 24 };
const b = { b: 35 };
// [object object]
a < b; // false
a > b; // false
a == b; // false
// 等于 !(a < b)
a <= b; // true
// 等于 !(a > b)
a >= b; // true
无关紧要的小知识
为什么有时用
void 0代替undefined?
undefined在ES5中已经是全局对象的一个只读(read-only)属性了,它不能被重写。但是在局部作用域中,还是可以被重写的。void运算符能对给定的表达式进行求值,然后返回undefined。即void后面你随便跟上一个表达式,返回的都是undefined,如 void (2), void (‘hello’)。void是不能被重写的,但为什么是void 0呢,因为void 0是表达式中最短的。