【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.

相关推荐
Moment1 分钟前
富文本编辑器技术选型,到底是 Prosemirror 还是 Tiptap 好 ❓❓❓
前端·javascript·面试
南行*4 分钟前
C语言Linux环境编程
linux·c语言·开发语言·网络安全
xkxnq6 分钟前
第二阶段:Vue 组件化开发(第 18天)
前端·javascript·vue.js
Morwit7 分钟前
Qt qml创建c++类的单例对象
开发语言·c++·qt
晓得迷路了7 分钟前
栗子前端技术周刊第 112 期 - Rspack 1.7、2025 JS 新星榜单、HTML 状态调查...
前端·javascript·html
古城小栈9 分钟前
Rust 已经自举,却仍需GNU与MSVC工具链的缘由
开发语言·rust
怕浪猫10 分钟前
React从入门到出门 第五章 React Router 配置与原理初探
前端·javascript·react.js
jinmo_C++10 分钟前
从零开始学前端 · HTML 基础篇(一):认识 HTML 与页面结构
前端·html·状态模式
jarreyer14 分钟前
数据项目分析标准化流程
开发语言·python·机器学习
鹏多多17 分钟前
前端2025年终总结:借着AI做大做强再创辉煌
前端·javascript