Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Whats the need and use of nested functions in JavaScript

I understand what a nested function is, but I don't understand why we even need nested functions in the first place. Is there a problem that can only be solved by using nested functions in JavaScript. All the examples I see which create nested function, can be coded without creating a function inside a function and will result the same. So which problem requires creation of nested functions, and can only/efficiently be solved by using nested functions.

like image 712
Mahtab Alam Avatar asked Jun 11 '17 10:06

Mahtab Alam


3 Answers

The core importance of nested functions is scope generation. We need nested functions and scopes in JavaScript to achieve the following.

  1. Non-Polluted Global Namespace
  2. Modularization of functionality
  3. Encapsulate private internal workings of modules
  4. Prevent collision of identifiers across different scripts
  5. Smaller script sizes due to the fact that variables inside nested scopes qualify for minification.
  6. It speeds up the Identifier Resolution Process

Here is a sample module that displays the power of encapsulation offered by function nesting and scopes:

var notificationService = (function ($, toastr, undefined) {
    var _externals = {},
        _jqExtend = $.extend;

    /*
     * Private Methods
     */
    function _showMessage(params) {
        params = params || {};
        toastr.remove();

        if (typeof (params.title) === "undefined")
            toastr[params.method](params.msg);
        else
            toastr[params.method](params.msg, params.title);
    }

    /*
     * Public Members
     */
    _externals.clear = function () {
        toastr.remove();
    };

    _externals.showError = function (params) {
        params = params || {};

        _jqExtend(params, {
            method: "error"
        });

        _showMessage(params);
    };

    _externals.showInfo = function (params) {
        params = params || {};

        _jqExtend(params, {
            method: "info"
        });

        _showMessage(params);
    };

    _externals.showSuccess = function (params) {
        params = params || {};

        _jqExtend(params, {
            method: "success"
        });

        _showMessage(params);
    };

    _externals.showWarning = function (params) {
        params = params || {};

        _jqExtend(params, {
            method: "warning"
        });

        _showMessage(params);
    };

    return _externals;
})(jQuery, toastr);

The code above gives us the power to control which things to expose. In this specific case all members attached to the _externals object are exposed to the global namespace via reference to notificationService object. Without using scoping, internal members (_jqExtend and _showMessage) would also be attached to the window object and increase the effort required by the browser to resolve identifier references.

like image 113
Allan Chua Avatar answered Nov 01 '22 12:11

Allan Chua


It's not about efficiency but about the paradigm. If you use the script paradigm you can just code away without worries. If you use the classical paradigm, you need to define classes but you don't need nested functions. Still, in scripting and classical, you MAY use nested functions if you want to.

Only if you switch to the functional paradigm, which is the actual "native" paradigm of javascript, you NEED nested functions in some cases.

As long as you do not use functional programming you'll not leverage all the power of javascript. This is an example of a factory that uses a closure that cannot be done otherwise (there are several other uses for nested functions, not just a closure):

function create(a, b)
{
  function compute()
  {
    return a + b;
  }

  return {
    "compute": compute
  };
}

The user code will do:

f = create(19, 73);

Without computing anything. Say, it takes a lot of time to compute this and you don't want to compute it unless necessary. You can now pass the function f to other code that is not yours (e.G. jQuery event handler code):

$("#id").on("click", function () { console.log(f.compute()); });

This f will be executed when you click on #id, but you cannot do anything about it. The arguments a and b are already embedded when create() was called.

This means that you can have information hiding and leverage contextual scoping. Imagine that the creator and the user are two different codebases not written by the same person. Or that a and b are secrets to be kept as such from the other codebase.

Look up the various words I sprinkled in the text above to learn more about functional programming.

If you want to know why we can't do without, then look at currying and monads, which are a fundamental parts of the functional paradigm. You need some mechanisms by which you can do these basic operations, otherwise the paradigm cannot be functional.

like image 34
pid Avatar answered Nov 01 '22 13:11

pid


JavaScript variables can belong to the local or global scope.

Global variables can be made local (private) with closures.

functions in JS are like variables, so if may want to use nested functions to be for local use.

Here's a good example

like image 44
Daniel Taub Avatar answered Nov 01 '22 13:11

Daniel Taub