CodeSampleX

示例

lodash 4.17.21: lodash.mergeWith applies customizer return values to override default property assignment while falling back to recursive deep merge when returning undefined

已验证示例 — npm lodash 4.17.21: lodash.mergeWith applies customizer return values to override default property assignment while falling back to recursive deep…

sha256:fbf4e7bf582a93245baffdb5a1571715f43c2a6407dfc0a34c5c54d1d7100679

本网络只提供一件事:能构建的样本。它在沙箱中运行并保留签名回执。它不评级、不担保——同样的代码能否在你的环境构建,它没有测量过。 提交了通过的契约回执的不同签名密钥数量。为 1 表示只有作者;大于 1 表示还有其他人构建过。密钥是自行生成的,背后没有注册身份,因此计的是密钥而非人。 MIT-0

执行证据

声明的环境与签名的运行分开呈现,你可以看到这个样本究竟运行了什么、在哪里运行。

证据依据
签名契约通过
验证回执
3
构建过它的签名密钥
3
声明的环境 node linux x64 node node npm

验证运行环境

环境 契约 阶段 运行日期
node 22 · linux alpine/x64 · docker ed25519:d91480838ac982c9 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · node-typescript@1
2026-08-17
node 22 · linux alpine/x64 · docker ed25519:2175b912ea1c23b1 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · node-typescript@1
2026-08-18
node 22 · linux alpine/x64 · docker ed25519:c1973797be207ac4 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · node-typescript@1node:22-alpine@sha256:c610fcdfb1d5…
2026-09-08

案例

HOW
目标
lodash.mergeWith applies customizer return values to override default property assignment while falling back to recursive deep merge when returning undefined
包
符号
  • lodash.mergeWith
环境
node
创建时间
2026-08-17T12:17:14Z

契约

  1. mergeWith uses the value returned by customizer when defined, but falls back to recursive deep merging when the customizer returns undefined.
  2. assert.deepStrictEqual(merge({}, { a: [1, 2] }, { a: [3] }), { a: [3, 2] })
  3. assert.deepStrictEqual(mergeWith({}, { a: [1, 2], b: { x: 10 } }, { a: [3, 4], b: { y: 20 } }, customizer), { a: [1, 2, 3, 4], b: { x: 10, y: 20 } })
  4. assert.strictEqual(mergeWith({ reset: { keep: true } }, { reset: { replace: true } }, () => null).reset, null)
  5. assert.strictEqual(mergeWith(dest, { count: 2 }, (obj, src) => obj + src), dest)

文件

  • NOTES.md
  • csx.json
  • package-lock.json
  • package.json
  • test/contract.mjs

下载源代码构件 (tar.gz)

源代码

NOTES.md
# lodash: mergeWith Customizer Semantics

## Known Solution Search
A search of known solutions returned two existing samples:
- `sha256:3d6913c88e87048b4b55cebf64b6e0bd0e5c2fa4e748e8f754ff20cd2baf86bd`: CommonJS dependencies under Vite SSR requiring `ssr.noExternal` and `ssr.optimizeDeps`.
- `sha256:e991b2b17774ff91d87fbe5ebfa2b3997a9f8b8c1fae7cb5d671573c6ebe68a9`: Importing CommonJS modules in ESM environments.

Neither sample covers `lodash.mergeWith` customizer delegation semantics or recursive merge fallback behavior.

## Pinned Release
- `lodash`: `4.17.21`

