or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/npm-lodash--clone

Creates shallow and deep clones of JavaScript values supporting arrays, objects, primitives, dates, maps, sets, and more.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/lodash@4.5.x

To install, run

npx @tessl/cli install tessl/npm-lodash--clone@4.5.0

0

# Lodash Clone

1

2

Lodash Clone provides comprehensive cloning functionality for JavaScript values, supporting both shallow and deep cloning operations with customization options. Part of the Lodash utility library, these functions handle a wide range of JavaScript types including arrays, objects, primitives, dates, maps, sets, regular expressions, and more.

3

4

## Package Information

5

6

- **Package Name**: lodash

7

- **Package Type**: npm

8

- **Language**: JavaScript

9

- **Installation**: `npm install lodash`

10

11

## Core Imports

12

13

```javascript

14

import { clone, cloneDeep, cloneWith, cloneDeepWith } from "lodash";

15

```

16

17

For CommonJS:

18

19

```javascript

20

const { clone, cloneDeep, cloneWith, cloneDeepWith } = require("lodash");

21

```

22

23

Full lodash import:

24

25

```javascript

26

import _ from "lodash";

27

// Use as _.clone(), _.cloneDeep(), etc.

28

```

29

30

## Basic Usage

31

32

```javascript

33

import { clone, cloneDeep } from "lodash";

34

35

// Shallow clone - shared references for nested objects

36

const original = { a: 1, b: { c: 2 } };

37

const shallow = clone(original);

38

console.log(shallow.b === original.b); // => true

39

40

// Deep clone - completely independent copy

41

const deep = cloneDeep(original);

42

console.log(deep.b === original.b); // => false

43

44

// Works with arrays

45

const arr = [{ name: "Alice" }, { name: "Bob" }];

46

const clonedArr = clone(arr);

47

console.log(clonedArr[0] === arr[0]); // => true (shallow)

48

49

const deepArr = cloneDeep(arr);

50

console.log(deepArr[0] === arr[0]); // => false (deep)

51

```

52

53

## Architecture

54

55

Lodash clone functionality is built around several key architectural components:

56

57

- **Core Engine**: The `baseClone` function serves as the central implementation handling all clone operations with parameters for depth, customization, and circular reference tracking

58

- **Type Routing**: Specialized clone handlers route different JavaScript types to optimized cloning strategies based on their `toStringTag`

59

- **Circular Reference Protection**: A stack-based tracking system prevents infinite recursion when cloning objects with circular references

60

- **Property Preservation**: Special logic preserves important properties like `lastIndex` on RegExp objects, `index` and `input` on RegExp exec results, and constructor relationships

61

- **Customization Layer**: Optional customizer functions allow override of default cloning behavior at any level of the object tree

62

- **Type-Specific Handlers**: Dedicated functions for complex types like ArrayBuffers, typed arrays, Maps, Sets, and Node.js Buffers ensure correct cloning semantics

63

64

## Capabilities

65

66

### Shallow Clone

67

68

Creates a shallow clone of a value where nested objects and arrays are shared between the original and clone.

69

70

```javascript { .api }

71

/**

72

* Creates a shallow clone of `value`.

73

* @param {*} value The value to clone.

74

* @returns {*} Returns the cloned value.

75

*/

76

function clone(value);

77

```

78

79

**Supported Types:**

80

- **Arrays**: Standard arrays and array-like objects

81

- **ArrayBuffers**: Binary data buffers with proper byte copying

82

- **Booleans**: Boolean primitives and Boolean objects

83

- **Dates**: Date objects with preserved time values

84

- **Maps**: Map objects with all key-value pairs preserved

85

- **Numbers**: Number primitives and Number objects

86

- **Objects**: Plain objects and object instances

87

- **RegExp**: Regular expressions with source, flags, and `lastIndex` preserved

88

- **Sets**: Set objects with all values preserved

89

- **Strings**: String primitives and String objects

90

- **Symbols**: Both symbol primitives and Symbol objects

91

- **Typed Arrays**: All typed array types (Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array)

92

- **Arguments Objects**: Cloned as plain objects with length property

93

- **Buffers**: Node.js Buffer objects (when available)

94

95

**Unsupported Types:** Returns empty object `{}` for functions, DOM nodes, WeakMaps, error objects, generators

96

97

**Usage Examples:**

98

99

