前端面试题-手写isEqual深度比较

440 阅读1分钟

题目:手写深度比较,执行深比较来确定两者的值是否相等, 模拟lodash的isEqual,例如如下效果

lodash的isEqual方法文档

// 定义两个对象
const obj1 = {a: 10, b: {x: 100, y: 200}}
const obj2 = {a: 10, b: {x: 100, y: 200}}

// 使用===判断会返回false
obj1 === obj2 // 返回false

// 自定义isEqual满足如下结果
isEqual(obj1, obj2) === true

代码实现如下

// 判断一个变量是否是对象的方法
function isObject(obj) {
    return typeof obj === 'object' && obj !== null
}

// 比较函数的实现
function isEqual(obj1, obj2) {
    if (!isObject(obj1) || !isObject(obj2)) {
        // 值类型,走正常的===进行判断
        return obj1 === obj2
    }
    
    // 如果是对象并且===为true,那么返回true
    if (obj1 === obj2) {
        return true
    }
    
    // 两个都是对象或数组, 而且不相等
    // 1. 对比对象的属性是否一样多,数组的元素个数是否一样多(数组也可以使用Object.keys,返回的是索引的集合)
    const obj1Keys = Object.keys(obj1)
    const obj2Keys = Object.keys(obj2)
    // 如果两个要对比的变量属性数量/元素数量不相等,那么直接返回false
    if (obj1Keys.length !== obj2Keys.length) {
        return false
    }
    
    // 2. 以obj1为基准,和obj2依次递归比较
    for (let key in obj1) {
        // 递归调用isEqual
        const res = isEqual(obj1[key], obj2[key])
        if (!res) {
            return false
        }
    }
    // 递归调用都返回true,那么说明子属性都相等,最终返回true
    return true
}

归纳总结

  1. 编写函数的时候需要进行边界判断,非object类型的变量,使用===进行判断
  2. 判断两个参数是否是一个变量,使用===判断返回true
  3. 对比两个参数的属性数量,不同那么直接返回false
  4. 深度递归对比每个属性值,如果有不同,那么return false;都相同,最终return true