Javascript 深度比较

Javascript Deep Comparison

本文关键字:比较 深度 Javascript      更新时间:2023-09-26
关于

对象深度比较的问题已经被问到,我有解决方案。但是解决方案中有一条我不完全理解的线。

这是解决方案,这是Eloquent JS第4章中比较对象的问题。我得到了所有内容,除了这一行:

    if (!(prop in a) || !deepEqual(a[prop], b[prop]))

它位于底部。这是完整的功能:

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])进行哪种类型的比较(例如,真或假)?我理解递归,但就像我之前的问题一样,这是在进行"它存在"的比较,还是对值中信息的比较?

提前谢谢你。

根据 MDN:

如果指定的属性位于指定的对象中,则 in 运算符返回true

也:

为...in 语句以任意顺序循环访问对象的可枚举属性。对于每个不同的属性,可以执行语句。

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

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

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

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

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 中的

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

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