【问题标题】:Why does '(function a() {})' not put 'a' into the global object?为什么 '(function a() {})' 不将 'a' 放入全局对象中?
【发布时间】:2011-10-27 06:13:35
【问题描述】:

answering另一个问题时,我正在使用这种模式递归调用函数:

(function() {
    // ...
    if(should_call_again) arguments.callee();
})();

这很有效。我得到反馈说命名函数也有效:

(function func() {
    // ...
    if(should_call_again) func();
})();

但是,使用这种技术,window.funcundefined,这让我很惊讶。

如果我简单地说,我的问题是:为什么以下是正确的?

function a() {}
typeof window.a; // "function"

(function b() {})
typeof window.b; // "undefined"

b 仍然可以访问 inside b 本身。所以看起来( ) 创建了另一个作用域,但事实并非如此,因为只有函数会创建另一个作用域,而我只是将它包装在( ) 中。

那么为什么在( ) 中包装一个函数不会将函数放入全局对象中呢?

【问题讨论】:

  • 我不知道为什么该函数可以通过其名称访问,但将定义包装在 () 中使其成为函数表达式,即使它们有名称,它也不会在当前范围。
  • 它可能已经过评估,并且由于它没有分配给变量,因此它不会出现在该范围内。
  • 也许在函数调用时创建的激活对象通过其名称引用了函数本身。即使您将函数分配给变量,也可以从函数内部通过其名称访问它。
  • 要解释为什么函数可以在函数内部通过其名称访问,请参阅此答案:stackoverflow.com/questions/7065120/…
  • @Felix Kling:我认为这回答了我的问题。 ... the Identifier in a FunctionExpression cannot be referenced from and does not affect the scope enclosing the FunctionExpression.

标签: javascript function scope window global


【解决方案1】:

因为你写的不是函数声明,而是函数表达式

函数表达式中定义的函数只有在你将它们分配给变量时才会被存储在某个地方;你没有那样做;你只是立即调用它。


在[非常松散!]的意义上,您可以将函数声明视为函数表达式赋值的一种特殊形式:

function a() {}
// vs:
var a = function() {};

这仍然不是一个严格准确的比较,但它可能有助于理解函数声明是一种特殊的东西。

【讨论】:

    【解决方案2】:

    您似乎忽略了一个细微的区别,而不是将函数定义为:

    (function b () { });

    它实际上写成:(注意末尾的额外括号)

    (function b () { }());

    当您编写这样的函数时,它会立即被调用,但仍具有自己的作用域。

    【讨论】:

    • 谢谢。不过,我不确定我是否理解正确。 (function b (){ console.log(1) }); 不记录任何内容。
    猜你喜欢
    • 2021-09-17
    • 2015-05-27
    • 1970-01-01
    • 2011-05-30
    • 1970-01-01
    • 2012-03-31
    • 2011-06-18
    • 2014-03-29
    • 1970-01-01
    相关资源
    最近更新 更多