JavaScript深度比较

3
关于对象的深度比较的问题已经被问到了,我有解决方案。但是在解决方案中有一行代码我不完全理解。
这是解决方案,它是Eloquent JS第四章中一个关于比较对象的问题。除了这一行代码之外,我都能理解:
    if (!(prop in a) || !deepEqual(a[prop], b[prop]))

它位于底部。以下是完整的功能代码:
```html

它位于底部。以下是完整的功能代码:

```
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;
}

“if (!(prop in a)”是在比较'b'对象在该索引处是否存在属性,还是在比较值?

关于第二部分的问题也一样,但我知道答案不同: !deepEqual(a[prop], b[prop])进行了何种比较(例如,true或false)? 我理解递归,但与我的上一个问题一样,这是在进行“存在性”比较,还是在比较值中的信息?

预先感谢。

3个回答

1

根据MDN的说法:

in 运算符会返回一个布尔值,表示指定的属性是否在指定的对象中。

此外:

for...in 语句按任意顺序迭代对象的可枚举属性。对于每个不同的属性,可以执行语句。

因此,回答您的第一个问题,prop in a 是检查来自对象 b 的字段 prop 是否存在于对象 a 中。

回答您的第二个问题,deepEqual(a[prop], b[prop]) 检查对象 a[prop]b[prop] 是否相等,包括其所有子项和内容。


谢谢caffinatedmonky(以及其他所有人的帮助)。这正是我所想,但我想确认一下。感谢关于“in”的信息。 - hikinthru
@hikinthru欢迎来到stackoverflow。谢谢您没有在第一篇帖子中犯语法错误。 - 0xcaff

0

它正在检查存在性。它说:“对于B中的每个属性,检查A。如果A没有该属性,或者A上该属性的值与B上该属性的值不相等,则返回false。”

另一种实现方式将避免在该行进行存在性检查,而是在函数顶部使用if(typeof A == 'undefined')来验证每轮递归开始时的输入参数...乍一看,我认为这是等效的,但效率较低。当前的实现避免了对未定义属性的调用。


但是,a = {x:undefined}b = {y:undefined}是否“深度相等”呢? - Bergi
好问题!显然 undefined == undefined 是真的(我不确定会是这样...可能会被视为不定),所以我想你问题中的 a 和 b 应该是深度相等的。很棒的发现。 - S McCrohan

0

in运算符返回true,如果表达式右侧的对象包含左侧字符串值的键。

例如:prop in a如果a包含与prop字符串值相同的名称的键,则为真。

var prop = "age";

var obj1 = {
    name: "Dave",
    age: 21,
    record: { ... }
};
var obj2 = {
    name: "John",
    record: { ... }
};

console.log(prop in obj1); // true
console.log(prop in obj2); // false

如果 prop 被设置为 "record",那么 deepEqual(a[prop], b[prop]) 会递归比较 a.recordb.record 中的

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接