```javascript

100

// Basic shallow cloning

101

const obj = { a: 1, b: { c: 2 } };

102

const cloned = clone(obj);

103

cloned.a = 10;

104

cloned.b.c = 20;

105

console.log(obj.a); // => 1 (independent)

106

console.log(obj.b.c); // => 20 (shared reference)

107

108

// Array cloning

109

const numbers = [1, 2, 3];

110

const clonedNumbers = clone(numbers);

111

console.log(clonedNumbers); // => [1, 2, 3]

112

113

// Date cloning

114

const date = new Date();

115

const clonedDate = clone(date);

116

console.log(clonedDate instanceof Date); // => true

117

```

118

119

### Shallow Clone with Customizer

120

121

Like clone but accepts a customizer function to produce the cloned value.

122

123

```javascript { .api }

124

/**

125

* This method is like `clone` except that it accepts `customizer` which

126

* is invoked to produce the cloned value.

127

* @param {*} value The value to clone.

128

* @param {Function} [customizer] The function to customize cloning.

129

* @returns {*} Returns the cloned value.

130

*/

131

function cloneWith(value, customizer);

132

```

133

134

**Customizer Function:**

135

- Called with arguments: `(value [, index|key, object, stack])`

136

- Return `undefined` to handle cloning normally

137

- Return any other value to use as the cloned result

138

139

**Usage Examples:**

140

141

```javascript

142

// Custom DOM node cloning

143

function customizer(value) {

144

if (value && value.nodeType === 1) { // Element node

145

return value.cloneNode(false);

146

}

147

}

148

149

const el = cloneWith(document.body, customizer);

150

console.log(el === document.body); // => false

151

console.log(el.nodeName); // => 'BODY'

152

153

// Custom handling for specific types

154

function typeCustomizer(value) {

155

if (typeof value === 'symbol') {

156

return Symbol(value.description);

157

}

158

}

159

160

const obj = { sym: Symbol('test') };

161

const customCloned = cloneWith(obj, typeCustomizer);

162

```

163

164

### Deep Clone

165

166

Creates a deep clone of a value where all nested objects and arrays are recursively cloned.

167

168

```javascript { .api }

169

/**

170

* This method is like `clone` except that it recursively clones `value`.

171

* @param {*} value The value to recursively clone.

172

* @returns {*} Returns the deep cloned value.

173

*/

174

function cloneDeep(value);

175

```

176

177

**Usage Examples:**

178

179

```javascript

180

// Deep object cloning

181

const original = {

182

user: { name: "Alice", profile: { age: 25 } },

183

tags: ["admin", "user"]

184

};

185

186

const deepCloned = cloneDeep(original);

187

deepCloned.user.profile.age = 30;

188

deepCloned.tags.push("moderator");

189

190

console.log(original.user.profile.age); // => 25 (unchanged)

191

console.log(original.tags.length); // => 2 (unchanged)

192

193

// Circular reference handling

194

const circular = { a: 1 };

195

circular.self = circular;

196

const clonedCircular = cloneDeep(circular);

197

console.log(clonedCircular.self === clonedCircular); // => true

198

199

// Complex nested structures with multiple circular references

200

const complex = { data: { items: [] } };

201

complex.data.parent = complex;

202

complex.data.items.push({ ref: complex.data });

203

const clonedComplex = cloneDeep(complex);

204

console.log(clonedComplex.data.parent === clonedComplex); // => true

205

console.log(clonedComplex.data.items[0].ref === clonedComplex.data); // => true

206

```

207

208

### Deep Clone with Customizer

209

210

Like cloneWith but recursively clones the value with customization.

211

212

```javascript { .api }

213

/**

214

* This method is like `cloneWith` except that it recursively clones `value`.

215

* @param {*} value The value to recursively clone.

216

* @param {Function} [customizer] The function to customize cloning.

217

* @returns {*} Returns the deep cloned value.

218

*/

219

function cloneDeepWith(value, customizer);

220

```

221

222

**Usage Examples:**

223

224

```javascript

225

// Custom deep cloning for DOM elements

226

function domCustomizer(value) {

227

if (value && value.nodeType === 1) {

228

return value.cloneNode(true); // Deep clone DOM

229

}

230

}

231

232

const container = cloneDeepWith(document.getElementById('container'), domCustomizer);

233

234

// Custom handling for class instances

235

function classCustomizer(value) {

236

if (value instanceof MyClass) {

237

return new MyClass(value.getData());

238

}

239

}

240

241

const complex = {

242

instance: new MyClass(),

243

nested: { another: new MyClass() }

244

};

245

246

const customDeepCloned = cloneDeepWith(complex, classCustomizer);

247

```

