web 3d图形渲染器
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.

213 lines
7.0 KiB

  1. <div align="center">
  2. <img src="logo.png" alt="klona" height="100" />
  3. </div>
  4. <div align="center">
  5. <a href="https://npmjs.org/package/klona">
  6. <img src="https://badgen.now.sh/npm/v/klona" alt="version" />
  7. </a>
  8. <a href="https://github.com/lukeed/klona/actions">
  9. <img src="https://github.com/lukeed/klona/workflows/CI/badge.svg" alt="CI" />
  10. </a>
  11. <a href="https://npmjs.org/package/klona">
  12. <img src="https://badgen.now.sh/npm/dm/klona" alt="downloads" />
  13. </a>
  14. <a href="https://codecov.io/gh/lukeed/klona">
  15. <img src="https://codecov.io/gh/lukeed/klona/branch/master/graph/badge.svg?token=8ej0WeKqz7" alt="codecov" />
  16. </a>
  17. </div>
  18. <div align="center">A tiny (240B to 501B) and fast utility to "deep clone" Objects, Arrays, Dates, RegExps, and more!</div>
  19. ## Features
  20. * Super tiny and [performant](#benchmarks)
  21. * Deep clone / recursive copies
  22. * Safely handles complex data types<br>
  23. _Array, Date, Map, Object, RegExp, Set, TypedArray, and more_
  24. Unlike a "shallow copy" (eg, `Object.assign`), a "deep clone" recursively traverses a source input and copies its _values_ &mdash; instead of _references_ to its values &mdash; into a new instance of that input. The result is a structurally equivalent clone that operates independently of the original source and controls its own values.
  25. > **Why "klona"?** It's "clone" in Swedish.<br>
  26. > **What's with the sheep?** [Dolly](https://en.wikipedia.org/wiki/Dolly_(sheep)).
  27. ## Install
  28. ```
  29. $ npm install --save klona
  30. ```
  31. ## Modes
  32. There are multiple "versions" of `klona` available, which allows you to bring only the functionality you need!
  33. #### `klona/json`
  34. > **Size (gzip):** 240 bytes<br>
  35. > **Availability:** [CommonJS](https://unpkg.com/klona/json/index.js), [ES Module](https://unpkg.com/klona/json/index.mjs), [UMD](https://unpkg.com/klona/json/index.min.js)<br>
  36. > **Ability:** JSON data types
  37. ```js
  38. import { klona } from 'klona/json';
  39. ```
  40. #### `klona/lite`
  41. > **Size (gzip):** 354 bytes<br>
  42. > **Availability:** [CommonJS](https://unpkg.com/klona/lite/index.js), [ES Module](https://unpkg.com/klona/lite/index.mjs), [UMD](https://unpkg.com/klona/lite/index.min.js)<br>
  43. > **Ability:** extends `klona/json` with support for custom class, Date, and RegExp
  44. ```js
  45. import { klona } from 'klona/lite';
  46. ```
  47. #### `klona`
  48. > **Size (gzip):** 451 bytes<br>
  49. > **Availability:** [CommonJS](https://unpkg.com/klona/dist/index.js), [ES Module](https://unpkg.com/klona/dist/index.mjs), [UMD](https://unpkg.com/klona/dist/index.min.js)<br>
  50. > **Ability:** extends `klona/lite` with support for Map, Set, DataView, ArrayBuffer, TypedArray
  51. ```js
  52. import { klona } from 'klona';
  53. ```
  54. #### `klona/full`
  55. > **Size (gzip):** 501 bytes<br>
  56. > **Availability:** [CommonJS](https://unpkg.com/klona/full/index.js), [ES Module](https://unpkg.com/klona/full/index.mjs), [UMD](https://unpkg.com/klona/full/index.min.js)<br>
  57. > **Ability:** extends `klona` with support for Symbol properties and and non-enumerable properties
  58. ```js
  59. import { klona } from 'klona/full';
  60. ```
  61. ## Usage
  62. ```js
  63. import { klona } from 'klona';
  64. const input = {
  65. foo: 1,
  66. bar: {
  67. baz: 2,
  68. bat: {
  69. hello: 'world'
  70. }
  71. }
  72. };
  73. const output = klona(input);
  74. // exact copy of original
  75. assert.deepStrictEqual(input, output);
  76. // applying deep updates...
  77. output.bar.bat.hola = 'mundo';
  78. output.bar.baz = 99;
  79. // ...doesn't affect source!
  80. console.log(
  81. JSON.stringify(input, null, 2)
  82. );
  83. // {
  84. // "foo": 1,
  85. // "bar": {
  86. // "baz": 2,
  87. // "bat": {
  88. // "hello": "world"
  89. // }
  90. // }
  91. // }
  92. ```
  93. ## API
  94. ### klona(input)
  95. Returns: `typeof input`
  96. Returns a deep copy/clone of the input.
  97. ## Benchmarks
  98. > Running Node v12.18.3
  99. The benchmarks can be found in the [`/bench`](/bench) directory. They are separated into multiple categories:
  100. * `JSON` – compares an array of objects comprised of JSON data types (`String`, `Number`, `null`, `Array`, `Object`)
  101. * `LITE` – like `JSON`, but adds `RegExp`, `Date` and `undefined` values
  102. * `DEFAULT` – object with `RegExp`, `Date`, `Array`, `Map`, `Set`, custom class, `Int8Array`, `DataView`, `Buffer` values
  103. * `FULL` – like `DEFAULT`, but adds `Symbol` and non-enumerable properties
  104. > **Important:** Only candidates that pass validation step(s) are listed. <br>However, `lodash` and `clone` are kept to highlight important differences.
  105. > **Note:** The `clone/include` candidate refers to its [`includeNonEnumerable` option](https://www.npmjs.com/package/clone#api) enabled.
  106. ```
  107. Load times:
  108. lodash/clonedeep 29.257ms
  109. rfdc 0.511ms
  110. clone 0.576ms
  111. clone-deep 2.494ms
  112. deep-copy 0.451ms
  113. klona/full 0.408ms
  114. klona 0.265ms
  115. klona/lite 0.308ms
  116. klona/json 0.263ms
  117. Benchmark :: JSON
  118. JSON.stringify x 53,899 ops/sec ±0.76% (92 runs sampled)
  119. lodash x 46,800 ops/sec ±0.86% (90 runs sampled)
  120. rfdc x 221,456 ops/sec ±0.88% (92 runs sampled)
  121. clone x 39,537 ops/sec ±0.68% (92 runs sampled)
  122. clone/include x 25,488 ops/sec ±1.06% (88 runs sampled)
  123. clone-deep x 99,998 ops/sec ±0.91% (93 runs sampled)
  124. deep-copy x 141,270 ops/sec ±0.95% (92 runs sampled)
  125. klona/full x 55,016 ops/sec ±0.68% (94 runs sampled)
  126. klona x 281,215 ops/sec ±0.77% (93 runs sampled)
  127. klona/lite x 318,481 ops/sec ±0.72% (91 runs sampled)
  128. klona/json x 334,932 ops/sec ±0.66% (93 runs sampled)
  129. Benchmark :: LITE
  130. lodash x 36,992 ops/sec ±0.65% (91 runs sampled)
  131. clone x 35,974 ops/sec ±1.13% (88 runs sampled)
  132. clone/include x 22,609 ops/sec ±1.02% (91 runs sampled)
  133. clone-deep x 92,846 ops/sec ±0.66% (93 runs sampled)
  134. klona/full x 47,873 ops/sec ±0.83% (88 runs sampled)
  135. klona x 226,638 ops/sec ±1.16% (93 runs sampled)
  136. klona/lite x 257,900 ops/sec ±0.82% (93 runs sampled)
  137. Benchmark :: DEFAULT
  138. lodash x 55,914 ops/sec ±0.75% (93 runs sampled)
  139. ✘ Buffer
  140. ✘ Map keys
  141. clone x 92,127 ops/sec ±0.83% (94 runs sampled)
  142. ✘ DataView
  143. clone/include x 62,052 ops/sec ±0.88% (93 runs sampled)
  144. ✘ DataView
  145. klona/full x 90,308 ops/sec ±0.68% (89 runs sampled)
  146. klona x 230,257 ops/sec ±0.71% (91 runs sampled)
  147. Benchmark :: FULL
  148. lodash x 60,361 ops/sec ±0.65% (91 runs sampled)
  149. ✘ Buffer
  150. ✘ Map keys
  151. ✘ Missing non-enumerable Properties
  152. clone/include x 47,263 ops/sec ±0.85% (93 runs sampled)
  153. ✘ DataView
  154. ✘ Incorrect non-enumerable Properties
  155. klona/full x 82,346 ops/sec ±0.62% (93 runs sampled)
  156. ```
  157. ## Related
  158. * [dlv](https://github.com/developit/dlv) – safely **read** from deep properties in 120 bytes
  159. * [dset](https://github.com/lukeed/dset) – safely **write** into deep properties in 160 bytes
  160. * [dequal](https://github.com/lukeed/dequal) – safely check for deep equality in 304 to 489 bytes
  161. ## License
  162. MIT © [Luke Edwards](https://lukeed.com)