1 | # rfdc
|
---|
2 |
|
---|
3 | Really Fast Deep Clone
|
---|
4 |
|
---|
5 |
|
---|
6 | [![build status](https://img.shields.io/travis/davidmarkclements/rfdc.svg)](https://travis-ci.org/davidmarkclements/rfdc)
|
---|
7 | [![coverage](https://img.shields.io/codecov/c/github/davidmarkclements/rfdc.svg)](https://codecov.io/gh/davidmarkclements/rfdc)
|
---|
8 | [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](http://standardjs.com/)
|
---|
9 |
|
---|
10 |
|
---|
11 | ## Usage
|
---|
12 |
|
---|
13 | ```js
|
---|
14 | const clone = require('rfdc')()
|
---|
15 | clone({a: 1, b: {c: 2}}) // => {a: 1, b: {c: 2}}
|
---|
16 | ```
|
---|
17 |
|
---|
18 | ## API
|
---|
19 |
|
---|
20 | ### `require('rfdc')(opts = { proto: false, circles: false }) => clone(obj) => obj2`
|
---|
21 |
|
---|
22 | #### `proto` option
|
---|
23 |
|
---|
24 | Copy prototype properties as well as own properties into the new object.
|
---|
25 |
|
---|
26 | It's marginally faster to allow enumerable properties on the prototype
|
---|
27 | to be copied into the cloned object (not onto it's prototype, directly onto the object).
|
---|
28 |
|
---|
29 | To explain by way of code:
|
---|
30 |
|
---|
31 | ```js
|
---|
32 | require('rfdc')({ proto: false })(Object.create({a: 1})) // => {}
|
---|
33 | require('rfdc')({ proto: true })(Object.create({a: 1})) // => {a: 1}
|
---|
34 | ```
|
---|
35 |
|
---|
36 | Setting `proto` to `true` will provide an additional 2% performance boost.
|
---|
37 |
|
---|
38 | #### `circles` option
|
---|
39 |
|
---|
40 | Keeping track of circular references will slow down performance with an
|
---|
41 | additional 25% overhead. Even if an object doesn't have any circular references,
|
---|
42 | the tracking overhead is the cost. By default if an object with a circular
|
---|
43 | reference is passed to `rfdc`, it will throw (similar to how `JSON.stringify` \
|
---|
44 | would throw).
|
---|
45 |
|
---|
46 | Use the `circles` option to detect and preserve circular references in the
|
---|
47 | object. If performance is important, try removing the circular reference from
|
---|
48 | the object (set to `undefined`) and then add it back manually after cloning
|
---|
49 | instead of using this option.
|
---|
50 |
|
---|
51 | ### `default` import
|
---|
52 | It is also possible to directly import the clone function with all options set
|
---|
53 | to their default:
|
---|
54 |
|
---|
55 | ```js
|
---|
56 | const clone = require("rfdc/default")
|
---|
57 | clone({a: 1, b: {c: 2}}) // => {a: 1, b: {c: 2}}
|
---|
58 | ```
|
---|
59 |
|
---|
60 | ### Types
|
---|
61 |
|
---|
62 | `rfdc` clones all JSON types:
|
---|
63 |
|
---|
64 | * `Object`
|
---|
65 | * `Array`
|
---|
66 | * `Number`
|
---|
67 | * `String`
|
---|
68 | * `null`
|
---|
69 |
|
---|
70 | With additional support for:
|
---|
71 |
|
---|
72 | * `Date` (copied)
|
---|
73 | * `undefined` (copied)
|
---|
74 | * `Buffer` (copied)
|
---|
75 | * `TypedArray` (copied)
|
---|
76 | * `Map` (copied)
|
---|
77 | * `Set` (copied)
|
---|
78 | * `Function` (referenced)
|
---|
79 | * `AsyncFunction` (referenced)
|
---|
80 | * `GeneratorFunction` (referenced)
|
---|
81 | * `arguments` (copied to a normal object)
|
---|
82 |
|
---|
83 | All other types have output values that match the output
|
---|
84 | of `JSON.parse(JSON.stringify(o))`.
|
---|
85 |
|
---|
86 | For instance:
|
---|
87 |
|
---|
88 | ```js
|
---|
89 | const rfdc = require('rfdc')()
|
---|
90 | const err = Error()
|
---|
91 | err.code = 1
|
---|
92 | JSON.parse(JSON.stringify(e)) // {code: 1}
|
---|
93 | rfdc(e) // {code: 1}
|
---|
94 |
|
---|
95 | JSON.parse(JSON.stringify({rx: /foo/})) // {rx: {}}
|
---|
96 | rfdc({rx: /foo/}) // {rx: {}}
|
---|
97 | ```
|
---|
98 |
|
---|
99 | ## Benchmarks
|
---|
100 |
|
---|
101 | ```sh
|
---|
102 | npm run bench
|
---|
103 | ```
|
---|
104 |
|
---|
105 | ```
|
---|
106 | benchDeepCopy*100: 457.568ms
|
---|
107 | benchLodashCloneDeep*100: 1230.773ms
|
---|
108 | benchCloneDeep*100: 655.208ms
|
---|
109 | benchFastCopy*100: 747.017ms
|
---|
110 | benchRfdc*100: 281.018ms
|
---|
111 | benchRfdcProto*100: 277.265ms
|
---|
112 | benchRfdcCircles*100: 328.148ms
|
---|
113 | benchRfdcCirclesProto*100: 323.004ms
|
---|
114 | ```
|
---|
115 |
|
---|
116 | ## Tests
|
---|
117 |
|
---|
118 | ```sh
|
---|
119 | npm test
|
---|
120 | ```
|
---|
121 |
|
---|
122 | ```
|
---|
123 | 169 passing (342.514ms)
|
---|
124 | ```
|
---|
125 |
|
---|
126 | ### Coverage
|
---|
127 |
|
---|
128 | ```sh
|
---|
129 | npm run cov
|
---|
130 | ```
|
---|
131 |
|
---|
132 | ```
|
---|
133 | ----------|----------|----------|----------|----------|-------------------|
|
---|
134 | File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
|
---|
135 | ----------|----------|----------|----------|----------|-------------------|
|
---|
136 | All files | 100 | 100 | 100 | 100 | |
|
---|
137 | index.js | 100 | 100 | 100 | 100 | |
|
---|
138 | ----------|----------|----------|----------|----------|-------------------|
|
---|
139 | ```
|
---|
140 |
|
---|
141 | ## License
|
---|
142 |
|
---|
143 | MIT
|
---|