Last active
October 5, 2025 12:56
-
-
Save KosarevDmitry/89ccf615cc795612f5c7716756f2082f to your computer and use it in GitHub Desktop.
Serialize prototype chain
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| import {serializePrototypeChain} from "./serializePrototypeChain.js"; | |
| function Baz(){} | |
| let obj = serializePrototypeChain(Baz); | |
| let str = JSON.stringify(obj); | |
| debugger | |
| */ | |
| // serializePrototypeChain.js | |
| export function serializePrototypeChain(obj) { | |
| const serializedChain = []; | |
| let current = obj; | |
| // Keep track of seen objects to handle circular references | |
| const seenObjects = new WeakSet(); | |
| while (current) { | |
| if (seenObjects.has(current)) { | |
| // Handle circular reference: e.g., store a reference ID or skip | |
| serializedChain.push({ __circularRef: true }); | |
| break; | |
| } | |
| // add to weaklist | |
| seenObjects.add(current); | |
| // object | |
| const levelData = { | |
| // ctor is not part of properties, so it need to fix separately | |
| constructorName: current.constructor ? current.constructor.name : 'Object', | |
| properties: {}, | |
| }; | |
| // Get all own property names (enumerable and non-enumerable) | |
| const propertyNames = Object.getOwnPropertyNames(current); | |
| for (const name of propertyNames) { | |
| try { | |
| // receive descriptors | |
| const descriptor = Object.getOwnPropertyDescriptor(current, name); | |
| if (descriptor) { | |
| // Serialize value based on type (handle functions, objects, etc.) | |
| if (typeof descriptor.value === 'function') { | |
| // it returns out that if this is a property so we save it without calling recursion | |
| levelData.properties[name] = `[Function: ${name}]`; // Represent functions | |
| } else if (typeof descriptor.value === 'object' && descriptor.value !== null) { | |
| // Recursively serialize nested objects or store a reference | |
| levelData.properties[name] = serializePrototypeChain(descriptor.value); | |
| } else { | |
| // case if it is not an object or a function | |
| levelData.properties[name] = descriptor.value; | |
| } | |
| } | |
| } catch (e) { | |
| // Handle cases where property access might throw errors (e.g., security restrictions) | |
| levelData.properties[name] = `[Error: ${e.message}]`; | |
| } | |
| } | |
| serializedChain.push(levelData); // outer as regard to recursion | |
| current = Object.getPrototypeOf(current); | |
| } | |
| return serializedChain; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment