1 | var clone = (function() {
|
2 | 'use strict';
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 | function clone(parent, circular, depth, prototype) {
|
23 | var filter;
|
24 | if (typeof circular === 'object') {
|
25 | depth = circular.depth;
|
26 | prototype = circular.prototype;
|
27 | filter = circular.filter;
|
28 | circular = circular.circular
|
29 | }
|
30 |
|
31 |
|
32 | var allParents = [];
|
33 | var allChildren = [];
|
34 |
|
35 | var useBuffer = typeof Buffer != 'undefined';
|
36 |
|
37 | if (typeof circular == 'undefined')
|
38 | circular = true;
|
39 |
|
40 | if (typeof depth == 'undefined')
|
41 | depth = Infinity;
|
42 |
|
43 |
|
44 | function _clone(parent, depth) {
|
45 |
|
46 | if (parent === null)
|
47 | return null;
|
48 |
|
49 | if (depth == 0)
|
50 | return parent;
|
51 |
|
52 | var child;
|
53 | var proto;
|
54 | if (typeof parent != 'object') {
|
55 | return parent;
|
56 | }
|
57 |
|
58 | if (clone.__isArray(parent)) {
|
59 | child = [];
|
60 | } else if (clone.__isRegExp(parent)) {
|
61 | child = new RegExp(parent.source, __getRegExpFlags(parent));
|
62 | if (parent.lastIndex) child.lastIndex = parent.lastIndex;
|
63 | } else if (clone.__isDate(parent)) {
|
64 | child = new Date(parent.getTime());
|
65 | } else if (useBuffer && Buffer.isBuffer(parent)) {
|
66 | if (Buffer.allocUnsafe) {
|
67 |
|
68 | child = Buffer.allocUnsafe(parent.length);
|
69 | } else {
|
70 |
|
71 | child = new Buffer(parent.length);
|
72 | }
|
73 | parent.copy(child);
|
74 | return child;
|
75 | } else {
|
76 | if (typeof prototype == 'undefined') {
|
77 | proto = Object.getPrototypeOf(parent);
|
78 | child = Object.create(proto);
|
79 | }
|
80 | else {
|
81 | child = Object.create(prototype);
|
82 | proto = prototype;
|
83 | }
|
84 | }
|
85 |
|
86 | if (circular) {
|
87 | var index = allParents.indexOf(parent);
|
88 |
|
89 | if (index != -1) {
|
90 | return allChildren[index];
|
91 | }
|
92 | allParents.push(parent);
|
93 | allChildren.push(child);
|
94 | }
|
95 |
|
96 | for (var i in parent) {
|
97 | var attrs;
|
98 | if (proto) {
|
99 | attrs = Object.getOwnPropertyDescriptor(proto, i);
|
100 | }
|
101 |
|
102 | if (attrs && attrs.set == null) {
|
103 | continue;
|
104 | }
|
105 | child[i] = _clone(parent[i], depth - 1);
|
106 | }
|
107 |
|
108 | return child;
|
109 | }
|
110 |
|
111 | return _clone(parent, depth);
|
112 | }
|
113 |
|
114 |
|
115 |
|
116 |
|
117 |
|
118 |
|
119 |
|
120 |
|
121 | clone.clonePrototype = function clonePrototype(parent) {
|
122 | if (parent === null)
|
123 | return null;
|
124 |
|
125 | var c = function () {};
|
126 | c.prototype = parent;
|
127 | return new c();
|
128 | };
|
129 |
|
130 |
|
131 |
|
132 | function __objToStr(o) {
|
133 | return Object.prototype.toString.call(o);
|
134 | };
|
135 | clone.__objToStr = __objToStr;
|
136 |
|
137 | function __isDate(o) {
|
138 | return typeof o === 'object' && __objToStr(o) === '[object Date]';
|
139 | };
|
140 | clone.__isDate = __isDate;
|
141 |
|
142 | function __isArray(o) {
|
143 | return typeof o === 'object' && __objToStr(o) === '[object Array]';
|
144 | };
|
145 | clone.__isArray = __isArray;
|
146 |
|
147 | function __isRegExp(o) {
|
148 | return typeof o === 'object' && __objToStr(o) === '[object RegExp]';
|
149 | };
|
150 | clone.__isRegExp = __isRegExp;
|
151 |
|
152 | function __getRegExpFlags(re) {
|
153 | var flags = '';
|
154 | if (re.global) flags += 'g';
|
155 | if (re.ignoreCase) flags += 'i';
|
156 | if (re.multiline) flags += 'm';
|
157 | return flags;
|
158 | };
|
159 | clone.__getRegExpFlags = __getRegExpFlags;
|
160 |
|
161 | return clone;
|
162 | })();
|
163 |
|
164 | if (typeof module === 'object' && module.exports) {
|
165 | module.exports = clone;
|
166 | }
|