index.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. 'use strict'
  2. module.exports = rfdc
  3. function copyBuffer (cur) {
  4. if (cur instanceof Buffer) {
  5. return Buffer.from(cur)
  6. }
  7. return new cur.constructor(cur.buffer.slice(), cur.byteOffset, cur.length)
  8. }
  9. function rfdc (opts) {
  10. opts = opts || {}
  11. if (opts.circles) return rfdcCircles(opts)
  12. return opts.proto ? cloneProto : clone
  13. function cloneArray (a, fn) {
  14. var keys = Object.keys(a)
  15. var a2 = new Array(keys.length)
  16. for (var i = 0; i < keys.length; i++) {
  17. var k = keys[i]
  18. var cur = a[k]
  19. if (typeof cur !== 'object' || cur === null) {
  20. a2[k] = cur
  21. } else if (cur instanceof Date) {
  22. a2[k] = new Date(cur)
  23. } else if (ArrayBuffer.isView(cur)) {
  24. a2[k] = copyBuffer(cur)
  25. } else {
  26. a2[k] = fn(cur)
  27. }
  28. }
  29. return a2
  30. }
  31. function clone (o) {
  32. if (typeof o !== 'object' || o === null) return o
  33. if (o instanceof Date) return new Date(o)
  34. if (Array.isArray(o)) return cloneArray(o, clone)
  35. if (o instanceof Map) return new Map(cloneArray(Array.from(o), clone))
  36. if (o instanceof Set) return new Set(cloneArray(Array.from(o), clone))
  37. var o2 = {}
  38. for (var k in o) {
  39. if (Object.hasOwnProperty.call(o, k) === false) continue
  40. var cur = o[k]
  41. if (typeof cur !== 'object' || cur === null) {
  42. o2[k] = cur
  43. } else if (cur instanceof Date) {
  44. o2[k] = new Date(cur)
  45. } else if (cur instanceof Map) {
  46. o2[k] = new Map(cloneArray(Array.from(cur), clone))
  47. } else if (cur instanceof Set) {
  48. o2[k] = new Set(cloneArray(Array.from(cur), clone))
  49. } else if (ArrayBuffer.isView(cur)) {
  50. o2[k] = copyBuffer(cur)
  51. } else {
  52. o2[k] = clone(cur)
  53. }
  54. }
  55. return o2
  56. }
  57. function cloneProto (o) {
  58. if (typeof o !== 'object' || o === null) return o
  59. if (o instanceof Date) return new Date(o)
  60. if (Array.isArray(o)) return cloneArray(o, cloneProto)
  61. if (o instanceof Map) return new Map(cloneArray(Array.from(o), cloneProto))
  62. if (o instanceof Set) return new Set(cloneArray(Array.from(o), cloneProto))
  63. var o2 = {}
  64. for (var k in o) {
  65. var cur = o[k]
  66. if (typeof cur !== 'object' || cur === null) {
  67. o2[k] = cur
  68. } else if (cur instanceof Date) {
  69. o2[k] = new Date(cur)
  70. } else if (cur instanceof Map) {
  71. o2[k] = new Map(cloneArray(Array.from(cur), cloneProto))
  72. } else if (cur instanceof Set) {
  73. o2[k] = new Set(cloneArray(Array.from(cur), cloneProto))
  74. } else if (ArrayBuffer.isView(cur)) {
  75. o2[k] = copyBuffer(cur)
  76. } else {
  77. o2[k] = cloneProto(cur)
  78. }
  79. }
  80. return o2
  81. }
  82. }
  83. function rfdcCircles (opts) {
  84. var refs = []
  85. var refsNew = []
  86. return opts.proto ? cloneProto : clone
  87. function cloneArray (a, fn) {
  88. var keys = Object.keys(a)
  89. var a2 = new Array(keys.length)
  90. for (var i = 0; i < keys.length; i++) {
  91. var k = keys[i]
  92. var cur = a[k]
  93. if (typeof cur !== 'object' || cur === null) {
  94. a2[k] = cur
  95. } else if (cur instanceof Date) {
  96. a2[k] = new Date(cur)
  97. } else if (ArrayBuffer.isView(cur)) {
  98. a2[k] = copyBuffer(cur)
  99. } else {
  100. var index = refs.indexOf(cur)
  101. if (index !== -1) {
  102. a2[k] = refsNew[index]
  103. } else {
  104. a2[k] = fn(cur)
  105. }
  106. }
  107. }
  108. return a2
  109. }
  110. function clone (o) {
  111. if (typeof o !== 'object' || o === null) return o
  112. if (o instanceof Date) return new Date(o)
  113. if (Array.isArray(o)) return cloneArray(o, clone)
  114. if (o instanceof Map) return new Map(cloneArray(Array.from(o), clone))
  115. if (o instanceof Set) return new Set(cloneArray(Array.from(o), clone))
  116. var o2 = {}
  117. refs.push(o)
  118. refsNew.push(o2)
  119. for (var k in o) {
  120. if (Object.hasOwnProperty.call(o, k) === false) continue
  121. var cur = o[k]
  122. if (typeof cur !== 'object' || cur === null) {
  123. o2[k] = cur
  124. } else if (cur instanceof Date) {
  125. o2[k] = new Date(cur)
  126. } else if (cur instanceof Map) {
  127. o2[k] = new Map(cloneArray(Array.from(cur), clone))
  128. } else if (cur instanceof Set) {
  129. o2[k] = new Set(cloneArray(Array.from(cur), clone))
  130. } else if (ArrayBuffer.isView(cur)) {
  131. o2[k] = copyBuffer(cur)
  132. } else {
  133. var i = refs.indexOf(cur)
  134. if (i !== -1) {
  135. o2[k] = refsNew[i]
  136. } else {
  137. o2[k] = clone(cur)
  138. }
  139. }
  140. }
  141. refs.pop()
  142. refsNew.pop()
  143. return o2
  144. }
  145. function cloneProto (o) {
  146. if (typeof o !== 'object' || o === null) return o
  147. if (o instanceof Date) return new Date(o)
  148. if (Array.isArray(o)) return cloneArray(o, cloneProto)
  149. if (o instanceof Map) return new Map(cloneArray(Array.from(o), cloneProto))
  150. if (o instanceof Set) return new Set(cloneArray(Array.from(o), cloneProto))
  151. var o2 = {}
  152. refs.push(o)
  153. refsNew.push(o2)
  154. for (var k in o) {
  155. var cur = o[k]
  156. if (typeof cur !== 'object' || cur === null) {
  157. o2[k] = cur
  158. } else if (cur instanceof Date) {
  159. o2[k] = new Date(cur)
  160. } else if (cur instanceof Map) {
  161. o2[k] = new Map(cloneArray(Array.from(cur), cloneProto))
  162. } else if (cur instanceof Set) {
  163. o2[k] = new Set(cloneArray(Array.from(cur), cloneProto))
  164. } else if (ArrayBuffer.isView(cur)) {
  165. o2[k] = copyBuffer(cur)
  166. } else {
  167. var i = refs.indexOf(cur)
  168. if (i !== -1) {
  169. o2[k] = refsNew[i]
  170. } else {
  171. o2[k] = cloneProto(cur)
  172. }
  173. }
  174. }
  175. refs.pop()
  176. refsNew.pop()
  177. return o2
  178. }
  179. }