# @bluelovers/deep-diff 中文文档

规范地址：https://npmcn.com/package/%40bluelovers/deep-diff/

版本：2\.0\.1
npm 元数据更新时间：2026-04-03T06:11:50.603Z
中文译文更新时间：2026-11-08T08:38:47.610Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40bluelovers/deep-diff
原文对照：https://npmcn.com/package/%40bluelovers/deep-diff/?lang=original
项目主页：https://github.com/bluelovers/deep-diff#readme
源码仓库：https://github.com/bluelovers/deep-diff

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：921 kB，44 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- 运行依赖：0 个
- 首次发布：2021-06-07T21:01:03.510Z
- 最新版本发布：2026-04-03T06:11:50.488Z
- 近 30 天下载量：4417（2026-10-09 至 2026-11-07，npm 官方下载统计）
- 已发布版本数：3（近 12 个月 1 个）

## 中文简介

Javascript 用于计算深差,捕获变化,并在对象之间应用变化;用于节点和浏览器.

## 安装

```sh
npm install @bluelovers/deep-diff
```

也可以使用：`pnpm add @bluelovers/deep-diff`、`yarn add @bluelovers/deep-diff`、`bun add @bluelovers/deep-diff`

## README

# 深潜

**深潜** 是一个javascript/node.js模块,提供用于确定对象间结构差异的功能,并包括一些用于应用对象间差异的功能.

## 安装

```bash
npm install @bluelovers/deep-diff
```

可能 v1.0 相容性 :

