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.