UNPKG

deep-freeze-plus

Version:

An ultra-fast and efficient library for deeply freezing JavaScript objects and preventing unintended mutations. Supports all data types, including complex objects like maps and sets, and guarantees immutability without recursion. Ideal for applications th

61 lines (52 loc) 1.81 kB
function deepFreeze(obj) { const primitives = { Boolean: true, Number: true, String: true, Function: true }; if (Object(obj) !== obj || primitives[obj.constructor.name]) { return obj; } const seenObjects = new WeakSet(); const stack = [{obj, keys: Object.getOwnPropertyNames(obj)}]; const emptyKeys = []; for (let i = 0; i < stack.length; i++) { const {obj, keys} = stack[i]; if (!seenObjects.has(obj)) { if (typeof obj !== 'object' || obj === null) { // skip freezing primitive values } else { Object.freeze(obj); seenObjects.add(obj); } } for (let j = keys.length - 1; j >= 0; j--) { const key = keys[j]; const value = obj[key]; if (value && typeof value === 'object' && !seenObjects.has(value)) { let childKeys = emptyKeys; if (!Object.isFrozen(value)) { childKeys = Object.getOwnPropertyNames(value); if (Array.isArray(value)) { childKeys = childKeys.concat(Object.getOwnPropertyNames(Array.prototype)); } } if (value instanceof Map) { for (const [mapKey, mapValue] of value) { childKeys.push(mapKey); stack.push({obj: mapValue, keys: Object.getOwnPropertyNames(mapValue)}); } } if (value instanceof Set) { for (const setValue of value) { stack.push({obj: setValue, keys: Object.getOwnPropertyNames(setValue)}); } } stack.push({obj: value, keys: childKeys}); } } } return obj; } export default deepFreeze;