JS的相等比较运算与类型转换

在JavaScript中,相等有两种比较方式:普通相等比较(==,在ECMAScript标准中称为“抽象相等比较”)和 严格相等比较(===)。
对于被广泛使用的普通相等比较运算符来讲,不同类型的操作数在进行比较之前,会尝试将两个操作数转换成相同的类型,再作比较运算。而对于严格相等比较运算符来讲,仅当两个操作数的类型相同且值相等时,返回为true。

抽象相等比较

ECMAScript标准的算法细节如下:

The comparison x == y, where x and y are values, produces true or false. Such a comparison is performed as follows:

  1. If Type(x) is the same as Type(y), then
    1. Return the result of performing Strict Equality Comparison x === y.
  2. If x is null and y is undefined, return true.
  3. If x is undefined and y is null, return true.
  4. If Type(x) is Number and Type(y) is String, return the result of the comparison x == ToNumber(y).
  5. If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y.
  6. If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y.
  7. If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).
  8. If Type(x) is either String, Number, or Symbol and Type(y) is Object, return the result of the comparison x == ToPrimitive(y).
  9. If Type(x) is Object and Type(y) is either String, Number, or Symbol, return the result of the comparison ToPrimitive(x) == y.
  10. Return false.

翻译如下:
1.如果Type(x)与Type(y)相同,执行严格相等运算x === y;
2.如果x是null,y是undefined,返回true;
3.如果x是undefined,y是null,返回true;

console.log(null == undefined);  // => true

4.如果Type(x)是数值,Type(y)是字符串,返回x == ToNumber(y)的结果;
5.如果Type(x)是字符串,Type(y)是数值,返回ToNumber(x) == y的结果;

如果字符串与数值比较,先字符串将转换成数值,再进行严格相等运算

console.log(1 == '1');  // => true

6.如果Type(x)是布尔值,返回ToNumber(x) == y的结果;
7.如果Type(y)是布尔值,返回x == ToNumber(y)的结果;

  1. 如果操作数为布尔类型,先将布尔值转换成数值。若布尔值为true,将转换成1,若为false,将转换成0
  2. 如果布尔值与字符串比较,布尔值会先转换成数值,而后便成了数值与字符串的比较;
console.log(true == 1);  // => true
console.log(false == 0);  // => true
console.log(true == '1');  // => true

8.如果Type(x)是字符串、数值或Symbol值,Type(y)是对象,返回x == ToPrimitive(y)的结果;
9.如果Type(x)是对象,Type(y)是字符串、数值或Symbol值,返回ToPrimitive(x) == y的结果;

如果对象与字符串、数值或Symbol值比较,先将对象转换成为一个非对象类型(non-Object type)的值。运算程序通过调用toStringvalueOf方法将对象转换为其原始值(一个非对象类型的值,比如字符串或数值等)。

class Human {
    toString(){
        return 1;
    }
}
class Animal {
    valueOf(){
        return 1;
    }
}
let human = new Human(), 
    animal = new Animal();
console.log(human == 1);  // => true
console.log(animal == 1);  // => true

10.返回false。

以上都不匹配,则返回false

严格相等比较

ECMAScript标准的算法细节如下:

The comparison x === y, where x and y are values, produces true or false. Such a comparison is performed as follows:

  1. If Type(x) is different from Type(y), return false.
  2. If Type(x) is Number, then
    1. If x is NaN, return false.
    2. If y is NaN, return false.
    3. If x is the same Number value as y, return true.
    4. If x is +0 and y is -0, return true.
    5. If x is -0 and y is +0, return true.
    6. Return false.
  3. Return SameValueNonNumber(x, y).

翻译如下:
1.如果Type(x)与Type(y)不同,返回false;
2.如果Type(x)是数值,则
    1.如果x是NaN,返回false;
    2.如果y是NaN,返回false;

NaN,是Not a Number的缩写,在IEEE浮点数算术标准(IEEE 754)中定义,表示一些特殊数值。在ECMAScript标准中,NaN属于Number类型

console.log(typeof NaN); // => "number"
console.log(NaN === NaN); // => false 

    3.如果x与y数值相同,返回true;
    4.如果x是+0、y是-0,返回true;
    5.如果x是-0、y是+0,返回true;

console.log(+0 === -0);  // => true

    6.返回false。
3.返回SameValueNonNumber(x, y)的结果。

当两个操作数不是数值类型时,调用内部运算SameValueNonNumber进行比较

SameValueNonNumber(x, y)

ECMAScript标准的算法细节如下:

The internal comparison abstract operation SameValueNonNumber(x, y), where neither x nor y are Number values, produces true or false. Such a comparison is performed as follows:

  1. Assert: Type(x) is not Number.
  2. Assert: Type(x) is the same as Type(y).
  3. If Type(x) is Undefined, return true.
  4. If Type(x) is Null, return true.
  5. If Type(x) is String, then
    1. If x and y are exactly the same sequence of code units (same length and same code units at corresponding indices), return true; otherwise, return false.
  6. If Type(x) is Boolean, then
    1. If x and y are both true or both false, return true; otherwise, return false.
  7. If Type(x) is Symbol, then
    1. If x and y are both the same Symbol value, return true; otherwise, return false.
  8. If x and y are the same Object value, return true. Otherwise, return false.

翻译如下:

  1. 断言: Type(x)不是数值;
  2. 断言: Type(x)与Type(y)相同;
  3. 如果Type(x)是Undefined,返回true;
  4. 如果Type(x)是Null,返回true;
  5. 如果Type(x)是字符串,则
    1. 如果x与y拥有相同字符顺序,返回true;否则,返回false。
  6. 如果Type(x)是布尔值,则
    1. 如果x与y都为true或都为false,返回true;否则,返回false。
  7. 如果Type(x)是Symbol值,则
    1. 如果x与y都为同一个Symbol值,返回true;否则,返回false。
  8. 如果x与y是同一个Object值,返回true;否则,返回false。

伪代码

  1. Type(x):获取传入参数的类型
  2. ToNumber(x):将传入参数转换为数值
  3. ToPrimitive(x):获取传入参数的原始值
  4. SameValueNonNumber(x, y):两个同类型、非数值的传入参数的比较运算

参考

[1] ECMA. ECMAScript 标准
[2] Mozilla. MDN Web 文档
[3] 阮一峰. ECMAScript 6 入门

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值