当前位置: 首页 > 面试题库 >

返回后定义函数

商开宇
2023-03-14
问题内容

我目前正在阅读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

在调用函数时(例如,在调用时dataService),其中突出显示了函数声明步骤,这是JavaScript引擎的工作:

  1. 设定值 this
  2. env为通话创建一个新环境(我们称之为)
  3. 设置对函数[[Scope]]属性的引用env(这是闭包工作方式的一部分)
  4. 为环境创建一个 绑定对象 (让我们称之为bindings),以容纳函数定义的各种名称(这是闭包如何工作以及变量引用如何解析的另一部分)
  5. 如果函数具有名称,则将其添加bindings为引用该函数的属性
  6. 将形式函数参数添加到 bindings
  7. 处理函数声明,将其名称添加到bindings
  8. 创建arguments对象,将其添加到bindings
  9. 添加与声明的每个变量varbindings(如果尚未定义)与价值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,因此返回的对象是没有用的。



 类似资料:
  • 问题内容: 我有一个计算税金的函数。 我不明白为什么它不能停止递归。 问题答案: 在您的职能部门中: 您没有从函数或设置中返回值。当您不返回任何内容时,返回值为。 也许,您想要这样:

  • 我真的需要温习一下我的异步等待和promise。我想要一些建议。 我正在对firebase firestore进行异步函数调用。函数应根据单个输入参数返回字符串。 该功能适用于1-1用户聊天。该功能是创建聊天/查找现有聊天,并返回其ID。 现在,我得到的作为返回值的和不知道为什么。除了返回之外,该函数还能正常工作。 我有两个功能。一个是React类组件生命周期方法,另一个是我的firebase异步

  • 问题内容: 我正在尝试获取返回值,但始终无法定义。 我不确定如何获取任何返回值并在其他地方使用它?我需要使用此返回值来与其他函数进行验证,但是它似乎在范围之内。 这是我的代码: 问题答案: 移动以下行: 进入回调: 如果希望返回某些内容,则还需要向其添加回调,以便可以使用它的返回值。例如,如果您希望这样做: 这将无法正常工作,因为内容的最终值将被异步检索。相反,您需要这样做: 您不能异步返回数据。

  • 问题内容: 因此,当我打开灯箱时,我试图禁止在页面上滚动,而我发现这个确实有用的脚本非常有用。不幸的是,当我在自己的页面上使用它时,它也禁止在灯箱中滚动。我开始用警报调试代码,只是发现该事件。wheelDelta在我的页面上返回“undefined”,而在JSFiddle中,它返回-120。 问题答案: jQuery事件处理程序中的对象不能反映真实事件。是IE和Opera的非标准事件属性,可通过j

  • 问题内容: 当我警告jsonServerResponse函数返回的值时,尽管从process.php页面返回了JSON,但其值未定义。 我知道问题是异步请求完成之前发出的警报功能,但是我不确定如何解决此问题。任何建议都非常感激:) 问题答案: 好的,我是从其他帖子中弄清楚的。结果可以在成功回调中处理,也可以添加本身是回调函数的参数并将ajax请求的结果应用于回调。 还有gdoron,您所询问的那一