声明为参数时的函数名称可见性

时间:2014-11-19 07:41:26

标签: javascript

function foo() {
    ui.login.setClose(function closer() {
        ui.hideAll()
        ui.main.show()
    })
    ui.ask.setClose(closer) // <-- closer is not defined
    ui.adduser.setClose(closer)
}

我想知道为什么这不起作用?是不是function关键字应该在当前函数(foo)主体的任何位置创建一个可见的名称?

3 个答案:

答案 0 :(得分:2)

您需要将其声明为函数,而不仅仅是回调函数。

这样的事情:

function foo() {
    function closer() {
        ui.hideAll()
        ui.main.show()
    }
    ui.login.setClose(closer);
    ui.ask.setClose(closer) // <-- closer is not defined
    ui.adduser.setClose(closer)
}

答案 1 :(得分:2)

你所拥有的是一个名为的命名函数表达式。 (不要在IE8或更早版本中使用它们,或者在其他一些相当旧的浏览器中使用它们。)它与函数声明在几个方面不同,其中之一是(在正确的实现上)函数的名称未添加到范围中你创建它。

在该示例中,如果您只希望在foo中访问它,则可能需要在foo内部使用函数声明:

function foo() {
    function closer() {
        ui.hideAll()
        ui.main.show()
    }

    ui.login.setClose(closer);
    ui.ask.setClose(closer);
    ui.adduser.setClose(closer);
}

foo之外的foo,如果您希望它可以在function closer() { ui.hideAll() ui.main.show() } function foo() { ui.login.setClose(closer); ui.ask.setClose(closer); ui.adduser.setClose(closer); } 之外访问:

Function

以下是创建函数的三种主要方法的概述(除了// `foo` is in scope *and* ready to use here, even before the declaration function foo() { // `foo` is in scope and ready here too } // `foo` is in scope and ready here too 构造函数之外,几乎总是应该避免使用):

功能声明

看起来像这样:

foo

特性:

  1. 作为逐步代码的一部分处理;相反,它是在运行范围中的任何分步代码之前创建的。这意味着您可以在上面上面声明的代码中使用上面的if

  2. 由于#1,函数声明不能​​在控制结构中(如switchfor=等),因为当函数将无效时,这是无意义的在逐步执行代码之前创建。 (这很重要,因为不同的浏览器会以不同的方式处理无效的展示位置。)

  3. 将函数的名称放在函数声明出现的范围内。

  4. 该函数有一个真实姓名,该名称在 函数范围内。

  5. 命名函数表达式

    看起来完全相同,只是它写在预期表达式的位置,例如:的右侧(例如,赋值)或// `foo` is *not* in scope here var x = function foo() { // `foo` is in scope here, refers to the function }; var obj = { x: function foo() { // `foo` is in scope here, refers to the function } }; bar(function foo() { // `foo` is in scope here, refers to the function }); // `foo` is *not* in scope here (在属性初始值设定项中)或作为函数的参数:

    x

    特性:

    1. 他们 作为逐步代码的一部分进行处理,就像任何其他表达式一样。

    2. 它们可以在现代浏览器(包括IE9及更高版本)上正常运行,但在IE8及更早版本中使用there are bugs,而其他一些相当老的浏览器也有错误({{ 3}})。

    3. 作为表达式,它们有一个结果:一个函数引用。 (例如,这是分配给bar或传递给上述var x = function() { // ... }; var obj = { x: function() { // ... } }; bar(function() { // ... }); 的内容。)

    4. 他们的名字已添加到他们定义的范围内。

    5. 该函数有一个真实姓名,该名称在 函数范围内(例如,用于递归)。

    6. 匿名函数表达式:

      与命名函数表达式相同,但是,呃,没有名称:

      x

      特性:

      1. 它们作为逐步代码的一部分进行处理,就像任何其他表达式一样。

      2. 它们会产生一个函数引用(例如,分配给bar或传递给x的内容)。

      3. 该函数没有当前规范的名称。但是,下一个规范ES6将通过查看表达式让引擎在可能的情况下推断出函数的名称。例如,在上文中,分配给x的两个名称都为bar;传入{{1}}的那个仍然是匿名的。

答案 2 :(得分:1)

在这种情况下

setClose()

除了函数作为参数,在你的代码中只定义在()内部,因此它不能在setclose()之外使用。如果仅在参数中需要该函数,则通常使用这种定义函数的方式。这就是为什么在这种情况下,原则上你不需要为它指定一个名称:

ui.login.setClose(function() { ui.hideAll(); ui.main.show(); });

但是,在您的情况下,您必须独立于函数setclose()定义函数close():

function closer() {
   ui.hideAll();
   ui.main.show();
}

function foo() {
   ui.login.setClose(closer);
   ui.ask.setClose(closer);
   ui.adduser.setClose(closer);
}

你还错过了一些;结束这条线。