-   数组中的元素现在按倒序处理,它会修正一些纠缠错误,但可能会打破一些用户
    -   如果您的代码依赖于报告差异的顺序, 那么您的代码将会被打破 。 如果你认为一个对象图是一棵大树,那么 `deep-diff` 执行 [对象图的前序倒转](https://en.wikipedia.org/wiki/Tree_traversal)然而,当遇到一个阵列时,阵列从一端到一端进行处理,每个元素在再下降时按顺序递归处理.

## 特征

-   获取两个对象之间的结构差异 .
-   观察两个对象之间的结构差异.
-   当结构差异代表变化时,应用从一个对象到另一个对象的改变.
-   当结构差异代表变化时,有选择地将改变从一个对象应用到另一个对象.

## 安装

```bash
npm install @bluelovers/deep-diff
```

### 导入

#### 节点

```javascript
var diff = require('@bluelovers/deep-diff').diff
// or:
// const diff = require('deep-diff');
// const { diff } = require('deep-diff');
// or:
// const DeepDiff = require('deep-diff');
// const { DeepDiff } = require('deep-diff');
// es6+:
// import diff from 'deep-diff';
// import { diff } from 'deep-diff';
// es6+:
// import DeepDiff from 'deep-diff';
// import { DeepDiff } from 'deep-diff';
```

#### 浏览器

```html
<script src="https://cdn.jsdelivr.net/npm/deep-diff@1/dist/deep-diff.min.js"></script>
```

> 在浏览器中, `deep-diff` 定义全局变量 `DeepDiff`。如果全局命名空间存在冲突,您可以恢复冲突的定义并指定 `deep-diff` 变成这样的变量 : `var deep = DeepDiff.noConflict();`。 。 。 .

## 简单示例

为了描述差异,变化围绕着 `origin` 对象。 为保持一致 `origin` 对象总是在 `left-hand-side` 行动。 这个 `comparand`,它可能包含变化,总是在 `right-hand-side` 行动.

```javascript
var diff = require('@bluelovers/deep-diff').diff;

var lhs = {
  name: 'my object',
  description: 'it\'s an object!',
  details: {
    it: 'has',
    an: 'array',
    with: ['a', 'few', 'elements']
  }
};

var rhs = {
  name: 'updated object',
  description: 'it\'s an object!',
  details: {
    it: 'has',
    an: 'array',
    with: ['a', 'few', 'more', 'elements', { than: 'before' }]
  }
};

var differences = diff(lhs, rhs);
```

_五.0.2.0及以上 (单位:千美元)_ 上面的代码片段将导致描述这些差异的下列结构:

```javascript
[ { kind: 'E',
    path: [ 'name' ],
    lhs: 'my object',
    rhs: 'updated object' },
  { kind: 'E',
    path: [ 'details', 'with', 2 ],
    lhs: 'elements',
    rhs: 'more' },
  { kind: 'A',
    path: [ 'details', 'with' ],
    index: 3,
    item: { kind: 'N', rhs: 'elements' } },
  { kind: 'A',
    path: [ 'details', 'with' ],
    index: 4,
    item: { kind: 'N', rhs: { than: 'before' } } } ]
```

### 差额

差异作为一项或多项变动记录列报。 更改记录的结构如下:

-   `kind` - 说明变化类型;将是下列变化之一:
    -   `N` - 表示新增加的财产/要素
    -   `D` - 表明财产/要素被删除
    -   `E` - 表明已编辑财产/内容
    -   `A` - 表示数组内发生的变化
-   `path` - 属性路径(从左手边根)
-   `lhs` - 比较左手边的值( 未定义是否为“ N” 类型)
-   `rhs` - 比较右侧的值( 未定义是否为 “% ” )
-   `index` - 当类型 “% 1” 时, 表示变化发生的数组索引
-   `item` - 当类型“ A” 时, 包含一个嵌入式更改记录, 显示阵列索引上发生的更改

生成所有结构差异的更改记录 `origin` 财务报告和审定财务报表 `comparand`。这些方法只考虑对象本身的属性和数组元素;不考虑从对象原型链所继承的元素.

对数组的更改是简单记录的。 我们最关心的是结构的形状;因此我们不花时间来确定一个物体是否从数组中的一个插槽移动到另一个插槽. 相反,我们只记录结构 差别。 如果结构差异是从 `comparand` 页:1 `origin` 然后两个对象将比较为“ 深等” , 使用大多数 `isEqual` 执行,例如载于 [摇篮](https://github.com/bestiejs/lodash) 或者说 [下划线](http://underscorejs.org/)。 。 。 .

### 变动

当两个对象不同时,可以观察到它们被计算时的区别,并有选择地将这些变化应用到原对象(左手侧)上.

```javascript
var observableDiff = require('deep-diff').observableDiff;
var applyChange = require('deep-diff').applyChange;

var lhs = {
  name: 'my object',
  description: 'it\'s an object!',
  details: {
    it: 'has',
    an: 'array',
    with: ['a', 'few', 'elements']
  }
};

var rhs = {
  name: 'updated object',
  description: 'it\'s an object!',
  details: {
    it: 'has',
    an: 'array',
    with: ['a', 'few', 'more', 'elements', { than: 'before' }]
  }
};

observableDiff(lhs, rhs, function (d) {
  // Apply all changes except to the name property...
  if (d.path[d.path.length - 1] !== 'name') {
    applyChange(lhs, rhs, d);
  }
});
```

## API 文档

标准导入 `var diff = require('deep-diff')` 在所有代码示例中假设。 导入结果为对象具有下列公共属性:

-   `diff(lhs, rhs[, options, acc])` ——计算两个对象之间的差异,可选择使用指定的累积器.
-   `observableDiff(lhs, rhs, observer[, options])` ——计算两个对象之间的相差,每个对象向一个观察函数报告.
-   `applyDiff(target, source, filter)` ——将源对象的任何结构差异应用到目标对象上,可选择过滤出每个差异.
-   `applyChange(target, source, change)` ——对目标对象应用单一更改记录. 注: `source` 未使用,可删除.
-   `revertChange(target, source, change)` 将单个更改记录还原为目标对象。 注: `source` 未使用,可删除.

### `diff`

这个 `diff` 函数计算两个对象之间的相差.

#### 参数

-   `lhs` - 左手操作;源对象.
-   `rhs` - 右手操作;正在从结构上将对象与原对象作比较.
-   `options` - 可具有下列属性的配置对象:
    -   `prefilter`: 函数,用于决定差异分析是否应在对象图下继续。 此功能还可以取代 `options` 后向兼容性参数中的对象.
    -   `normalize`: 预处理的函数 _叶子_ 在树上.
-   `acc` - 可选累积器/阵列(要求它具有下列特性: `push` 函数)。 每种差异被推到指定的累积器上.

返回一系列变化,或者,如果没有变化, `undefined`。这原本是选中的,所以结果将会通过一个真实测试:

```javascript
var changes = diff(obja, objb);
if (changes) {
  // do something with the changes.
}
```

#### 过滤前对象属性

这个 `prefilter`'签名应为: `function(path, key)` 它应该返回任何真实值 `path`\- 说吧`key` 组合,应当过滤。 如果经过过滤,则差异分析不会在已识别的对象-财产路径上进行进一步分析.

```javascript
const diff = require('@bluelovers/deep-diff').diff;
const assert = require('assert');

const data = {
  issue: 126,
  submittedBy: 'abuzarhamza',
  title: 'readme.md need some additional example prefilter',
  posts: [
    {
      date: '2018-04-16',
      text: `additional example for prefilter for deep-diff would be great.
      https://stackoverflow.com/questions/38364639/pre-filter-condition-deep-diff-node-js`
    }
  ]
};

const clone = JSON.parse(JSON.stringify(data));
clone.title = 'README.MD needs additional example illustrating how to prefilter';
clone.disposition = 'completed';

const two = diff(data, clone);
const none = diff(data, clone,
  (path, key) => path.length === 0 && ~['title', 'disposition'].indexOf(key)
);

assert.equal(two.length, 2, 'should reflect two differences');
assert.ok(typeof none === 'undefined', 'should reflect no differences');
```

#### 使对象属性正常化

这个 `normalize`'签名应为: `function(path, key, lhs, rhs)` 如果未实现正常化,它应返回病态值,或 `[lhs, rhs]` 阵列来替换原始值。 如果路径在 `prefilter` 阶段.

```javascript
const diff = require('@bluelovers/deep-diff').diff;
const assert = require('assert');

const data = {
  pull: 149,
  submittedBy: 'saveman71',
};

const clone = JSON.parse(JSON.stringify(data));
clone.issue = 42;

const two = diff(data, clone);
const none = diff(data, clone, {
  normalize: (path, key, lhs, rhs) => {
    if (lhs === 149) {
      lhs = 42;
    }
    if (rhs === 149) {
      rhs = 42;
    }
    return [lhs, rhs];
  }
});

assert.equal(two.length, 1, 'should reflect one difference');
assert.ok(typeof none === 'undefined', 'should reflect no difference');
```

### `observableDiff`

这个 `observableDiff` 函数计算两个对象之间的差额,并将每个对象报告给一个观察员函数.

#### 参数

-   `lhs` - 左手操作;源对象.
-   `rhs` - 右手操作;正在从结构上将对象与原对象作比较.
-   `observer` - 向观察员报告.
-   `options` - 可具有下列属性的配置对象:
    -   `prefilter`: 函数,用于决定差异分析是否应在对象图下继续。 此功能还可以取代 `options` 后向兼容性参数中的对象.
    -   `normalize`: 预处理的函数 _叶子_ 在树上.

## 捐款

在作出贡献时,铭记着这是一个目标: `deep-diff` 没有包的依赖性。 这在未来可能有所改变,但目前没有依赖关系.

请在提交公关前进行单位测试: `npm test`。希望您的PR包含额外的单位测试,以说明您的改变/修改!

当你跑的时候 `npm test`, 将进行 linting 操作, 任何 linting 错误将失败测试... 这包括代码格式化 .

> 感谢所有那些贡献至今的人们!

## 常见问题

### @bluelovers/deep-diff 是什么？

Javascript 用于计算深差,捕获变化,并在对象之间应用变化;用于节点和浏览器\.

### 如何安装 @bluelovers/deep-diff？

在项目目录运行 npm install @bluelovers/deep-diff，或使用 pnpm add / yarn add / bun add。

### @bluelovers/deep-diff 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @bluelovers/deep-diff 支持 ESM 还是 CommonJS？

同时提供 ES Module 与 CommonJS 入口，import 和 require\(\) 都可以使用，打包工具会自动选择合适的版本。

### @bluelovers/deep-diff 可以商用吗？

@bluelovers/deep-diff 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @bluelovers/deep-diff 的下载量有多少？

根据 npm 官方下载统计，@bluelovers/deep-diff 在 2026/10/09 – 2026/11/07 这 30 天内被下载 4,417 次，日均约 147 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @bluelovers/deep-diff 还在维护吗？

最新版本 2\.0\.1 发布于 2026/04/03（7 个月前）；至今共发布 3 个版本，其中过去 12 个月发布了 1 个；首次发布于 2021/06/08。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

