坚持Javascript中的递归

时间:2015-03-14 17:38:14

标签: javascript recursion

在理解这个问题的解决方案时遇到问题:

  

在   ==运算符按标识比较对象。但有时,您更愿意比较其实际属性的值。

     

编写一个函数deepEqual,它接受两个值并返回true   只有它们是相同的值或具有相同的对象   与递归相比,其值也相等的属性   打电话给deepEqual。

     

要确定是否按身份比较两件事(使用===   操作员)或通过查看他们的属性,你可以使用   typeof运算符。如果它产生"对象"对于这两个值,你应该   做一个深刻的比较。但你必须把一个愚蠢的例外   帐户:由于历史事故,typeof null也会生成" object"。

以下是解决方案:

function deepEqual(a, b) {   
  if (a === b) return true;
     if (a == null || typeof a != "object" ||
      b == null || typeof b != "object")
          return false;

  var propsInA = 0, propsInB = 0;

  for (var prop in a)
    propsInA += 1;

  for (var prop in b) {
    propsInB += 1;
    if (!(prop in a) || !deepEqual(a[prop], b[prop]))
      return false;   }

  return propsInA == propsInB; 
}

var obj = {here: {is: "an"}, object: 2}; 
console.log(deepEqual(obj, obj)); // → true 
console.log(deepEqual(obj, {here: 1, object: 2})); // → false     
console.log(deepEqual(obj, {here: {is: "an"}, object: 2})); // → true

特别是在第二轮for循环中发生的事情以及我们之后返回的内容方面存在问题。问题来自Eloquent Javascript第4章。感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

在第二个for循环中:

// #1
propsInB += 1;

计算对象属性

// #2
!(prop in a)

检查对象a是否具有与b相同的属性

// #3
!deepEqual(a[prop], b[prop])

检查两个对象的属性值是否具有相同的值(此处使用了deepEqual,因为它也可能正在比较另一个对象)

如果#2或#3失败,它会立即返回false,但是如果它不会发生(这意味着a具有所有b的属性),它最终会检查所有prop的数量是多少两个对象中的属性是相等的。如果是 - 对象是相同的实例。

修改

我重写了整个代码,因此对您来说更具可读性。 请注意,我为每个for循环将prop_a更改为prop_bfunction deepEqual(a, b) { if (a === b) return true; if (a == null || typeof a != "object" || b == null || typeof b != "object") { return false; } var propsInA = 0; var propsInB = 0; for (var prop_a in a) { propsInA += 1; } for (var prop_b in b) { propsInB += 1; if (!(prop_b in a) || !deepEqual(a[prop_b], b[prop_b])) { return false; } } return propsInA == propsInB; }

{{1}}