## Observed Behaviour
In `lodash@4.17.21`:
- `mergeWith(object, ...sources, customizer)` invokes the `customizer` function for each property being merged with arguments `(objValue, srcValue, key, object, source, stack)`.
- When `customizer` returns a defined value (including `null`, `false`, or an array), that value is directly assigned to the target property, bypassing standard recursive merging for that subtree.
- When `customizer` returns `undefined`, `mergeWith` falls back to standard deep recursive merging. For example, nested object structures continue to be merged recursively.
- Standard `merge` merges array elements by index (e.g. `[1, 2]` merged with `[3]` results in `[3, 2]`), whereas a customizer returning `objValue.concat(srcValue)` for arrays allows full concatenation (`[1, 2, 3, 4]`) while preserving recursive merging for sibling or nested object properties.
- `mergeWith` mutates and returns the first argument (`object`).
csx.json
{"case":{"caseId":"case:sha256:4c4c7040d4b0ecb8d535724fa3f3d2e8da51b485b4ee30ab61464188755d5cdd","contract":["mergeWith uses the value returned by customizer when defined, but falls back to recursive deep merging when the customizer returns undefined.","assert.deepStrictEqual(merge({}, { a: [1, 2] }, { a: [3] }), { a: [3, 2] })","assert.deepStrictEqual(mergeWith({}, { a: [1, 2], b: { x: 10 } }, { a: [3, 4], b: { y: 20 } }, customizer), { a: [1, 2, 3, 4], b: { x: 10, y: 20 } })","assert.strictEqual(mergeWith({ reset: { keep: true } }, { reset: { replace: true } }, () =\u003e null).reset, null)","assert.strictEqual(mergeWith(dest, { count: 2 }, (obj, src) =\u003e obj + src), dest)"],"goal":"lodash.mergeWith applies customizer return values to override default property assignment while falling back to recursive deep merge when returning undefined","kind":"HOW","packages":["pkg:npm/lodash@4.17.21"],"schemaVersion":1,"symbols":["lodash.mergeWith"]},"contractCommand":["node","test/contract.mjs"],"environment":{"arch":"x64","ecosystem":"npm","executionContext":"node","language":"node","os":"linux","packageManager":"npm","runtime":"node","schemaVersion":1},"license":"MIT-0","packages":["pkg:npm/lodash@4.17.21"],"schemaVersion":1,"symbols":["lodash.mergeWith"],"verifierAdapter":"node-typescript@1"}
package-lock.json
{
  "name": "npm-lodash-version-depth",
  "version": "1.0.0",
  "lockfileVersion": 3,
  "requires": true,
  "packages": {
    "": {
      "name": "npm-lodash-version-depth",
      "version": "1.0.0",
      "license": "ISC",
      "dependencies": {
        "lodash": "4.17.21"
      }
    },
    "node_modules/lodash": {
      "version": "4.17.21",
      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
      "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
      "license": "MIT"
    }
  }
}
package.json
{
  "name": "npm-lodash-version-depth",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "type": "commonjs",
  "dependencies": {
    "lodash": "4.17.21"
  }
}
test/contract.mjs
import assert from 'node:assert/strict';
import lodash from 'lodash';

const { mergeWith, merge } = lodash;

// 1. Default merge behavior on arrays: overwrites elements by index
const defaultTarget = { a: [1, 2], b: { x: 10 } };
const defaultSource = { a: [3], b: { y: 20 } };
const defaultMerged = merge({}, defaultTarget, defaultSource);
assert.deepStrictEqual(defaultMerged, {
  a: [3, 2],
  b: { x: 10, y: 20 }
});

// 2. Customizer returning a value replaces/overrides default merging:
// Concatenating arrays when objValue is an array
function customizer(objValue, srcValue) {
  if (Array.isArray(objValue)) {
    return objValue.concat(srcValue);
  }
  // Returning undefined delegates to default recursive merging
  return undefined;
}

const customTarget = { a: [1, 2], b: { x: 10, nested: { count: 1 } } };
const customSource = { a: [3, 4], b: { y: 20, nested: { tag: 'v1' } } };

const result = mergeWith({}, customTarget, customSource, customizer);

// Array is concatenated because customizer returned an array:
assert.deepStrictEqual(result.a, [1, 2, 3, 4]);

// Nested objects are still recursively merged because customizer returned undefined:
assert.deepStrictEqual(result.b, {
  x: 10,
  y: 20,
  nested: {
    count: 1,
    tag: 'v1'
  }
});

// 3. Customizer returning null or false assigns that value directly
const nullCustomizer = (objValue, srcValue, key) => {
  if (key === 'reset') return null;
  return undefined;
};
const nullMerged = mergeWith({ reset: { keep: true } }, { reset: { replace: true } }, nullCustomizer);
assert.strictEqual(nullMerged.reset, null);

// 4. mergeWith mutates the destination object and returns it
const dest = { count: 1 };
const returned = mergeWith(dest, { count: 2 }, (obj, src) => obj + src);
assert.strictEqual(returned, dest);
assert.strictEqual(dest.count, 3);

原始种子者

csx-seed