繁体   English   中英

返回后定义函数

[英]Defining functions after return

我正在阅读John Papa的AngularJS风格指南,并看到了代码

function dataService() {
    var someValue = '';
    var service = {
        save: save,
        someValue: someValue,
        validate: validate
    };
    return service;

    ////////////

    function save() {
        /* */
    };

    function validate() {
        /* */
    };
}

您可以看到函数savevalidate函数返回值定义的。 这是如何运作的? 它是否符合标准并适用于所有浏览器(例如,来自IE 6)?

您可以看到函数savevalidate是在函数返回值后定义的。

这就是从它们写入的地方看起来的样子,是的,但实际上它们是在函数中的任何分步代码运行之前定义的。 有时这被称为“提升”声明到函数的顶部(类似的情况也发生在var ;更多下面)。

当控件进入执行上下文时(例如,当您输入函数时,在程序开头输入全局环境,或输入eval代码), 在执行任何分步代码之前发生的几件事之一是处理该上下文中的所有函数声明并创建这些函数。 由于savevalidate是由函数声明定义的,因此它们是在代码的第一个逐步行之前创建的,因此它们在return之后并不重要。

以下是JavaScript引擎在调用函数时所执行的操作(例如,在调用dataService ),并突出显示了函数声明步骤:

  1. 设置的值, this
  2. 为呼叫创建一个新环境(让我们称之为env
  3. env上设置对函数[[Scope]]属性的引用(这是闭包工作方式的一部分)
  4. 为环境创建一个绑定对象 (让我们称之为bindings )来保存我们由函数定义的各种名称(这是闭包如何工作的另一部分,以及如何解析变量引用)
  5. 如果函数具有名称,请将其作为引用该函数的属性添加到bindings
  6. 将正式函数参数添加到bindings
  7. 处理函数声明,将其名称添加到bindings
  8. 创建arguments对象,将其添加到bindings
  9. 将使用var声明的每个变量添加到bindings (如果尚未定义),并使用值undefined
  10. 处理函数中的逐步代码
  11. 设置调用表达式的结果

这在§10.4.1中的规范及其链接的部分中以极其详细的方式列出 (如果你去阅读那个,自我鼓励,散文就是......不稳定......)这是当前规范的一个链接,但这在1999年旧版第三版规范的§10中也有明确规定,而且我很确定从一开始就是如此。

它是否符合标准并适用于所有浏览器(例如,来自IE 6)?

是。 它曾经让我感到紧张,所以几年前(可能〜2005年)我在我能找到的所有当时和非常死的浏览器(包括IE6)上证明了这一点,并且它得到了普遍正确的处理。 这实际上并不令人惊讶,因为它是使这段代码工作的原因:

doSomething();

function doSomething() {
    // ....
}

......人们这样做, 所有的时间


这种“提升”是函数声明和函数表达式之间的关键差异之一。 如果savevalidate是由函数表达式创建的,那么return后写入它们会很重要 - 它们永远不会被创建:

// It wouldn't work like this, for instance
function dataService() {
    var someValue = '';
    var service = {
        save: save,             // `save` has the value `undefined` at this point
        someValue: someValue,
        validate: validate      // So does `validate`
    };
    return service;

    ////////////

    var save = function() {      // Now this is a function expression
        /* */
    };

    var validate = function() {  // This too
        /* */
    };
}

将创建savevalidate变量(由于上面的步骤9),但是在使用它们的地方,它们的值undefined ,因此返回的对象将没有用处。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM