JavaScript重难点实例精讲
上QQ阅读APP看书,第一时间看更新

1.4.1 等于运算符

不同于其他编程语言,JavaScript中相等的比较分为双等于(==)比较和三等于(===)比较。这是因为在Java、C等强类型语言中,一个变量在使用前必须声明变量类型,所以在比较的时候就无须判断变量类型,只需要有双等于即可。而JavaScript是弱类型语言,一个变量可以声明为任何类型的值,在比较时,采用的等于运算符不同,最后得到的结果也可能不同,具体表现如下。

· 双等于运算符在比较时,会将两端的变量进行隐式类型转换,然后比较值的大小。

· 三等于运算符在比较时,会优先比较数据类型,数据类型相同才去判断值的大小,如果类型不同则直接返回“false”。

对于不同类型的数据,在比较时需要遵循不同的规则。

1. 三等于运算符

① 如果比较的值类型不相同,则直接返回“false”。


1 === '1'; // false
true === 'true';  // false 

需要注意的是,基本类型数据存在包装类型。在未使用new操作符时,简单类型的比较实际为值的比较,而使用了new操作符后,实际得到的是引用类型的值,在判断时会因为类型不同而直接返回“false”。


1 === Number(1);  // true
1 === new Number(1);  // false
'hello' === String('hello');  // true
'hello' === new String('hello'); // false

② 如果比较的值都是数值类型,则直接比较值的大小,相等则返回“true”,否则返回“false”。需要注意的是,如果参与比较的值中有任何一方为NaN,则返回“false”。


23 === 23;   // true
34 === NaN;  // false
NaN === NaN; // false

③ 如果比较的值都是字符串类型,则判断每个位置的字符是否一样,如果一样则返回“true”,否则返回“false”。


'kingx' === 'kingx';   // true
'kingx' === 'kingx2';  // false

④ 如果比较的值都是Boolean类型,则两者同时为true或者false时,返回“true”,否则返回“false”。


false === false;  // true
true === false;   // false

⑤ 如果比较的值都是null或者undefined,则返回“true”;如果只有一方为null或者undefined,则返回“false”。


null === null;   // true
undefined === undefined;   // tr
null === undefined;   // false

⑥ 如果比较的值都是引用类型,则比较的是引用类型的地址,当两个引用指向同一个地址时,则返回“true”,否则返回“false”。


var a = [];
var b = a;
var c = [];
console.log(a === b); // true
console.log(a === c); // false
console.log({} === {}); // false

实际上,如果不是通过赋值运算符(=)将定义的引用类型的值赋予变量,那么引用类型的值在比较后都会返回“false”,所以我们会发现空数组或者空对象的直接比较返回的是“false”。


[] === [];  // false
{} === {};  // false

引用类型变量的比较还有一个很明显的特点,即只要有一个变量是通过new操作符得到的,都会返回“false”,包括基本类型的包装类型。


'hello' === new String('hello');  // false
new String('hello') === new String('hello');  // false

// 函数对象类型
function Person(name) {
   this.name = name;
}
var p1 = new Person('zhangsan');
var p2 = new Person('zhangsan');
console.log(p1 === p2);  // false

2. 双等于运算符

相比于三等于运算符,双等于运算符在进行相等比较时,要略微复杂,因为它不区分数据类型,而且会做隐式类型转换。双等于运算符同样会遵循一些比较规则。

① 如果比较的值类型相同,则采用与三等于运算符一样的规则。


123 === 123;    // true
false == false; // true
[] == [];       // false
{} == {};       // false

② 如果比较的值类型不同,则会按照下面的规则进行转换后再进行比较。

· 如果比较的一方是null或者undefined,只有在另一方是null或者undefined的情况下才返回“true”,否则返回“false”。


null == undefined;      // true
null == 1;             // false
null == false;         // false
undefined == 0;         // false
undefined == false;      // false

· 如果比较的是字符串和数值类型数据,则会将字符串转换为数值后再进行比较,如果转换后的数值相等则返回“true”,否则返回“false”。


1 == '1';     // true
123 == '123'; // true

需要注意的是,如果字符串是十六进制的数据,会转换为十进制后再进行比较。


'0x15' == 21;  // true

字符串'0x15'实际为十六进制数,转换为十进制后为1×16 + 5 = 21,与21比较后返回“true”。

字符串并不支持八进制的数据,如果字符串以0开头,则0会直接省略,后面的值当作十进制返回。


'020' == 16;  // false
'020' == 20;  // true

'020'会被直接当作十进制处理,前面的0省略,得到的是20,然后与20比较后返回“true”。· 如果任一类型是boolean值,则会将boolean类型的值进行转换,true转换为1,false转换为0,然后进行比较。


'1' == true;    // true
'0' == false;   // true
'0.0' == false; // true
'true' == true; // false

上述代码中,true会转换为1,false会转换为0,字符串'1'会转换为1,'0'和'0.0'会转换为0,然后进行比较。而字符串'true'不能正常转换为数字,最终转换为NaN,所以'true'与true的比较会返回“false”。

· 如果其中一个值是对象类型,另一个值是基本数据类型或者对象类型,则会调用对象的valueOf()函数或者toString()函数,将其转换成基本数据类型后再作比较,关于valueOf()函数和toString()函数会在1.5节中详细讲到。