source: node_modules/es-toolkit/dist/compat/object/clone.mjs

Last change on this file was a762898, checked in by istevanoska <ilinastevanoska@…>, 5 months ago

Added visualizations

  • Property mode set to 100644
File size: 4.9 KB
Line 
1import { isPrimitive } from '../../predicate/isPrimitive.mjs';
2import { getTag } from '../_internal/getTag.mjs';
3import { arrayBufferTag, dataViewTag, booleanTag, numberTag, stringTag, dateTag, regexpTag, symbolTag, mapTag, setTag, argumentsTag, uint32ArrayTag, uint16ArrayTag, uint8ClampedArrayTag, uint8ArrayTag, objectTag, int32ArrayTag, int16ArrayTag, int8ArrayTag, float64ArrayTag, float32ArrayTag, arrayTag } from '../_internal/tags.mjs';
4import { isArray } from '../predicate/isArray.mjs';
5import { isTypedArray } from '../predicate/isTypedArray.mjs';
6
7function clone(obj) {
8 if (isPrimitive(obj)) {
9 return obj;
10 }
11 const tag = getTag(obj);
12 if (!isCloneableObject(obj)) {
13 return {};
14 }
15 if (isArray(obj)) {
16 const result = Array.from(obj);
17 if (obj.length > 0 && typeof obj[0] === 'string' && Object.hasOwn(obj, 'index')) {
18 result.index = obj.index;
19 result.input = obj.input;
20 }
21 return result;
22 }
23 if (isTypedArray(obj)) {
24 const typedArray = obj;
25 const Ctor = typedArray.constructor;
26 return new Ctor(typedArray.buffer, typedArray.byteOffset, typedArray.length);
27 }
28 if (tag === arrayBufferTag) {
29 return new ArrayBuffer(obj.byteLength);
30 }
31 if (tag === dataViewTag) {
32 const dataView = obj;
33 const buffer = dataView.buffer;
34 const byteOffset = dataView.byteOffset;
35 const byteLength = dataView.byteLength;
36 const clonedBuffer = new ArrayBuffer(byteLength);
37 const srcView = new Uint8Array(buffer, byteOffset, byteLength);
38 const destView = new Uint8Array(clonedBuffer);
39 destView.set(srcView);
40 return new DataView(clonedBuffer);
41 }
42 if (tag === booleanTag || tag === numberTag || tag === stringTag) {
43 const Ctor = obj.constructor;
44 const clone = new Ctor(obj.valueOf());
45 if (tag === stringTag) {
46 cloneStringObjectProperties(clone, obj);
47 }
48 else {
49 copyOwnProperties(clone, obj);
50 }
51 return clone;
52 }
53 if (tag === dateTag) {
54 return new Date(Number(obj));
55 }
56 if (tag === regexpTag) {
57 const regExp = obj;
58 const clone = new RegExp(regExp.source, regExp.flags);
59 clone.lastIndex = regExp.lastIndex;
60 return clone;
61 }
62 if (tag === symbolTag) {
63 return Object(Symbol.prototype.valueOf.call(obj));
64 }
65 if (tag === mapTag) {
66 const map = obj;
67 const result = new Map();
68 map.forEach((obj, key) => {
69 result.set(key, obj);
70 });
71 return result;
72 }
73 if (tag === setTag) {
74 const set = obj;
75 const result = new Set();
76 set.forEach(obj => {
77 result.add(obj);
78 });
79 return result;
80 }
81 if (tag === argumentsTag) {
82 const args = obj;
83 const result = {};
84 copyOwnProperties(result, args);
85 result.length = args.length;
86 result[Symbol.iterator] = args[Symbol.iterator];
87 return result;
88 }
89 const result = {};
90 copyPrototype(result, obj);
91 copyOwnProperties(result, obj);
92 copySymbolProperties(result, obj);
93 return result;
94}
95function isCloneableObject(object) {
96 switch (getTag(object)) {
97 case argumentsTag:
98 case arrayTag:
99 case arrayBufferTag:
100 case dataViewTag:
101 case booleanTag:
102 case dateTag:
103 case float32ArrayTag:
104 case float64ArrayTag:
105 case int8ArrayTag:
106 case int16ArrayTag:
107 case int32ArrayTag:
108 case mapTag:
109 case numberTag:
110 case objectTag:
111 case regexpTag:
112 case setTag:
113 case stringTag:
114 case symbolTag:
115 case uint8ArrayTag:
116 case uint8ClampedArrayTag:
117 case uint16ArrayTag:
118 case uint32ArrayTag: {
119 return true;
120 }
121 default: {
122 return false;
123 }
124 }
125}
126function copyOwnProperties(target, source) {
127 for (const key in source) {
128 if (Object.hasOwn(source, key)) {
129 target[key] = source[key];
130 }
131 }
132}
133function copySymbolProperties(target, source) {
134 const symbols = Object.getOwnPropertySymbols(source);
135 for (let i = 0; i < symbols.length; i++) {
136 const symbol = symbols[i];
137 if (Object.prototype.propertyIsEnumerable.call(source, symbol)) {
138 target[symbol] = source[symbol];
139 }
140 }
141}
142function cloneStringObjectProperties(target, source) {
143 const stringLength = source.valueOf().length;
144 for (const key in source) {
145 if (Object.hasOwn(source, key) && (Number.isNaN(Number(key)) || Number(key) >= stringLength)) {
146 target[key] = source[key];
147 }
148 }
149}
150function copyPrototype(target, source) {
151 const proto = Object.getPrototypeOf(source);
152 if (proto !== null) {
153 const Ctor = source.constructor;
154 if (typeof Ctor === 'function') {
155 Object.setPrototypeOf(target, proto);
156 }
157 }
158}
159
160export { clone };
Note: See TracBrowser for help on using the repository browser.