Creates a deep clone of a value with customizable cloning behavior through a user-provided customizer function
npx @tessl/cli install tessl/npm-lodash--clonedeepwith@4.5.00
# lodash.clonedeepwith
1
2
Creates a deep clone of a value with customizable cloning behavior through a user-provided customizer function. This method is like `_.cloneWith` except that it recursively clones the value, providing complete control over how different types of values are cloned.
3
4
## Package Information
5
6
- **Package Name**: lodash.clonedeepwith
7
- **Package Type**: npm
8
- **Language**: JavaScript
9
- **Installation**: `npm install lodash.clonedeepwith`
10
11
## Core Imports
12
13
```javascript
14
const cloneDeepWith = require('lodash.clonedeepwith');
15
```
16
17
Or when using the full lodash library:
18
19
```javascript
20
const _ = require('lodash');
21
// Use as _.cloneDeepWith(value, customizer)
22
```
23
24
## Basic Usage
25
26
```javascript
27
const cloneDeepWith = require('lodash.clonedeepwith');
28
29
// Basic deep cloning with custom DOM element handling
30
function customizer(value) {
31
if (value && value.nodeType) {
32
return value.cloneNode(true);
33
}
34
}
35
36
const originalElement = document.body;
37
const clonedElement = cloneDeepWith(originalElement, customizer);
38
39
console.log(clonedElement === originalElement); // => false
40
console.log(clonedElement.nodeName); // => 'BODY'
41
console.log(clonedElement.childNodes.length); // => 20
42
```
43
44
## Capabilities
45
46
### Deep Clone with Customizer
47
48
Creates a deep clone of a value with customizable cloning behavior through a user-provided customizer function.
49
50
```javascript { .api }
51
/**
52
* This method is like `_.cloneWith` except that it recursively clones `value`.
53
*
54
* @param {*} value The value to recursively clone.
55
* @param {Function} [customizer] The function to customize cloning.
56
* @returns {*} Returns the deep cloned value.
57
*/
58
function cloneDeepWith(value, customizer);
59
```
60
61
**Parameters:**
62
63
- `value` *(*)* - The value to recursively clone. Can be any JavaScript value including objects, arrays, primitives, functions, etc.
64
- `customizer` *(Function)* [optional] - The function to customize cloning behavior
65
66
**Returns:**
67
- *(*)* - Returns the deep cloned value
68
69
**Customizer Function:**
70
71
The customizer function is invoked with different arguments depending on the context:
72
73
- **For root-level cloning:** `customizer(value)`
74
- **For object properties:** `customizer(value, key, object, stack)`
75
76
Where:
77
- `value` - The current value being cloned
78
- `key` - The key of the property being cloned (when cloning object properties)
79
- `object` - The parent object containing the property (when cloning object properties)
80
- `stack` - Internal stack object used for circular reference handling
81
82
**Customizer Return Behavior:**
83
- Return `undefined` to use default cloning behavior
84
- Return any other value to use that value as the clone
85
- The customizer is called recursively for nested values
86
87
**Usage Examples:**
88
89
```javascript
90
const cloneDeepWith = require('lodash.clonedeepwith');
91
92
// Example 1: Custom DOM element cloning
93
function domCustomizer(value) {
94
if (value && value.nodeType) {
95
return value.cloneNode(true);
96
}
97
}
98
99
const element = document.createElement('div');
100
element.innerHTML = '<span>Hello</span>';
101
const clonedElement = cloneDeepWith(element, domCustomizer);
102
103
// Example 2: Custom class instance handling
104
class MyClass {
105
constructor(data) {
106
this.data = data;
107
}
108
}
109
110
function classCustomizer(value) {
111
if (value instanceof MyClass) {
112
return new MyClass(value.data);
113
}
114
}
115
116
const original = {
117
items: [new MyClass('test'), new MyClass('data')]
118
};
119
const cloned = cloneDeepWith(original, classCustomizer);
120
121
// Example 3: Selective property handling
122
function selectiveCustomizer(value, key) {
123
if (key === 'password') {
124
return '[REDACTED]';
125
}
126
if (key === 'timestamp') {
127
return new Date();
128
}
129
}
130
131
const userData = {
132
name: 'John',
133
password: 'secret123',
134
timestamp: new Date('2020-01-01'),
135
profile: {
136
email: 'john@example.com',
137
password: 'another-secret'
138
}
139
};
140
const sanitized = cloneDeepWith(userData, selectiveCustomizer);
141
142
// Example 4: Type-based customization
143
function typeCustomizer(value) {
144
if (value instanceof Date) {
145
return new Date(value.getTime() + 86400000); // Add one day
146
}
147
if (typeof value === 'function') {
148
return function() { return 'wrapped'; };
149
}
150
}
151
152
const complex = {
153
date: new Date(),
154
fn: function() { return 'original'; },
155
nested: {
156
date: new Date('2020-01-01'),
157
fn: () => 'arrow'
158
}
159
};
160
const customized = cloneDeepWith(complex, typeCustomizer);
161
```
162
163
## Supported Clone Types
164
165
The function can clone the following types:
166
167
- **Primitives:** strings, numbers, booleans, symbols, null, undefined
168
- **Objects:** plain objects, with recursive property cloning
169
- **Arrays:** including nested arrays and typed arrays (Float32Array, etc.)
170
- **Built-in Objects:** Date, RegExp, Map, Set, ArrayBuffer, DataView
171
- **Circular References:** automatically detected and handled
172
- **Custom Objects:** through customizer function
173
174
## Error Handling
175
176
The function handles circular references automatically using an internal stack. If the customizer function throws an error, the error will propagate up to the caller.
177
178
## Performance Notes
179
180
- Deep cloning is a recursive operation that can be expensive for large, deeply nested objects
181
- The function is optimized for arrays larger than 200 elements
182
- Circular reference detection adds overhead but prevents infinite loops
183
- Custom cloning logic in the customizer can impact performance depending on complexity