判断全相等| 青训营笔记

92 阅读3分钟

这是我参与「第四届青训营 」笔记创作活动的第4天

一、先来讲讲 == 和 ===

==(转换类型比较):在比较前先将左右两个操作数转为相同类型再比较

=== (严格比较):直接比较,不转换类型,要求变量类型和值均相等。使用===可避免因“JS类型转换”带来的问题

二、 判断基本数据类型

基本数据类型:String、Number、Boolean、Null、Undefined、ES6新加的Symbol

现在可以大胆的说,因为 === 是直接比较的,不转换类型,so,推荐使用 === / !== ,而不是 == / != ,判断两个基本数据类型是否相等

三、判断引用类型

引用数据类型:Array、Object、Function、Date、RegExp等

使用 === 或 == 时,当且仅当两个对象的引用指针指向内存堆中的相同区域(地址)时,才相等。

但有时候我们的需求就只是比较“值”,so,封装isEqual函数咯

四、封装isEqual全相等函数

判断两个变量是否全相等【重点是对象类型的全等验证】

限制:[] 和 {}

// *** 工具函数:判断是否是对象 ***
function isObject(obj){
    return (typeof obj == "object") && (obj !== null)
}

// *** 中心函数:判断两个变量是否全相等【重点是对象类型的全等验证】  ***
// 传入:两个变量
// 传出:true || false
function isequal(obj1 ,obj2){
    if(!isObject(obj1) || !isObject(obj2)){
        return obj1 === obj2 // 比较的两个值中任意一个不是对象,直接用 === 判断是否全相等
    }
    if(obj1 === obj2){ //对象之间用 === 或 == 比较,就是比较他们的地址是否相等
        return true
    }
    if(Object.keys(obj1).length !== Object.keys(obj2).length){ // 获取两者所有自身可遍历属性长度 进行比较
        return false
    }
    for (const key in obj1) { // 遍历其中一个对象的所有自身和继承的可遍历属性
        let res = isequal(obj1[key] ,obj2[key])
        if(res === false){ // 某一层属性判断结果为false,直接返回结果
            return false
        }
    }
    return true // 通过每一层属性的全等判断,表示这两个对象全等
}
//*** 验证 ***
let obj1 = {
    'a': 123,
    123: 'a',
    'arr':[1,2,3],
    'obj': {
        'ar':'我是武当门派'
    } 
}
let obj2 = {
    'a': 123,
    123: 'a',
    'arr':[1,2,3],
    'obj': {
        'ar':'我是天山门派'
    } 
}
let obj3 = {
    'a': 123,
    123: 'a',
    'arr':[1,2,3],
    'obj': {
        'ar':"我是天山门派"
    } 
}
// *** 直接用 == 或 === 不能真正判断到对象的值,而只是判断了对象中存储的指针指向的堆内存是否是同一片区域(地址) ***
console.log(obj1 == obj2) // false
console.log(obj1 === obj2) // false
console.log(obj2 == obj3) // flase
console.log(obj2 === obj3) // flase
// *** 测试结果如下,武当派当然不能和天门山派混为一谈啦 ***
console.log(isequal(obj1,obj2)) // false
console.log(isequal(obj3,obj2)) // true

步骤分析

  1. 先判断两个对象中若有一个不是对象 【isObject 工具函数】 ,直接用 === 判断是否全相等;
  2. 否则再判断变量内存储的指针地址是否相同 ,地址相同直接返回true;
  3. 否则再判断对象的键的个数是否相等 【使用 Object.keys() 】,不相等直接返回false;
  4. 否则用for...in遍历其中一个对象,用递归判断两个对象的每层属性,一旦有不符合的直接返回false;
  5. 最后,如果for...in遍历完成,则返回true,表示两个对象全等