Javascript 深度比较:当两个对象的值不相同时,该代码如何返回false?

Javascript 深度比较:当两个对象的值不相同时,该代码如何返回false?,javascript,logic,Javascript,Logic,代码: 1。有人能解释一下第二街区的用途吗?它在做什么? 2。当两个对象中的值不相同时,哪个部分处理返回false?这是一个递归函数,当给定一个对象时,它将使用这些对象的值调用自己。因此,当您传入{b:1},{b:5}时,它将查看键并再次调用函数,如果键匹配,只需传入值。因此,在下一次迭代中,您调用deepEqual(1,5),它的计算结果为false,因为对于a==b测试,它没有返回true,并且其中一个(或两个)参数不是对象(typeof a!=“object”) 下面是一个示例,其中包含一

代码:

1。有人能解释一下第二街区的用途吗?它在做什么?


2。当两个对象中的值不相同时,哪个部分处理返回false?这是一个递归函数,当给定一个对象时,它将使用这些对象的值调用自己。因此,当您传入
{b:1},{b:5}
时,它将查看键并再次调用函数,如果键匹配,只需传入值。因此,在下一次迭代中,您调用
deepEqual(1,5)
,它的计算结果为false,因为对于
a==b
测试,它没有返回true,并且其中一个(或两个)参数不是对象(
typeof a!=“object”

下面是一个示例,其中包含一个键和一个console.log以提供帮助:

函数深度相等(a,b){
log(“用:”,a,b调用的深度相等)
如果(a==b)返回true;
log(“a和b是什么类型的?”,a的类型,b的类型)
log(“如果为null或不是object,则返回false”)
//第二街区
如果(a==null | |类型a!=“对象”||
b==null | | typeof b!=“object”)返回false;
设keysA=Object.keys(a),keysB=Object.keys(b);
if(keysA.length!=keysB.length)返回false;
for(让钥匙A的钥匙){
log(“让我们看看a[key]、b[key]、“是否相等”)
如果(!keysB.includes(key)| |!deepEqual(a[key],b[key]))返回false;
}
返回true;
}
一={b:1};
二={b:5};

控制台日志(deepEqual(一,二))//按预期返回false
函数打开时进行以下检查:

function deepEqual(a, b) {
 if (a === b) return true;

  //2nd block
 if (a == null || typeof a != "object" ||
     b == null || typeof b != "object") return false; 

 let keysA = Object.keys(a), keysB = Object.keys(b);

 if (keysA.length != keysB.length) return false;

for (let key of keysA) {
 if (!keysB.includes(key) || !deepEqual(a[key], b[key])) return false;
 }

return true;
}

 one= {a:1, b:1};
 two = {a:1, b:5};
 console.log(deepEqual(one, two));  //returns false as expected
这将涵盖值不是对象的所有情况,并且值可以直接相等。然而,对象将有不同的引用,要比较它们,您需要逐个挖掘它们

第二个街区:

if( a === b) return true;
这将检查值是否为null或不是对象。如果至少有一个值为null或不是对象,则此块返回false。这是因为第一个检查没有通过,我们知道这些值不是严格相等的,如果不是objects或null,那么它们就不相等。只有当两个值都是对象时,代码才会在此点之后执行


其余的是检查对象的键和值是否相同,检查是否设置了相同数量的键,是否调用了相同的键,然后通过调用self来递归,以比较调用相同键的值

您的函数通过消去过程确定相等性。这其中有两个棘手的方面:

  • 第二个街区:
  • 这从本质上检查值a和b是否不是js对象(这意味着它们没有更深层次的——键值对——来检查潜在的相等性)。如果值是primitive或null,那么我们可以假设它们不可能相等并返回false

  • 递归:
  • 检查a&b(给定a&b为对象)内的值是否相等的行位于for循环中:
    !深度相等(a[键]、b[键])
    这就是说,取a和b的值,其中key=key,并检查它们的相等性。在您的示例中,我们检查了两种情况:

    第一:

    if (a == null || typeof a != "object" ||
     b == null || typeof b != "object") return false;
    
    第二点:

    a[a] = 1
    b[a] = 1
    deepEqual(1, 1) --> gets called for key = a
    since 1 === 1 --> true gets returned
    
    通过您的代码进行逐步解释:

    a[b] = 1
    b[b] = 5
    deepEqual(1, 5) --> gets called for key = b
    since 1 !== 5 & 1 and 5 are not objects --> false gets returned
    
    现在来看递归语句!深度相等(a[key],b[key]),记住!意思是不。因此,如果deepequal()返回true,则if语句将进行计算。数组keysA和keysB只存储了对象的属性,但我们需要一种方法来比较该对象的值。 以奔驰和特斯拉为例

        function deepEqual(a, b) {
         // the line below checks whether two values are the same i.e 2 == 3 returns false;
         if (a === b) return true;
    
          /** This below if statement just checks to make sure that what is been passed 
        is an object . the "typeof" is what checks for it. when you run typeof on null values
      returns objects . so we must also check whether the value is null */
    
         if (a == null || typeof a != "object" ||
             b == null || typeof b != "object") return false; 
    
        // this puts into an array the object properties
         let keysA = Object.keys(a), keysB = Object.keys(b);
    
    /** checks if the length of the array are the same. if they have the same number of properties the array length will be equal*/
         if (keysA.length != keysB.length) return false;
    
    // this "let keys of keysA" was tricky for me but i figured it out
    // it loops through the array and returns the value into the variable let
        for (let key of keysA) {
         /** the first checks whether keysB array includes the properties that key is returning from keyA. i would explain the "!deepEqual(a[key], b[key])" statement in the comments*/
         if (!keysB.includes(key) || !deepEqual(a[key], b[key])) return false;
         }
    
        return true;
        }
    
         one= {a:1, b:1};
         two = {a:1, b:5};
         console.log(deepEqual(one, two));  //returns false as expected
    
    当我们调用Object.keys(benz)时,我们得到一个数组[“color”,“wheels”]

    为了找出对象的值,我们运行代码benz[keys]。。。严格遵守守则

    当调用这些值时。如果两个值都相等,则返回true。这使得递归函数再次调用自身,直到得到最终值。
    我希望所有读过这篇文章的人都能理解它

    最终调用
    deepEqual(a[key],b[key]
    将等同于调用
    deepEqual(1,5)
    ,因为第一行的原因,这将是错误的。嗨,对不起,你能帮我看一下吗?出于某些原因,我很难想象这一点?另外,如果我删除“第二块”,为什么它不再返回正确的值,因为这肯定与检查simple(a===b)的第一行无关(或者可能与之无关)?逐步完成这些操作的最佳方法是在所有地方添加
    console.log
    。在声明keysA和keysB后尝试添加一个,并在for循环中添加一个。(我认为这里发生的是假设它们不相等,因为1和5不是对象,根据检查的类型返回false)@LShapz这实际上是有意义的。基于第二次检查返回false。为了安全起见,我正确地假设给定两个不同的值,它首先检查第一行,当到达
    1==5
    时,第一行被完全跳过。控制转到
    2块
    ,并且从开始返回
    false
    e> 1和
    5
    不是
    对象
    ?在代码中,它实际上在哪里说“如果1,5不相同,则返回false”。我在第一行看到的是,如果两个值完全相同,
    返回true
    。但是,在这种情况下,
    5
    1
    是不同的,但它能够正确地
    返回false
    ?这是真正的混淆。另外,请您解释一下第二个块到底在这里做什么?对不起,这是错误的不清楚。当你传入两个非对象的参数并且不是
    ===
    时,你进入下一个块,如果其中一个不是对象,它将返回false。
    typeof!=“object”
    是的。肯定是第二个块返回false,而不是第一个块。许多
        function deepEqual(a, b) {
         // the line below checks whether two values are the same i.e 2 == 3 returns false;
         if (a === b) return true;
    
          /** This below if statement just checks to make sure that what is been passed 
        is an object . the "typeof" is what checks for it. when you run typeof on null values
      returns objects . so we must also check whether the value is null */
    
         if (a == null || typeof a != "object" ||
             b == null || typeof b != "object") return false; 
    
        // this puts into an array the object properties
         let keysA = Object.keys(a), keysB = Object.keys(b);
    
    /** checks if the length of the array are the same. if they have the same number of properties the array length will be equal*/
         if (keysA.length != keysB.length) return false;
    
    // this "let keys of keysA" was tricky for me but i figured it out
    // it loops through the array and returns the value into the variable let
        for (let key of keysA) {
         /** the first checks whether keysB array includes the properties that key is returning from keyA. i would explain the "!deepEqual(a[key], b[key])" statement in the comments*/
         if (!keysB.includes(key) || !deepEqual(a[key], b[key])) return false;
         }
    
        return true;
        }
    
         one= {a:1, b:1};
         two = {a:1, b:5};
         console.log(deepEqual(one, two));  //returns false as expected
    
    let benz = {
       color: "black",
       wheels : 4
    }
     let tesla = {
       color: "red",
       wheels : 4
    }