You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					144 lines
				
				3.4 KiB
			
		
		
			
		
	
	
					144 lines
				
				3.4 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								# rfdc
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Really Fast Deep Clone
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[](https://travis-ci.org/davidmarkclements/rfdc)
							 | 
						||
| 
								 | 
							
								[](https://codecov.io/gh/davidmarkclements/rfdc)
							 | 
						||
| 
								 | 
							
								[](http://standardjs.com/)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								## Usage
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								const clone = require('rfdc')()
							 | 
						||
| 
								 | 
							
								clone({a: 1, b: {c: 2}}) // => {a: 1, b: {c: 2}}
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								## API
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### `require('rfdc')(opts = { proto: false, circles: false }) => clone(obj) => obj2`
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#### `proto` option
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Copy prototype properties as well as own properties into the new object.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								It's marginally faster to allow enumerable properties on the prototype
							 | 
						||
| 
								 | 
							
								to be copied into the cloned object (not onto it's prototype, directly onto the object).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								To explain by way of code:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								require('rfdc')({ proto: false })(Object.create({a: 1})) // => {}
							 | 
						||
| 
								 | 
							
								require('rfdc')({ proto: true })(Object.create({a: 1})) // => {a: 1}
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Setting `proto` to `true` will provide an additional 2% performance boost.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#### `circles` option
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Keeping track of circular references will slow down performance with an
							 | 
						||
| 
								 | 
							
								additional 25% overhead. Even if an object doesn't have any circular references,
							 | 
						||
| 
								 | 
							
								the tracking overhead is the cost. By default if an object with a circular
							 | 
						||
| 
								 | 
							
								reference is passed to `rfdc`, it will throw (similar to how `JSON.stringify` \
							 | 
						||
| 
								 | 
							
								would throw).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Use the `circles` option to detect and preserve circular references in the
							 | 
						||
| 
								 | 
							
								object. If performance is important, try removing the circular reference from
							 | 
						||
| 
								 | 
							
								the object (set to `undefined`) and then add it back manually after cloning
							 | 
						||
| 
								 | 
							
								instead of using this option.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### `default` import
							 | 
						||
| 
								 | 
							
								It is also possible to directly import the clone function with all options set
							 | 
						||
| 
								 | 
							
								to their default:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								const clone = require("rfdc/default")
							 | 
						||
| 
								 | 
							
								clone({a: 1, b: {c: 2}}) // => {a: 1, b: {c: 2}}
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### Types
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								`rfdc` clones all JSON types:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								* `Object`
							 | 
						||
| 
								 | 
							
								* `Array`
							 | 
						||
| 
								 | 
							
								* `Number`
							 | 
						||
| 
								 | 
							
								* `String`
							 | 
						||
| 
								 | 
							
								* `null`
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								With additional support for:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								* `Date` (copied)
							 | 
						||
| 
								 | 
							
								* `undefined` (copied)
							 | 
						||
| 
								 | 
							
								* `Buffer` (copied)
							 | 
						||
| 
								 | 
							
								* `TypedArray` (copied)
							 | 
						||
| 
								 | 
							
								* `Map` (copied)
							 | 
						||
| 
								 | 
							
								* `Set` (copied)
							 | 
						||
| 
								 | 
							
								* `Function` (referenced)
							 | 
						||
| 
								 | 
							
								* `AsyncFunction` (referenced)
							 | 
						||
| 
								 | 
							
								* `GeneratorFunction` (referenced)
							 | 
						||
| 
								 | 
							
								* `arguments` (copied to a normal object)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								All other types have output values that match the output
							 | 
						||
| 
								 | 
							
								of `JSON.parse(JSON.stringify(o))`.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								For instance:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								const rfdc = require('rfdc')()
							 | 
						||
| 
								 | 
							
								const err = Error()
							 | 
						||
| 
								 | 
							
								err.code = 1
							 | 
						||
| 
								 | 
							
								JSON.parse(JSON.stringify(e)) // {code: 1}
							 | 
						||
| 
								 | 
							
								rfdc(e) // {code: 1}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								JSON.parse(JSON.stringify({rx: /foo/})) // {rx: {}}
							 | 
						||
| 
								 | 
							
								rfdc({rx: /foo/}) // {rx: {}}
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								## Benchmarks
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```sh
							 | 
						||
| 
								 | 
							
								npm run bench
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								benchDeepCopy*100: 457.568ms
							 | 
						||
| 
								 | 
							
								benchLodashCloneDeep*100: 1230.773ms
							 | 
						||
| 
								 | 
							
								benchCloneDeep*100: 655.208ms
							 | 
						||
| 
								 | 
							
								benchFastCopy*100: 747.017ms
							 | 
						||
| 
								 | 
							
								benchRfdc*100: 281.018ms
							 | 
						||
| 
								 | 
							
								benchRfdcProto*100: 277.265ms
							 | 
						||
| 
								 | 
							
								benchRfdcCircles*100: 328.148ms
							 | 
						||
| 
								 | 
							
								benchRfdcCirclesProto*100: 323.004ms
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								## Tests
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```sh
							 | 
						||
| 
								 | 
							
								npm test
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								169 passing (342.514ms)
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### Coverage
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```sh
							 | 
						||
| 
								 | 
							
								npm run cov
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								----------|----------|----------|----------|----------|-------------------|
							 | 
						||
| 
								 | 
							
								File      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
							 | 
						||
| 
								 | 
							
								----------|----------|----------|----------|----------|-------------------|
							 | 
						||
| 
								 | 
							
								All files |      100 |      100 |      100 |      100 |                   |
							 | 
						||
| 
								 | 
							
								 index.js |      100 |      100 |      100 |      100 |                   |
							 | 
						||
| 
								 | 
							
								----------|----------|----------|----------|----------|-------------------|
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								## License
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								MIT
							 |