Keywords: JavaScript | Object Flattening | Performance Optimization
Abstract: This paper comprehensively examines the flattening and unflattening operations of nested JavaScript objects, proposing an efficient algorithm based on regular expression parsing. By analyzing performance bottlenecks of traditional recursive methods and introducing path parsing optimization strategies, it significantly improves execution efficiency while maintaining functional integrity. Detailed explanations cover core algorithm logic, performance comparison data, and security considerations, providing reliable solutions for handling complex data structures.
Problem Background and Performance Requirements
In modern web development, handling complex nested JavaScript objects is a common requirement. Flattening operations convert multi-layer nested structures into single-layer key-value pairs, facilitating serialization, transmission, or modification; unflattening restores the original nested structure. However, traditional recursive methods perform poorly with deep nesting or large-scale data, potentially triggering browser "long script" warnings.
Core Algorithm Design Principles
The key to efficient algorithms lies in optimizing the path parsing process. Traditional methods use string splitting operations, while improved solutions employ regular expression matching to significantly reduce operational steps. The regular expression /\.?([^.\[\]]+)|\[(\d+)\]/g is specifically designed to parse composite paths containing dot separators and array indices.
The flattening process adopts a depth-first traversal strategy:
Object.flatten = function(data) {
var result = {};
function recurse (cur, prop) {
if (Object(cur) !== cur) {
result[prop] = cur;
} else if (Array.isArray(cur)) {
for(var i=0, l=cur.length; i<l; i++)
recurse(cur[i], prop + "[" + i + "]");
if (l == 0)
result[prop] = [];
} else {
var isEmpty = true;
for (var p in cur) {
isEmpty = false;
recurse(cur[p], prop ? prop+"."+p : p);
}
if (isEmpty && prop)
result[prop] = {};
}
}
recurse(data, "");
return result;
}
The unflattening process utilizes loop-based path component parsing:
Object.unflatten = function(data) {
"use strict";
if (Object(data) !== data || Array.isArray(data))
return data;
var regex = /\.?([^.\[\]]+)|\[(\d+)\]/g,
resultholder = {};
for (var p in data) {
var cur = resultholder,
prop = "",
m;
while (m = regex.exec(p)) {
cur = cur[prop] || (cur[prop] = (m[2] ? [] : {}));
prop = m[2] || m[1];
}
cur[prop] = data[p];
}
return resultholder[""] || resultholder;
};
Performance Optimization Analysis
Benchmark tests verify significant performance improvements in mainstream browsers: Opera 12.16 reduced from ~1900ms to 900ms, Chrome 29 from ~1600ms to 800ms. Performance gains primarily stem from:
- Using regular expressions instead of multiple string operations
- Avoiding unnecessary object copying and memory allocation
- Optimizing loop structures and conditional judgment logic
Security Considerations
This algorithm focuses on performance optimization but carries prototype pollution security risks. When processing input data from untrusted sources, maliciously constructed key names may modify the object prototype chain, creating security vulnerabilities. Production environments should incorporate input validation or use specialized security libraries.
Application Scenarios and Extensions
The algorithm applies to: data serialization, configuration management, state persistence, and other scenarios. Functionality can be extended based on specific requirements, such as supporting custom delimiters, handling circular references, or adding type validation. The algorithm design maintains good extensibility for future enhancements.