248

249

## Type Definitions

250

251

```javascript { .api }

252

/**

253

* Customizer function for clone operations

254

* @callback Customizer

255

* @param {*} value - The value being cloned

256

* @param {number|string} [index] - The index or key of value

257

* @param {Object} [object] - The parent object of value

258

* @param {Object} [stack] - The stack for tracking circular references

259

* @returns {*} The custom cloned value or undefined for default handling

260

*/

261

262

/**

263

* Cloneable value types supported by lodash clone functions

264

* @typedef {Array|ArrayBuffer|boolean|Date|Map|number|Object|RegExp|Set|string|symbol|TypedArray} CloneableValue

265

*/

266

```

267

268

## Advanced Features

269

270

### Circular Reference Handling

271

272

Lodash clone functions automatically detect and handle circular references to prevent infinite recursion:

273

274

```javascript

275

// Self-referencing object

276

const obj = { name: "parent" };

277

obj.self = obj;

278

const cloned = cloneDeep(obj);

279

console.log(cloned.self === cloned); // => true (maintains circularity)

280

281

// Cross-referencing objects

282

const a = { name: "a" };

283

const b = { name: "b", ref: a };

284

a.ref = b;

285

const clonedA = cloneDeep(a);

286

console.log(clonedA.ref.ref === clonedA); // => true

287

```

288

289

### Property Preservation

290

291

Clone functions preserve important properties and metadata:

292

293

```javascript

294

// RegExp lastIndex preservation

295

const regex = /test/g;

296

regex.lastIndex = 5;

297

const clonedRegex = clone(regex);

298

console.log(clonedRegex.lastIndex); // => 5

299

300

// RegExp exec result properties (index and input)

301

const execResult = /(\w+)/.exec("hello world");

302

execResult.customProp = "added";

303

const clonedResult = clone(execResult);

304

console.log(clonedResult.index); // => 0 (preserved)

305

console.log(clonedResult.input); // => "hello world" (preserved)

306

console.log(clonedResult.customProp); // => "added" (preserved)

307

308

// Array expando properties

309

const arr = [1, 2, 3];

310

arr.customProperty = "custom";

311

const clonedArr = clone(arr);

312

console.log(clonedArr.customProperty); // => "custom"

313

```

314

315

### Buffer Cloning (Node.js)

316

317

In Node.js environments, Buffer objects are properly cloned:

318

319

```javascript

320

// Node.js Buffer handling

321

const buffer = Buffer.from("hello", "utf8");

322

const clonedBuffer = clone(buffer);

323

console.log(Buffer.isBuffer(clonedBuffer)); // => true

324

console.log(clonedBuffer.toString()); // => "hello"

325

console.log(clonedBuffer === buffer); // => false (different instances)

326

```

327

328

## Error Handling

329

330

Clone functions handle edge cases gracefully:

331

332

- **Uncloneable values** (functions, DOM nodes, WeakMaps, error objects): Return empty objects `{}`

333

- **Null/undefined**: Return as-is

334

- **Primitives**: Return as-is (numbers, strings, booleans)

335

- **Circular references**: Detected and handled properly in deep clone operations

336

- **Invalid customizer**: Ignored if not a function, falls back to default behavior

337

338

## Performance Notes

339

340

- **Shallow cloning** is faster and uses less memory

341

- **Deep cloning** is more expensive but provides complete independence

342

- **Customizers** add overhead but provide flexibility

343

- Consider using shallow clone when nested object sharing is acceptable

344

- Use deep clone when complete isolation is required

345

346

## Common Patterns

347

348

```javascript

349

// State management (shallow clone for immutability)

350

const newState = { ...state, updates: clone(state.updates) };

351

352

// API response processing (deep clone for data manipulation)

353

const processedData = cloneDeep(apiResponse);

354

processData(processedData); // Safe to mutate

355

356

// Configuration merging with custom handling

357

const config = cloneDeepWith(defaultConfig, (value) => {

358

if (Array.isArray(value)) {

359

return [...value]; // Custom array handling

360

}

361

});

362

```