JavaScript对象字面量和自执行函数

6

我正在学习JavaScript中的对象字面量和自执行函数。在查看一些YUI代码时,我发现了一个对象字面量的一些方法会自行执行。我的问题是为什么以下代码不会弹出“Ohai Mark!”的提示框:

var bar = {
    alert: function () {
        window.alert('Ohai Mark!');
    },
    init: (function () {
        bar.alert();
    }())
};
2个回答

9
详细解释如下:
> var bar = {

在JavaScript中,声明会先被处理,因此在执行开始之前 bar 已经存在作为一个变量。
>     alert: function () {
>         window.alert('Ohai Mark!');
>     },
>     init: (function () {
>         bar.alert();
>     }())

bar将在右侧表达式被评估后被赋值。在该评估过程中,bar具有语句(整行)到达时的任何值。它目前为undefined,因此尚未具有alert属性。

> };

1
啊,谢谢。所以我想更好的方法是消除自调用方法,只需在赋值后加上bar.init()这一行?你会怎么做呢?我看到另一个问题建议做类似于var bar = (function () { function alert() { alert('hi'); } return {alert: alert}}()) 然后像这样简单地调用alert bar.alert()。你认为这是更好的方法吗? - dunnza
Zach,这是一个很好的方法来正确地定义函数作用域。这样,每个函数都可以在“bar”命名空间中定义作用域,这进一步允许您拥有私有/公共函数。加油! - hayesgm

3
在执行代码时,“bar”已被定义,但在init()方法被定义(并将被分配给bar对象)之前尚未分配生成的JSON对象。由于init的函数作用域已正确定义,建议在那里声明该函数,如下所示:[编辑]
var bar = {
  init: (function () {
      var alert = function () {
        window.alert('Ohai Mark!');
      };

      alert(); //this will execute the code above
  }())
};

请参见Javascript Garden#命名空间和作用域[编辑] 你可能会认为这类似于:
(function() {
  var c = c + 1;
})();

1
+1,但更正确的说法是,在运行任何代码之前,bar已经被定义,但在函数被调用时,具有属性alert的对象尚未被分配。 - RobG
哇,太棒了,你让这个问题难以解释。非常感谢您提供更进一步的反馈(请参见编辑)。 - hayesgm
我会这样解释:在 RHS 表达式(不是“JSON 对象”)评估之前,bar 尚未被赋值,因此在表达式评估期间调用 *bar.alert()*(即在它存在之前)会导致错误。 - RobG
所引用的文章有很多错误,不应该提供给没有 JavaScript 或 ECMAScript 经验的人。 - RobG
页面上没有发送评论的链接,例如:所有内容都在一个全局共享命名空间中定义忽略了函数作用域。A在全局作用域中定义了一个名为foo的变量不是这样的,在该示例中,foo将在代码执行时作为全局对象的属性创建。对“提升”的解释很差,没有提到变量实例化阶段(它应该),因此将“提升”与作用域(不同的概念)混淆。还有许多其他问题-总体趋势是可以的,但存在许多非正式错误。 - RobG
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接