A function with nested inner functions and a depth of more than 3 levels is a Nested function.
Impact
- A heavily nested function makes it bulky and complex to read and maintain.
- Time and maintenance cost increases.
- Possibility of duplication of function increases.
Characteristics
- A function has multiple inner functions including anonymous functions and arrow functions.
function genModuleGetter (instanceId) { var instance = instances[instanceId]; return function (name) { var nativeModule = modules[name] || []; var output = {}; var loop = function ( methodName ) { Object.defineProperty(output, methodName, { enumerable: true, configurable: true, get: function proxyGetter () { return function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; return instance.document.taskCenter.send('module', { module: name, method: methodName }, args) } }, set: function proxySetter (val) { if (typeof val === 'function') { return instance.document.taskCenter.send('module', { module: name, method: methodName }, [val]) } } }); }; for (var methodName in nativeModule) loop( methodName ); return output; } }
Solution: Move the logic of inner functions into separate independent functions in the same file.
function genModuleGetter (instanceId) { var instance = instances[instanceId]; return getOutput(name, instance); } function getOutput(name, instance) { var nativeModule = modules[name] || []; var output = {}; var loop = iterate( methodName , output, instance) for (var methodName in nativeModule) loop( methodName ); return output } function iterate(methodName , output, instance) { Object.defineProperty(output, methodName, { enumerable: true, configurable: true, get: proxyGetter (methodName, instance), set: proxySetter (val, methodName, instance) }); } function proxyGetter (methodName, instance) { return function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; return instance.document.taskCenter.send('module', { module: name, method: methodName }, args) } } function proxySetter (val, methodName, instance) { if (typeof val === 'function') { return instance.document.taskCenter.send('module', { module: name, method: methodName }, [val]) } }
Guidelines
- Follow the ‘one function one task’ rule.
- Create separate named functions instead of inner anonymous functions. It makes functions more readable and maintainable.
- Declare functions with the intention of reusing the logic they offer.