【Javascript】jsondiffpatch检测到子节点改变了,父节点会标记为改变吗?

答案是:No

但是你也有办法检查哪些父节点受到改变的影响,具体分析如下:

jsondiffpatch is designed to be very granular and identifies changes at the most specific path possible.

If a sub-node changes, the parent node itself is not explicitly identified as "changed" in the jsondiffpatch delta. The delta will only show the specific change at the path of the sub-node.

Why?

jsondiffpatch aims for minimal, atomic changes. It doesn't generate a "cascading" change report up the object tree. It pinpoints the exact property or array element that was added, removed, or modified.

Example

Let's illustrate this with an example:

javascript 复制代码
const jsondiffpatch = require('jsondiffpatch').create();

const originalJson = {
  "id": 1,
  "name": "Product A",
  "details": {
    "price": 100,
    "currency": "USD",
    "dimensions": {
      "width": 10,
      "height": 20
      // "depth": 5 // uncomment to see another type of change
    }
  },
  "tags": ["electronics", "gadget"]
};

const modifiedJson = {
  "id": 1,
  "name": "Product A",
  "details": {
    "price": 100,
    "currency": "USD",
    "dimensions": {
      "width": 12, // <--- This sub-node changed
      "height": 20
    }
  },
  "tags": ["electronics", "gadget"]
};

const delta = jsondiffpatch.diff(originalJson, modifiedJson);

console.log("Original JSON:\n", JSON.stringify(originalJson, null, 2));
console.log("\nModified JSON:\n", JSON.stringify(modifiedJson, null, 2));
console.log("\nDelta (changes):\n", JSON.stringify(delta, null, 2));

// --- Let's also check if 'details' or 'dimensions' objects are marked as direct changes ---
// (They won't be)
const detailsDelta = delta && delta.details;
const dimensionsDelta = detailsDelta && detailsDelta.dimensions;

console.log("\nIs 'details' itself in the delta (as a modified object)?", !!detailsDelta && Object.keys(detailsDelta).length > 0);
console.log("Is 'dimensions' itself in the delta (as a modified object)?", !!dimensionsDelta && Object.keys(dimensionsDelta).length > 0);

if (delta) {
  // To check if a specific parent was "affected", you'd look for its properties in the delta.
  const detailsAffected = 'details' in delta;
  const dimensionsAffected = 'details' in delta && 'dimensions' in delta.details;
  const widthAffected = 'details' in delta && 'dimensions' in delta.details && 'width' in delta.details.dimensions;

  console.log("\nProgrammatic check:");
  console.log("'details' node path is present in delta:", detailsAffected);
  console.log("'dimensions' node path is present in delta:", dimensionsAffected);
  console.log("'width' node path is present in delta:", widthAffected);
}

Output Explanation:

复制代码
Original JSON:
 {
  "id": 1,
  "name": "Product A",
  "details": {
    "price": 100,
    "currency": "USD",
    "dimensions": {
      "width": 10,
      "height": 20
    }
  },
  "tags": [
    "electronics",
    "gadget"
  ]
}

Modified JSON:
 {
  "id": 1,
  "name": "Product A",
  "details": {
    "price": 100,
    "currency": "USD",
    "dimensions": {
      "width": 12,
      "height": 20
    }
  },
  "tags": [
    "electronics",
    "gadget"
  ]
}

Delta (changes):
 {
  "details": {
    "dimensions": {
      "width": [
        10,
        12
      ]
    }
  }
}

Is 'details' itself in the delta (as a modified object)? true
Is 'dimensions' itself in the delta (as a modified object)? true

Programmatic check:
'details' node path is present in delta: true
'dimensions' node path is present in delta: true
'width' node path is present in delta: true

As you can see from the Delta (changes) output:

  1. The delta object has a details property.
  2. Inside details, it has a dimensions property.
  3. Inside dimensions, it has a width property, which shows the actual change [10, 12].

jsondiffpatch doesn't report details as being replaced by a new details object, nor dimensions as being replaced. It just shows that something inside details.dimensions.width changed.

How to interpret "parent affected":

While the parent itself isn't marked as replaced, its path is present in the delta object if any of its children (or children's children, etc.) have changed.

So, if you want to know if details was "affected," you would check if delta.details exists and has any properties (indicating changes within it). If delta.details.dimensions exists, then dimensions was affected. If delta.details.dimensions.width exists and contains a change array, then width itself changed.

相关推荐
东东2331 小时前
GeoJSON 介绍:Web 地图数据的通用语言
前端·javascript·json
之恒君1 小时前
Promise.resolve(x) 等同 new Promise(resolve => resolve(x))?
前端·promise
Tzarevich1 小时前
JavaScript 原型链:理解对象继承的核心机制
javascript·promise
caron41 小时前
C++ 推箱子游戏
开发语言·c++·游戏
JienDa1 小时前
JienDa聊PHP:PHP从入门到精通—PHP开发入门:从环境搭建到第一个程序
开发语言·php
T___T1 小时前
写着写着,就踩进了 JavaScript 的小坑
前端·javascript·面试
ERP老兵-冷溪虎山1 小时前
Python/JS/Go/Java同步学习(第五十篇半)四语言“path路径详解“对照表: 看完这篇定位文件就通透了(附源码/截图/参数表/避坑指南)
java·javascript·python·golang·中医编程·编程四语言同步学·path路径详解
月亮慢慢圆1 小时前
首字母模糊匹配
前端
一个有理想的摸鱼选手1 小时前
CesiumLite-在三维地图中绘制3D图形变得游刃有余
前端·gis·cesium