为什么JavaScript模块模式中要使用自执行匿名函数?

9
在JavaScript的模块模式中,“立即执行函数表达式”(也称为自执行匿名函数)被用作返回对象的自执行函数。如何隐藏私有变量并仅公开返回的对象?为什么普通的JavaScript函数不能做到这一点?因此,在下面的小型模块中,如果没有包含的()(),我们为什么无法实现相同的封装概念?
var Module = (function () {
    var privateVariable = "foo",
        privateMethod = function () {
            alert('private method');
        };

    return {
        PublicMethod: function () {
            alert(privateVariable); 
            privateMethod(); 
        }
    };
})();

了解所分配的内容应该能够给你50%的必要理解。另外50%来自对闭包的理解。如果仍有困难,那么可以阅读Douglas Crockford的《JavaScript中的私有成员》。 - Beetroot-Beetroot
3个回答

9
自执行函数如何隐藏私有变量并仅暴露返回的对象?普通JavaScript函数为什么不能这样做?
普通JavaScript函数确实可以这样做。
function MakeModule() {
    var privateVariable = "foo",
        privateMethod = function () {
            alert('private method');
        };

    return {
        PublicMethod: function () {
            alert(privateVariable); 
            privateMethod(); 
        }
    };
}

var Module = MakeModule();

会很好地工作。

唯一的区别在于匿名函数引入了一个较少的全局变量,并且允许自己被垃圾收集,而MakeModule除非被作者显式删除,否则无法被回收。


立即调用函数表达式(IIFE)如果形成了一个包含被其返回值引用的闭包,那么它真的可以被垃圾回收吗? - Dagg Nabbit
1
@DaggNabbit,是的。只要它的arguments对象没有被使用。函数对象作为调用的操作数创建,因此一旦调用完成,对它的初始引用就不再使用,从调用中剩下的唯一东西是存储被逃逸内部函数闭合变量的任何执行上下文。 - Mike Samuel

2
私有性是由闭包实现的。 "var privateVariable" 被 "PublicMethod" 所封闭,因此只有该函数可以访问该变量,因为它在其闭包中具有该变量。它不能被其他任何东西引用,因此是“私有的”。
这不仅发生在“立即调用函数表达式”中,而且在普通函数调用中也会发生。这只是一种在定义模块时立即创建闭包的方法,而不是在调用外部函数时再创建。
另请参阅 Douglas Crockford 自己的这篇文章:http://javascript.crockford.com/private.html

“立即创建闭包”的想法最好地回答了我的问题,我认为。 - Brendan

0
你可以通过命名函数定义一个匿名函数。
示例:
//factorial
(function(n){
    var self = function(n){
        //call self
        return n > 0 ? (self(n-1) * n) : 1;
    }
    return self;
})()

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