今天看啥  ›  专栏  ›  红_e8d9

JavaScript相等运算符匹配规则

红_e8d9  · 简书  ·  · 2021-03-04 22:55

文章预览

JavaScript的等号有=,==,===三个运算符虽然都读成“等于”,但概念是不一样的,=指的是赋值;==称为相等运算符,比较的是两个操作数值是否相等;===称为严格相等运算符,比较的是两个操作数是否是“完全相同”。

一般情况下我们尽量使用“===”来精确判断,在判断对象属性和函数参数是否存在时可以使用“==”。

用于判断对象的属性是否存在
let obj = {};
if( obj.a == null ) {
    //这里相对于:obj.a === null || obj.a === undefined 的简写形式,jquery源码的推荐写法
}

用于判断函数的参数是否存在
function fn( a, b ) {
    if( a == null ) {
        //这里也相当于 a === null || a === undefined 的简写
    }
}

严格相等运算符

说明: 严格匹配,不会类型转换,必须要数据类型和值完全一致。

先判断类型,如果类型不是同一类型的话直接为false;

1 对于基本数据类型(值类型): Number,String,Boolean,Null和Undefined:两边的值要一致,才相等
      console.log(null === null)   // true
      console.log(undefined === undefined)  // true
   注意: NaN: 不会等于任何数,包括它自己
   console.log(NaN === NaN)  // false 

2 对于复杂数据类型(引用类型): Object,Array,Function等:两边的引用地址如果一致的话,是相等的
     arr1 = [1,2,3];
     arr2 = arr1;
     console.log(arr1 === arr2)   // true

相等运算符

相等运算符(“==”)操作结果参照表
image

比较规则:

1. 值的类型相同

应用严格相等运算符转换规则的值类型相同规则(除:操作数类型不同)。

2.不同原始类型值(string,boolean,number)

规则:如果是不同原始类型值(数字、字符串、布尔值)进行比较,有隐式类型转换,会将不是number类型的数据转成number

0 == undefined //false
// 等同于 0 == Number(undefined)
// 等同于0 == NAN

0 == null  //false
// 等同于 0 == Number(null)

1 == true // true
// 等同于 1 == Number(true)

'true' == true // false
// 等同于 Number('true') == Number(true)
// 等同于 NaN === 1

'' == 0 // true
// 等同于 Number('') == 0
// 等同于 0 == 0

'1' == true  // true
// 等同于 Number('1') == Number(true)
// 等同于 1 == 1

'\n  123  \t' == 123 // true
// 因为字符串转为数字时,省略前置和后置的空格

1 == ! "true" //false  
(1) 1 == !Boolean('true')  (2) 1 == !true  (3) 1 == false  (4)1 ==Number(false)
 0 == ! "true" //true

3. 对象和原始类型值

如果其中一个操作数是对象,另外一个是原始类型值(数字、字符串、布尔值),按如下规则:

将对象转换成原始类型值: 先调用valueOf方法,然后调用toString方法
转换后的原始类型值与另一个操作数的类型一样,使用值类型相同的规则
如果不一样,将非数字类型转换成数字再进行比较。

valueOf :一般默认返回自身
数组的toString :默认会调用join方法拼接每个元素并且返回拼接后的字符串

例1:对象对比数字

[1] == 1 //true
解析:
a. [1]先转换成原始值"1";
b. 转换后与右边的操作数1类型不一样,将"1"转换成1;
c. 1 == 1 结果是true

例2:对象对比字符串

[1] == "1"
解析:
a. [1]先转换成原始值"1";
b. 转换后与右边的操作数"1"类型一样,"1"=="1",结果是true;

例3:对象对比布尔值

[1] == true
解析:
a. [1]先转换成原始值"1";
b. 转换后与右边的操作数true类型不一样,将右边的操作数true转换成1;
c. 1 == 1 结果是true

[].toString () ;//空字符串
{}.toString () ;//[object Object]
注意:  空数组的toString()方法会得到空字符串,
      而空对象的toString()方法会得到字符串[object Object] (注意第一个小写o,第二个大写O哟)
{} == '[object Object]';//true

[ 1, 2, 3 ].valueOf().toString();//‘1,2,3’
[ 1, 2, 3 ] == "1,2,3" ;//true  
//(1)[1,2,3].toString() == '1,2,3'  (2)'1,2,3' == '1,2,3'

4.都是复杂数据类型 :

只比较地址,如果地址一致则返回true,否则返回false

var arr1 = [10,20,30];
var arr2 = [10,20,30];
var arr3 = arr1;//将arr1的地址拷贝给arr3

console.log ( arr1 == arr2 );//虽然arr1与arr2中的数据是一样,但是它们两个不同的地址
console.log ( arr3 == arr1 );//true  两者地址是一样

console.log ( [] == [] );//false
console.log ( {} == {} );//false

5. null和undefined

如果其中一个值是null,另外一个是undefined,结果是相等

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

6.NaN : NaN与任何数字都不等

规则:没有隐式类型转换,无条件返回false

console.log ( NaN == NaN );//false

总结

严格相等运算符的比较是不对操作数进行类型转换的,只要操作数类型不一致,返回就是false;
null和undefined是严格相等的,而NaN和任何类型的操作数都不会相等包括它自己。

相等运算符是会对操作数是不同的原始值类型,都转换成数字再进行比较;
如果是原始值类型和对象的比较,先调用valueOf方法转换为自身,然后调用toString方法转换成字符串,如果还是不同,都转换成数字再进行比较;

面试题

注意:八种情况转boolean得到false: 0 -0 NaN undefined null '' false document.all()

[] == 0; //true 
(1) [].valueOf().toString() == 0  
(2) Number('') == 0  
(3) false == 0  
(4) 0 == 0

console.log(![] == 0); //true
  // 逻辑非优先级高于关系运算符 ![] = false (空数组转布尔值得到true)

[] == []; //false
// [] 与右边逻辑非表达式结果比较
(1) [] == !Boolean([])   
(2) [] == !true  
(3) [] == false  
(4) [].toString() == false  
(5)'' == false   
(6)Number('0') == Number(false)
console.log([] == ![]); //true

{} == {}; //false
// {} 与右边逻辑非表达式结果比较
(1){} == !{} 
(2){} == !true  
(3){} == false  
(4){}.toString() == false  
(5)'[object Object]' == false  
(6)Number('[object Object]') == false
console.log({} == !{}); //false
………………………………

原文地址:访问原文地址
快照地址: 访问文章快照
总结与预览地址:访问总结与预览