如何在JavaScript中返回对象字面量

3
我正在尝试将一个JavaScript对象字面量包装在一个自执行的匿名函数中。下面的第一个代码示例运行正常,但第二个却不行,我真的不知道为什么? < p > < em > 工作: < / em > < / p >
(function(){
    return MyApp = {
        init: function() {
            console.log('MyApp init');
        }
    }
})();

无法工作:

(function(){
    var MyApp = {
        init: function() {
            console.log('MyApp init');
        }
    }
    return MyApp;
})();

据我所知,SEAF应该执行并立即返回。这就是为什么第一个示例返回一个可以与之交互的MyApp对象。我原以为在SEAF内部将MyApp分配给一个变量,然后返回它会做同样的事情,但是却出现了未捕获的引用错误“MyApp未定义”。为什么?

2
在你的第一个例子中,你将结果分配给了名为'MyApp'的全局变量。而在第二种情况下,你将变量分配给了闭包局部变量'MyApp'。你必须在某个地方分配闭包执行的结果,否则它会丢失。 - Mike Edwards
2
假设你捕获了返回值,你的代码运行得非常好 - zzzzBov
正如zzzzBov所指出的那样,如果您将var someName = (theClosureExecution)放入其中,它就可以正常工作。 - Mike Edwards
什么是“SEAF”? “IIFE”是什么? - Peter Mortensen
好的,SEAF 可能是自执行匿名函数。 - Peter Mortensen
3个回答

3

由于您的SEAF(最好称为IIFE)的结果在任何地方都没有被使用。函数返回什么并不重要。现在进行比较

(function(){
    MyApp = {…}
})();

使用

(function(){
    var MyApp = {…}
})();

区别在于第二个函数中变量前面有一个var keyword,这使它成为IEFE内部的局部变量,而在第一个函数中,它是一个隐式全局变量(应该避免使用)。这样,第二个代码片段不会分配给全局范围中的任何内容,并且稍后从外部访问MyApp将导致错误。
最好返回一些值,然后将其赋值给全局声明的变量:
var MyApp = (function(){
    return {…};
})();

如果我使用这个命名空间来命名我的JavaScript代码,那么返回一个对象字面量是否是实现单例模式的最佳方式,因为我只想在任何给定时间只有一个App实例可用? - Iain
是的,可能可以。如果在模块中没有任何局部变量,您可以省略IEFE;它不一定需要是对象字面量,而是可以使用任何创建对象的方式。 - Bergi

1
你的第一个例子所做的是将MyApp设置为全局变量 - 因为变量MyApp没有使用var关键字或点符号前缀,所以它变成了全局变量。如果你将MyApp放在自执行函数中,那么这似乎对你并不是问题 - 你可以真正地从中删除return语句 - 或者甚至在同一个函数中定义其他全局变量。你从未引用顶层函数的结果,因此没有使用那个return。
你的第二个例子使用var将MyApp设置为局部变量,因此它仅在运行它的函数的上下文中可见。

0

使用箭头函数的解决方案:

var myApp = (() => {
    return {
        init: () => console.log('MyApp init')
    };    
})();
myApp.init();

说明:

  • 全局变量myApp被设置为IIFE(立即调用的函数表达式)的结果。
  • init也可以写成箭头函数。
  • 如果在箭头函数中的返回语句之前没有执行其他逻辑,并且它返回一个对象字面量,则可以进一步简化。要从箭头函数返回对象字面量,请将其包装在括号中:

var myApp = (
   () => ({
       init: () => console.log('MyApp init')
   })
)();

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