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