【问题标题】:Whats the need and use of nested functions in JavaScriptJavaScript 中嵌套函数的需求和用途是什么
【发布时间】:2017-11-12 22:31:27
【问题描述】:

我了解嵌套函数是什么,但我不明白为什么我们首先需要嵌套函数。有没有只能通过在 JavaScript 中使用嵌套函数来解决的问题。我看到的所有创建嵌套函数的示例都可以在不在函数内部创建函数的情况下进行编码,并且结果相同。那么哪个问题需要创建嵌套函数,并且只能/有效地通过使用嵌套函数来解决。

【问题讨论】:

  • @FabianLauer 我在等着有人说嵌套函数只在创建闭包时才有用。
  • 隐私只能通过嵌套函数来实现,大多数模块系统也依赖于闭包,以免污染全局命名空间。如果没有闭包,您要么必须在全局命名空间中的某处注册所有内容,其他所有脚本都可以访问和修改它,或者您必须将内部状态之类的东西作为参数传递给该类的每个公共函数。所以基本上你没有任何内部状态了,只有公共状态。

标签: javascript nested-function


【解决方案1】:

这不是关于效率,而是关于范式。如果您使用脚本范例,您可以无需担心地编写代码。如果使用经典范式,则需要定义类但不需要嵌套函数。尽管如此,在脚本和经典中,如果您愿意,您可以使用嵌套函数。

只有当你切换到函数式范式,也就是真正的 JavaScript 的“原生”范式时,在某些情况下你需要嵌套函数。

只要您不使用函数式编程,您就无法充分利用 javascript 的所有功能。这是一个使用 闭包 的工厂示例,否则无法完成(嵌套函数还有其他几种用途,而不仅仅是闭包):

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

  return {
    "compute": compute
  };
}

用户代码会这样做:

f = create(19, 73);

无需计算任何东西。比如说,计算它需要很多时间,除非必要,否则你不想计算它。您现在可以将函数 f 传递给不属于您的其他代码(例如 jQuery 事件处理程序代码):

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

当您单击#id 时,此f 将被执行,但您无能为力。在调用create() 时,参数ab 已经嵌入。

这意味着您可以隐藏信息并利用上下文范围。想象一下,creatoruser 是两个不同的代码库,不是由同一个人编写的。或者 ab 是其他代码库的机密。

查看我在上面的文字中散布的各种单词,以了解有关函数式编程的更多信息。

如果您想知道为什么我们不能没有,请查看 curryingmonads,它们是函数式范例的基本组成部分。您需要一些机制来执行这些基本操作,否则范式将无法正常运行。

【讨论】:

    【解决方案2】:

    嵌套函数的核心重要性是作用域生成。我们需要在 JavaScript 中嵌套函数和作用域来实现以下目标。

    1. Non-Polluted Global Namespace
    2. Modularization 的功能
    3. 封装modules的私有内部工作
    4. 防止标识符在不同脚本之间发生冲突
    5. 由于嵌套范围内的变量符合minification 的条件,因此脚本大小更小。
    6. 它加快了Identifier Resolution Process

    这是一个示例模块,展示了函数嵌套和作用域提供的封装功能:

    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);
    

    上面的代码让我们能够控制要公开哪些内容。在这种特定情况下,所有附加到 _externals 对象的成员都通过对 notificationService 对象的引用暴露给全局命名空间。如果不使用范围,内部成员(_jqExtend 和 _showMessage)也将附加到窗口对象,并增加浏览器解析标识符引用所需的工作量。

    【讨论】:

      【解决方案3】:

      首先,在编程中,做一个任务的方法有很多种,但是其中我们要选择一种在内存和执行时间上效率更高,速度更快的方法。当你需要从主程序切换到子程序时如果子程序的大小更小,那么上下文切换的时间不仅仅是执行内联任务。所以总的来说,如果大小更小,否则你总是有备用路径。嵌套函数也可以访问“上面”的范围它们。它将减少将参数传递给函数并在程序中的其他地方重用它的麻烦。所有上述变量和函数都可以访问这个嵌套函数并可以更新它们。..

      【讨论】:

        【解决方案4】:

        JavaScript 变量可以属于本地或全局范围。

        可以使用闭包将全局变量设为本地(私有)。

        JS 中的函数就像变量一样,所以如果想使用嵌套函数供本地使用。

        这是一个很好的example

        【讨论】:

          猜你喜欢
          • 2019-07-24
          • 2016-01-03
          • 1970-01-01
          • 2021-03-31
          • 2013-06-11
          • 2018-01-06
          • 1970-01-01
          • 1970-01-01
          • 2018-12-13
          相关资源
          最近更新 更多